documentation_technique:ldap_fusiondirectory

Préambule

Installation de OpenLDAP + FusionDirectory sur une debian fraîchement installée.
Apache et PHP5 sont déjà installés.

2018-09-30 by thomas

Objectif: permettre à un utilisateur de gérer son organisation et ses utilisateurs via FD

Fait:

  1. création d'une organisation de test (wildmyrtille)
  2. affectation d'une ACL : turlux et thomas admin de la branche
  3. recopie du modèle “utilisateur hadoly” dans la branche
  4. connexion en tant que “thomas” sur FD:
    1. on ne voit que la branche wildmyrtille (impossible de remonter dans l'arborescence, impossible de voir les autres utilisateurs / domaines)
    2. on peut créer un compte utilisateur fonctionnel en utilisant le modèle

Conclusion: il est possible de déléguer l'administration d'une branche à un utilisateur.

:!: attention de ne pas exposer le nom / prénom de l'adhérent via ldap: les champs sn et cn ne doivent pas être récupérés par LDAP, lui préférer l'attribut displayName qui doit normalement correspondre au pseudo

En règle général, l'accès à un service (application) est basé sur l'appartenance du compte qui se connecte au groupe correspondant.

Créer un groupe d'accès à l'application, à la racine, nommé application_group (voir par exemple le groupe mail_group )

Créer un compte ldap lecteur dédié à l'application. (voir par exemple le compte doku-account dans la branche service)

Configurer l'application avec les informations suivantes:

  • adresse du serveur: ldaps:/ /leodagan.hadoly.fr
  • port: 636 (pas d'accès en clair)
  • base de recherche: dc=hadoly,dc=fr
  • filtre de recherche. Celui-ci doit vérifier que le compte est bien membre du groupe permettant l'accès à l'application. Par exemple:
(&(|(objectclass=gosaMailAccount))(|(memberof=cn=cloud_group,ou=groups,dc=hadoly,dc=fr)))

Ce filtre vérifie: - le compte est du type gosaMailAccount (càd un utilisateur) - le compte est membre du groupe cloud_group

2017-02-20: by thomas, tentative de mise en œuvre sur guetenoch

doc de référence: https://documentation.fusiondirectory.org/en/documentation/plugin/ssh_plugin/how_to_setup_ssh_plugin

  • leodagan: installation du plugin fusiondirectory-plugin-ssh
  • leodagan: installation et activation du schéma adhoc :
  • leodagan: activation du schéma fusiondirectory-insert-schema -i /etc/ldap/schema/fusiondirectory/openssh-lpk.schema
  • Après s'être déconnecté reconnecté sur fusion directory, dans la gestion des utilisateurs apparaît un nouvel onglet “SSH” permettant de créer puis enregistrer les infos ssh

Sur chaque machine:

apt-get install ldap-auth-client nscd
auth-client-config -t nss -p lac_ldap

déployer le script suivant:

cat /usr/local/bin/ldap_fetch_authorizedkeys.sh
#! /bin/bash
ldapsearch -xLLL '(&(objectClass=posixAccount)(uid='"$1"'))' 'sshPublicKey' | sed -n '/^ /{H;d};/sshPublicKey:/x;$g;s/\n *//g;s/sshPublicKey: //gp'

Ce script doit appartenir à root et être exécutable par n'importe qui (au moins par nobody)

Rajouter les directives suivantes dans la configuration ssh: AuthorizedKeysCommandUser nobody AuthorizedKeysCommand /usr/local/bin/ldap_fetch_authorizedkeys.sh

J'ai rajouté une tâche auth_ldap.yml au rôle ansible base qui réalise les 2 manips décrites ci-dessus. Je n'ai pas testé. # Authentification chez Hadoly

  • chacun des membres a un compte utilisateur (centralisé dans un annuaire)
  • la gestion des autorisations d'accès se fait en se basant sur des groupes LDAP (compte d'admin par exemple)
  • tous les flux sont chiffrés
  • certains membres (comme un asso) peuvent avoir plusieurs utilisateurs (qui leur sont spécifiques)
  • seuls les comptes Hadoly sont pris en compte pour la gestion des moyens communs: pas question qu'un compte d'association
  • interface web de gestion des comptes avec des modèles.
  • stockage des clefs SSH dans le comptes utilisateurs (XXX préciser l'utilisation exacte)
  • systeme cible: OpenLDAP dans container LXC Debian
  • prevoir le cas: autres (sous-)organisation que Hadoly (asso par exemple)
  • XXX preciser les schema employes, notamment les types d'objets.
  • XXX contraintes sur les uid/gid: [500..800] pour LDAP && hadoly, > 2000 si asso ?
  • XXX groupes: par membres sur les utilisateurs ou referals dans les groupes ?

Organisation de l'annuaire: on reste en “dc=<org>,dc=<tld>” pour se faciliter la vie (et la config du paquet Debian).
On utilise l'organisation suivante:

+ dc=hadoly,dc=fr     # le Root DN
|
+-- cn=admin          # OpenLDAP superuser
|
+-- ou=people         # compte utilisateurs Hadoly (contient les admin des applis et des infras)
|     |
|     +-- cn=pierre   # exemple: compte utilisateur du petit Pierre
|
+-- ou=groups         # les groupes Hadoly
|
+-- ou=service        # comptes/groupes pour les applis pour binder LDAP
|     |
|     +-- ou=account  # les comptes
|     |     |
|     |     +-- cn=owncloud-nginx  # exemple: compte pour l'appli owncloud (frontal nginx)
|     |
|     +-- ou=roles    # groupes pour définir les droits LDAP des "account" sur l'annuaire
|           |
|           +-- cn=ldap-ro-people-cn-and-sshpubkey-only  # exemple
|           +-- cn=ldap-ro-people-cn-and-passwd          # exemple
|
+-- ou=dns            # objets pour le DNS (nécessaire ?)
|
+-- ou=subent               # les entites membres d'Hadoly (association) avec plusieurs utilisateurs/groupes
|     |
|     +-- cn=asso1          # association "asso1"
|           +-- ou=people   # comptes utilisateurs de <asso1>
|           +-- ou=groups   # groupe de <asso1>

OpenLDAP

Description des fichiers et répertoires contenant le stockage (backend) de OpenLDAP

  • service d'arrêt/démarrage de service: /etc/init.d/slapd, paramétré par le contenu du fichier /etc/default/slapd,
  • fichiers de configuration: dans le répertoire `/etc/ldap/slapd.d/'
  • PAS de fichier de configuration initiale de slapd (comme /etc/ldap/slapd.conf) :
    • tout est dans le baseDN cn=config pour permettre des modification de configuration sans arrêt du service.
    • En fait, des fichiers sont auto-générés pour le (re)démarrage du service:

cf /etc/ldap/slapd.d/cn\=config.ldif,
cf répertoire /etc/ldap/slapd.d/cn\=config/

XXX fichiers de bases de données (à sauvegarder).

Puisqu'on l'installe dans un environnement Debian, on commence par suivre le guide d'installation Debian:
https://wiki.debian.org/LDAP/OpenLDAPSetup

Note: à ce stade, on suppose juste que l'on a un shell root dans un environnement “quelconque” sous Debian:

  • on suppose juste que l'on est sous Debian Jessie (8.3)
  • soit dans une VM, soit dans un conteneur LXC
  • AUCUNE hypothèse sur l'environnement réseau (hostanme, addresse IP et son entrée DNS associée)

Installation du paquet contenant le serveur OpenLDAP et des outils clients LDAP (ldapadd, ldapmodify).
L'installation du paquet permet de définir le mot de passe administrateur LDAP (cn=admin,dc=nodomain à cet instant):

$ sudo aptitude install slapd ldap-utils

[...]
Setting up slapd (2.4.40+dfsg-1+deb8u2) ...
Setting up ldap-utils (2.4.40+dfsg-1+deb8u2) ...

Le service est alors opérationnel:

<HTML><ul></HTML> <HTML><li></HTML><HTML><p></HTML>processus:<HTML></p></HTML>

$ ps -ef | grep ldap | grep -v -w grep
openldap   1097  1  0 10:10 ?  00:00:00 /usr/sbin/slapd -h ldap:/// ldapi:/// -g openldap -u openldap -F /etc/ldap/slapd.d

<HTML></li></HTML> <HTML><li></HTML><HTML><p></HTML>socket(s) réseaux en utilisation:<HTML></p></HTML>

$ netstat -lntp | grep slapd
tcp        0      0 0.0.0.0:389       0.0.0.0:*      LISTEN      1097/slapd      
tcp6       0      0 :::389            :::*           LISTEN      1097/slapd    

<HTML></li></HTML><HTML></ul></HTML>

On reconfigure alors le paquet Debian du LDAP pour Hadoly avec le paramétrage suivant (cas où le système n'a pas encore une config “hadoldy”):

$ sudo dpkg-reconfigure slapd
* Omit OpenLDAP server configuration? NO
* DNS domain name: hadoly.fr
* Organization name: Hadoly
* administrator password: ********** (compte `cn=admin,dc=hadoly,dc=fr`)
* Database backend to use: [mdb]  (choix par défaut)
* Do you want the database to be removed when slapd is purged? YES
* Move old database? YES
* Allow LDAPv2 protocol? NO

<HTML><ul></HTML> <HTML><li></HTML><HTML><p></HTML>liste des objects dans cn=config:<HTML></p></HTML>

# slapcat -s cn=config | grep ^dn
dn: cn=config
dn: cn=module{0},cn=config
dn: cn=schema,cn=config
dn: cn={0}core,cn=schema,cn=config
dn: cn={1}cosine,cn=schema,cn=config
dn: cn={2}nis,cn=schema,cn=config
dn: cn={3}inetorgperson,cn=schema,cn=config
dn: olcBackend={0}mdb,cn=config
dn: olcDatabase={-1}frontend,cn=config
dn: olcDatabase={0}config,cn=config
dn: olcDatabase={1}mdb,cn=config

<HTML></li></HTML> <HTML><li></HTML><HTML><p></HTML>Liste des objects dans le base DN:<HTML></p></HTML>

# slapcat  | grep ^dn
dn: dc=hadoly,dc=fr
dn: cn=admin,dc=hadoly,dc=fr

<HTML></li></HTML><HTML></ul></HTML>

Comme indiqué dans la doc Debian, on rajoute des index supplémentaires pour avoir un service plus rapide.

Pour déterminer les index à rajouter, rechercher candidates dans les logs ldap:

sudo journalctl -x --unit slapd| awk '/indexed/{print $7, $8}' | sort | uniq -c

si un attribut apparaît fréquemment, rajouter un index.

De mon (thomas) point de vue les index de type eq sont contre performants. Par défaut, on a les index suivants:

$ ldapsearch -Y EXTERNAL -H ldapi:/// -b "cn=config"  "(olcDatabase={1}mdb)" olcDbIndex
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
# extended LDIF
#
# LDAPv3
# base <cn=config> with scope subtree
# filter: (olcDatabase={1}mdb)
# requesting: olcDbIndex 
#

# {1}mdb, config
dn: olcDatabase={1}mdb,cn=config
olcDbIndex: objectClass eq
olcDbIndex: cn,uid eq
olcDbIndex: uidNumber,gidNumber eq
olcDbIndex: member,memberUid eq

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1

On créer un fichier LDIF contenant les index supplémentaires à créer (basé sur la page Debian et adapté):

$ cat olcDbIndex.ldif
dn: olcDatabase={1}mdb,cn=config
changetype: modify
delete: olcDbIndex
olcDbIndex: cn,uid eq
-
add: olcDbIndex
olcDbIndex: cn pres,sub,eq
-
add: olcDbIndex
olcDbIndex: sn pres,sub,eq
-
add: olcDbIndex
olcDbIndex: uid pres,sub,eq
-
add: olcDbIndex
olcDbIndex: displayName pres,sub,eq
-
add: olcDbIndex
olcDbIndex: default sub
-
add: olcDbIndex
olcDbIndex: mail,givenName eq,subinitial
-
add: olcDbIndex
olcDbIndex: dc eq

Fichier que l'on applique au serveur:

$ ldapmodify -Y EXTERNAL -H ldapi:/// -f ./olcDbIndex.ldif

Vérifions que les nouveaux index sont en place:

$ ldapsearch -Y EXTERNAL -H ldapi:/// -b "cn=config"  "(olcDatabase={1}mdb)" olcDbIndex
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
# extended LDIF
#
# LDAPv3
# base <cn=config> with scope subtree
# filter: (olcDatabase={1}mdb)
# requesting: olcDbIndex 
#

# {1}mdb, config
dn: olcDatabase={1}mdb,cn=config
olcDbIndex: objectClass eq
olcDbIndex: uidNumber,gidNumber eq
olcDbIndex: member,memberUid eq
olcDbIndex: cn pres,sub,eq
olcDbIndex: sn pres,sub,eq
olcDbIndex: uid pres,sub,eq
olcDbIndex: displayName pres,sub,eq
olcDbIndex: default sub
olcDbIndex: mail,givenName eq,subinitial
olcDbIndex: dc eq

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1

Rajoutons les quelques objets manquants en utilisant ldapadd (ce qui permet de vérifier l'accès au LDAP en mode client/serveur):

# ldapadd -x -D "cn=admin,dc=hadoly,dc=fr" -W -f ./hadoly.ldif
adding new entry "ou=people,dc=hadoly,dc=fr"
adding new entry "ou=groups,dc=hadoly,dc=fr"
adding new entry "ou=subent,dc=hadoly,dc=fr"
[...]

Le fichier .ldif pour les ajouts contient ceci (avec une ligne vide à la fin !!):

# cat hadoly.ldif
dn: ou=people,dc=hadoly,dc=fr
objectClass: organizationalUnit
ou: people

dn: ou=groups,dc=hadoly,dc=fr
objectClass: organizationalUnit
ou: groups

dn: ou=subent,dc=hadoly,dc=fr
objectClass: organizationalUnit
ou: subent

dn: ou=service,dc=hadoly,dc=fr
objectClass: organizationalUnit
ou: service

dn: ou=account,ou=service,dc=hadoly,dc=fr
objectClass: organizationalUnit
ou: account

dn: ou=roles,ou=service,dc=hadoly,dc=fr
objectClass: organizationalUnit
ou: roles

Sauvegarde au format LDIF:

# slapcat -s dc=hadoly,dc=fr | gzip > /path/to/backup.hadoly.ldif.gz
# slapcat -s cn=config       | gzip > /path/to/backup.config.ldif.gz

Procédures de backup/restauration (à tester et valider) :

  • https://help.ubuntu.com/12.04/serverguide/openldap-server.html#ldap-backup
  • http://blog.panek.work/2015/08/29/openldap_backup_restore.html

Le service LDAP n'a pas vocation a être utilisée publiquement, mais uniquement de fournir un service d'authentification et d'autorisation à d'autres services Hadoly (front-end web par exemple). Il convient de le fiabiliser et le sécuriser autant que possible.

  • XXX filtrage réseau sur toute cette machine: uniquement depuis notre sous-réseau public
  • XXX sans doute laisser passer l'interface d'administratation (HTTPS) ?
  • XXX uniquement du LDAPS

ldaps en place avec certificat auto signé.

serveur accessible uniquement en ldaps et socket.

  • XXX gestion des appartenances par référal, ça semble plus souple ?
  • XXX pas de contraintes pour les applications ? elles savent gerer les referals ?
  • XXX mécanisme type memberOf au niveau LDAP ?

Utilisation de l'overlay memberof qui permet de récupérer (via l'attribut memberof) la liste des attributs auxquels appartient un utilisateur. Cela permet des requètes du style:

ldapsearch uid=test1 memberof
ldapsearch memberof=cn=cloud_group,ou=groups,dc=hadoly,dc=fr

en vrac:

  • XXX restrictions d'accès ?
  • XXX contraintes sur les uid ?
  • XXX contraintes sur les mots de passe ?
  • XXX quel frontal utiliser ?

XXX Pas encore mis en place

Notre but est :

  • de stocker les clefs publiques de chaque utilisateur dans l'annuaire LDAP
  • d'utiliser ces clefs publiques stockées dans le LDAP à être utilisé par OpenSSH.

Par contre, les docs existantes indiquent comment faire pour que ça fonctionne en se logguant en tant que utilisateur X sur le système distant, et non pas Y@local vers root@distant … va falloir tweaker un peu la conf, genre faire renvoyer l'équivalent d'un cat de toutes les clefs publiques pour tous les utilisateurs (que l'on filtrera sans doute suivant une contrainte particulière, genre appartenance à un groupe particulier).

  • XXX plusieurs pubkey SSH possibles par utilisateur ?
  • XXX autre solution: autoriser le login en tant que X@distant et autoriser sudo pour l'utilisateur X sur le système distant ?

Documentation, pointeurs:

https://imil.net/blog/2013/04/29/debian-backport-of-openssh-6-2/
http://connect.ed-diamond.com/GNU-Linux-Magazine/GLMF-161/AuthorizedKeysCommand-quand-OpenSSH-devient-CloudSSH.-Nan-j-deconne

  • [old] OpenSSH PLK patch: “permits the use of an OpenLDAP server as an SSH public key provider”:

http://code.google.com/p/openssh-lpk/

  • CentOS/RedHat:

http://itdavid.blogspot.fr/2013/11/howto-configure-openssh-to-fetch-public.html

  • XXX détailler (exemple) la configuration ansible pour déployer un tel service
  • XXX ajout/suppression d'utilisateurs
  • XXX interface de gestion: phpldapadmin ? FusionDirectory ?
  • XXX restriction d'accès à l'interface de gestion ?
  • XXX bind anonyme ou pas pour les applicatifs ?
  • XXX config nginx
  • XXX config Apache HTTP server
  • XXX config OpenSSH
  • XXX config owncloud
  • XXX config SMTP server: postfix
  • XXX config IMAP server
  • XXX réplication multi-master
  • XXX Délégation d'authentification (Google, ConnectFrance, OpenID … ) ?
  • XXX SSO
  • XXX OTP

Exemple: recherche de tout les noms des objets présents dans l'annuaire:
(juste leur entrées, on ne voit pas leur(s) attribut(s))

# ldapsearch -Y EXTERNAL -H ldapi:/// -b "dc=hadoly,dc=fr"  dn
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
# extended LDIF
#
# LDAPv3
# base <dc=hadoly,dc=fr> with scope subtree
 filter: (objectclass=*)
# requesting: dn 
#

# hadoly.fr
dn: dc=hadoly,dc=fr

# admin, hadoly.fr
dn: cn=admin,dc=hadoly,dc=fr

# people, hadoly.fr
dn: ou=people,dc=hadoly,dc=fr

[...]

Permet de récupérer des “dump” des données LDAP (pas au format LDIF par contre).
slapcat est un outil “serveur”: n'utilise pas le mode client/server, mais un accès via socket unix (ldapi), donc doit être exécuté sur le même hôte que le service LDAP.

thomas: non, les commandes slapcat, slapadd, slapindex et slaptest n'accèdent pas au serveur via le socket, mais va taper directement dans les fichiers de bdd. Ça marche même quand le serveur est down.

D'ailleurs, il vaut mieux éviter d'utiliser ces commandes si le serveur est en cours de fonctionnement (sauf slapcat).

Exemple: listons rapidement tous les dn (Distinguished Name) présents dans cn=config:
(juste leur entrées, on ne voit pas leur(s) attribut(s))

# slapcat -s cn=config | grep ^dn
dn: cn=config
dn: cn=module{0},cn=config
dn: cn=schema,cn=config
dn: cn={0}core,cn=schema,cn=config
dn: cn={1}cosine,cn=schema,cn=config
dn: cn={2}nis,cn=schema,cn=config
dn: cn={3}inetorgperson,cn=schema,cn=config
dn: olcBackend={0}mdb,cn=config
dn: olcDatabase={-1}frontend,cn=config
dn: olcDatabase={0}config,cn=config
dn: olcDatabase={1}mdb,cn=config

ldapvi est un éditeur en mode texte spécialisé pour l'édition d'un annuaire LDAP.

Installation sous Debian:

$ apt-get install ldapvi

Exemple d'utilisation:

$ ldapvi --user "cn=admin,dc=hadoly,dc=fr" -b "dc=hadoly,dc=fr"

Pour éditer l'entrée “cn=config” , il faut passer par une socket unix (ldapi):

$ ldapvi -h ldapi:/// -Y EXTERNAL -b cn=config

L'installation par défaut ne permet pas d'accéder à la branche cn=config via le réseau.

Découverte et quelques tips d'utilisation:

Références:

http://connect.ed-diamond.com/GNU-Linux-Magazine/GLMF-104/ldapvi-un-editeur-LDAP-pour-les-barbus

FusionDirectory (FD)

Suite à l'installation de OpenLDAP, on installe FusionDirectory pour réaliser les opérations courantes de maintenance à l'aide d'une interface web.
FusionDirectory permet également de mettre en place des ACLs et des rôles dans l'annuaire LDAP. Apache et php5 sont déjà installés.

Je me suis basé sur la doc de FusionDirectory : https://documentation.fusiondirectory.org/en/documentation_admin Enfin, basé… Je l'ai suivi à la lettre.

On utilise le dépôt officiel de FusionDirectory pour Debian pour les paquets binaires (plutôt que de l'installer et de le maintenir “à la main”).

Récupération de la clef GPG du dépôt de FusionDirectory. Le serveur GNUPG défini dans la doc de Fusion Directory est en erreur et ne permet pas de récupérer la clé. On peut utiliser le serveur hébergé chez Ubuntu :

$ sudo gpg --keyserver keyserver.ubuntu.com --recv-key 62B4981F
$ sudo gpg --export -a "Fusiondirectory Archive Manager <contact@fusiondirectory.org>" > FD-archive-key
$ sudo apt-key add FD-archive-key

On ajoute (on déclare) les dépôts de Fusion Directory comme source de paquets:

$ sudo cp -p /etc/apt/sources.list /etc/apt/sources.list.old
$ sudo echo 'deb http://repos.fusiondirectory.org/debian-jessie jessie main' >> /etc/apt/sources.list
$ sudo apt-get update

On commence par installer le gestionnaire des schémas LDAP de Fusion Directory:

$ sudo apt-get install fusiondirectory-schema

Et on lance son initialisation, ce qui a pour effet de référencer lesdits schémas dans le serveur OpenLDAP:

$ sudo fusiondirectory-insert-schema
[...]
executing 'ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/fusiondirectory/core-fd.ldif'
adding new entry "cn=core-fd,cn=schema,cn=config"

[...]
executing 'ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/fusiondirectory/core-fd-conf.ldif'
adding new entry "cn=core-fd-conf,cn=schema,cn=config"

[...]
executing 'ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/fusiondirectory/ldapns.ldif'
adding new entry "cn=ldapns,cn=schema,cn=config"

[...]
executing 'ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/fusiondirectory/template-fd.ldif'
adding new entry "cn=template-fd,cn=schema,cn=config"

On peut alors installer le paquet FusionDirectory, ce qui amène environ 140 paquets en dépendance (Apache HTTP, PHP, openssl, etc):

$ sudo apt-get install fusiondirectory

Liste des schémas FusionDirectory installés à ce stade:

$ sudo fusiondirectory-insert-schema -l
core
cosine
nis
inetorgperson
core-fd
core-fd-conf
ldapns
template-fd

FusionDirectory est architecturé à l'aide de plugins, permettant de n'ajouter que les fonctionnalités dont on a besoin.

L'installation des plugins se fait toujours suivant la même séquence:

$ sudo apt-get install fusiondirectory-plugin-<machin> 
$ sudo fusiondirectory-insert-schema -i /etc/ldap/schema/fusiondirectory/<machin-truc>.schema

Il existe de nombreux plugins, ils sont listé dans la doc de FD que j'ai posté plus haut.

Rappel: liste des schémas FusionDirectory installés:

$ sudo fusiondirectory-insert-schema -l

XXX quelle utilité ?

$ sudo apt-get install fusiondirectory-plugin-systems
$ sudo apt-get install fusiondirectory-plugin-systems-schema
$ sudo fusiondirectory-insert-schema -i /etc/ldap/schema/fusiondirectory/service-fd.schema
$ sudo fusiondirectory-insert-schema -i /etc/ldap/schema/fusiondirectory/systems-fd-conf.schema
$ sudo fusiondirectory-insert-schema -i /etc/ldap/schema/fusiondirectory/systems-fd.schema

NB: le plugin “Mail” dépend du plugin “Systems”.

XXX quelle utilité ?
On pourra créer des serveurs postfix et imap/pop

$ sudo apt-get install fusiondirectory-plugin-mail
$ sudo apt-get install fusiondirectory-plugin-mail-schema
$ sudo fusiondirectory-insert-schema -i /etc/ldap/schema/fusiondirectory/mail-fd.schema
$ sudo fusiondirectory-insert-schema -i /etc/ldap/schema/fusiondirectory/mail-fd-conf.schema

Le plugin “dovecot” dépend du plugin “Mail”

On pourra créer des serveurs dovecot

$ sudo apt-get install fusiondirectory-plugin-dovecot
$ sudo apt-get install fusiondirectory-plugin-dovecot-schema
$ sudo fusiondirectory-insert-schema -i /etc/ldap/schema/fusiondirectory/dovecot-fd.schema

2017-02-26

Symptôme: lors d'une connexion sur FD, on obtient un message d'erreur concernant un attribut indéfini.

C'est lié à une mise à jour, qui nécessite apparemment une réinstallation manuelle des nouveaux schémas ldap:

for i in /etc/ldap/schema/fusion-directory/* ; do fusiondirectory-insert-schema -m $i ; done

Une fois les paquets installés pour FusionDirectory, on peut démarrer sa configuration via son interface web.

Sous Debian, l'interface web est à l'adresse http://your-web-server/fusiondirectory

L'installeur commence par demander une confirmation que l'on est bien admin du système sur lequel il se trouve via une ligne de commande du style:

$ sudo echo -n TrucBidule13546 > /var/cache/fusiondirectory/fusiondirectory.auth 

La suite de l'installation se décompose en vérifications (modules PHP nécessaires) et en configurations diverses détaillées ci-dessous.

  • Language Setup : [automatic]
  • Vérification de l'installation de PHP:
    • vérifie que tous les modules PHP requis sont bien installés : support de LDAP, gettext, curl, iconv, IMAP, etc.
    • que la configuration de PHP est OK :

PHP version,
register_globals = off, session.gc_maxlifetime >= 86400, session.auto_start = Off,
memory_limit >= 128, implicit_flush = Off, max_execution_time >= 30
expose_php = Off, zend.ze1_compatibility_mode = Off

⇒ Rien eu à modifier, tout est OK avec les configuration par défaut Debian.

  • LDAP connection setup:
    • location name: default
    • connection URI: ldaps://leodagan.hadoly.fr/dc=hadoly,dc=fr
    • Base DN: dc=hadoly,dc=fr
    • admin DN: cn=admin (relatif à ,dc=hadoly,dc=fr)
    • Admin password: *********

A ce point de la configuration, la connexion à OpenLDAP se fait en tant que cn=admin,dc=hadoly,dc=fr.

<HTML><ul></HTML> <HTML><li></HTML>Look and Feel: <HTML><ul></HTML> <HTML><li></HTML>Language: [automatic]<HTML></li></HTML> <HTML><li></HTML>Theme : [breezy]<HTML></li></HTML> <HTML><li></HTML>Timezone: [Europe/Paris]<HTML></li></HTML><HTML></ul></HTML> <HTML></li></HTML> <HTML><li></HTML>Schema setup: <HTML><ul></HTML> <HTML><li></HTML>[x] schema validation<HTML></li></HTML><HTML></ul></HTML> <HTML></li></HTML> <HTML><li></HTML>FusionDirectory Configuration: <HTML><ul></HTML> <HTML><li></HTML>Password Settings: <HTML><ul></HTML> <HTML><li></HTML>Password Default Hash: [ssha]<HTML></li></HTML> <HTML><li></HTML>[x] force default hash<HTML></li></HTML> <HTML><li></HTML>Password minimum length: 10<HTML></li></HTML> <HTML><li></HTML>Password minimum differs: 5 XXX usage ?<HTML></li></HTML> <HTML><li></HTML>[x] Use account expiration<HTML></li></HTML> <HTML><li></HTML>SASL Realm: (rien pour le moment) XXX usage ?<HTML></li></HTML> <HTML><li></HTML>SASL Exop : (rien pour le moment) XXX usage ?<HTML></li></HTML><HTML></ul></HTML> <HTML></li></HTML> <HTML><li></HTML>Login and session: <HTML><ul></HTML> <HTML><li></HTML>Login attribute: [both] (uid and email)<HTML></li></HTML> <HTML><li></HTML>[ ] enforce encrypted connections # XXX si activé implique HTTPS seulement des la fin de la config …<HTML></li></HTML> <HTML><li></HTML>[x] warn if session is not encrypted<HTML></li></HTML> <HTML><li></HTML>[ ] HTTP basic authentication<HTML></li></HTML> <HTML><li></HTML>[ ] HTTP header authentication<HTML></li></HTML><HTML></ul></HTML> <HTML></li></HTML> <HTML><li></HTML>snapshots <HTML><ul></HTML> <HTML><li></HTML>[x] enable snapshots<HTML></li></HTML> <HTML><li></HTML>snapshot base: ou=snapshots,dc=hadoly,dc=fr<HTML></li></HTML><HTML></ul></HTML> <HTML></li></HTML> <HTML><li></HTML>SSL <HTML><ul></HTML> <HTML><li></HTML>key path : /etc/ssl/private/fd.key<HTML></li></HTML> <HTML><li></HTML>Certificate path CA : /etc/ssl/certs/fd.cert<HTML></li></HTML> <HTML><li></HTML>Certificate path : /etc/ssl/certs/ca.cert<HTML></li></HTML><HTML></ul></HTML> <HTML></li></HTML> <HTML><li></HTML>CAS <HTML><ul></HTML> <HTML><li></HTML>[ ] enable CAS # XXX pas pour le moment<HTML></li></HTML><HTML></ul></HTML> <HTML></li></HTML> <HTML><li></HTML>People and group storage <HTML><ul></HTML> <HTML><li></HTML>people DN attribute: [uid] # XXX ou bien “cn” ?<HTML></li></HTML> <HTML><li></HTML>CN pattern: %givenName% %sn%<HTML></li></HTML> <HTML><li></HTML>[x] strict naming policy<HTML></li></HTML> <HTML><li></HTML>Group/user min id: 100 ⇒ 1000<HTML></li></HTML> <HTML><li></HTML>Base number for user id: 1100 ⇒ 2000<HTML></li></HTML> <HTML><li></HTML>Base number for group id: 1100 ⇒ 2000<HTML></li></HTML> <HTML><li></HTML>users RDN : ou=people<HTML></li></HTML> <HTML><li></HTML>groups RDN : ou=groups<HTML></li></HTML> <HTML><li></HTML>ACL role RDN : ou=aclroles<HTML></li></HTML> <HTML><li></HTML>id allocation method: [traditional]<HTML></li></HTML> <HTML><li></HTML>[ ] restrict role member # XXX ca sert à quoi ?<HTML></li></HTML><HTML></ul></HTML> <HTML></li></HTML> <HTML><li></HTML><HTML><p></HTML>Core settings<HTML></p></HTML> <HTML><p></HTML>Laisser les réglages par défaut.<HTML></p></HTML> <HTML><ul></HTML> <HTML><li></HTML>Display summary in listings [x]<HTML></li></HTML> <HTML><li></HTML>Edit locking : entryCSN<HTML></li></HTML> <HTML><li></HTML>Enable logging [x]<HTML></li></HTML> <HTML><li></HTML>LDAP size limit : 200 (200 quoi ? A augmenter ?)<HTML></li></HTML><HTML></ul></HTML> <HTML></li></HTML><HTML></ul></HTML> <HTML></li></HTML><HTML></ul></HTML>

Pas grand-chose à dire: beaucoup de paramètres, on fait donc des choix plutôt guidés par les valeurs par défaut pour le moment.

XXX documenter ou=aclroles dans le schema general.

<HTML><ul></HTML> <HTML><li></HTML><HTML><p></HTML>LDAP inspection
Analyze your current LDAP for FusionDirectory compatibility<HTML></p></HTML> <HTML><ul></HTML> <HTML><li></HTML><HTML><p></HTML>Inspecting object classes in root object : FAILED ⇒ bouton [migrate]
veut rajouter les entrees suivantes:<HTML></p></HTML>

dn: dc=hadoly,dc=fr  
objectClass: top  
objectClass: dcObject  
objectClass: organization  
+objectClass: gosaDepartment  
+ou: hadoly  
+description: hadoly  

XXX on fait quoi ?<HTML></li></HTML> <HTML><li></HTML>Checking permission for LDAP database : ok<HTML></li></HTML> <HTML><li></HTML>Checking for invisible users: ok<HTML></li></HTML> <HTML><li></HTML><HTML><p></HTML>Checking for super administrator : FAILED
“There is no FusionDirectory administrator account inside your LDAP”
propose de creer un UserID “fd-admin” password=fd-admin69<HTML></p></HTML><HTML></li></HTML> <HTML><li></HTML>Checking for default ACL roles and groups: Default ACL have been inserted<HTML></li></HTML> <HTML><li></HTML>Checking for users outside the people tree : ok<HTML></li></HTML> <HTML><li></HTML>Checking for groups outside the groups tree: ok<HTML></li></HTML> <HTML><li></HTML><HTML><p></HTML>Checking for invisible departments: WARNING
“Found 3 department(s) that will not be visible in FusionDirectory.”
⇒ propose de rajouter sur les entrées suivantes sur ou=subent,dc=hadoly,dc=fr ou=service,dc=hadoly,dc=fr et ou=account,ou=service,dc=hadoly,dc=fr :<HTML></p></HTML>

objectClass: organizationalUnit  
+objectClass: gosaDepartment  
+description: FusionDirectory department  

XXX on fait quoi ?<HTML></li></HTML> <HTML><li></HTML>Checking for duplicated UID numbers : ok<HTML></li></HTML> <HTML><li></HTML><HTML><p></HTML>Checking for duplicated GID numbers: ok<HTML></p></HTML><HTML></li></HTML><HTML></ul></HTML> <HTML></li></HTML><HTML></ul></HTML>

XXX ou=aclroles contient quoi ?

XXX quel est le dn de l'utilisateur fd-admin ?

XXX on peut faire du CAS aussi (désactivé par defaut)

Le webinstaller propose de générer un fichier fusiondirectory.conf.
On le télécharge et on le sauvegarde en tant que fichier /etc/fusiondirectory/fusiondirectory.conf

Pour vérifier que les permissions et le contenu du fichier /etc/fusiondirectory/fusiondirectory.conf sont corrects:

$ sudo fusiondirectory-setup --check-config

XXX ou sont stockes tous les settings que l'on a fait ? dans cn=config ?

XXX le fichier /etc/fusiondirectory/fusiondirectory.conf ne contient que peu de choses

J'ai eu un petit bug lors de mes test du plugin Systems. Il n'avait pas d'encodage défini et faisait une erreur lorsqu'on essaye de créer un System Allez dans Configuration puis dans l'onglet Systèmes. Dans “divers” fixez un encodage. Au hasard UTF-8 ?

Et voilà ! Il reste à voir commment Kerkeros s'interface avec mais je pense pas qu'il y ai de soucis. Pour le moment je ne suis pas du tout à l'aise avec LDAP et ses dénominations ce qui va me ralentire pour interfacer Postfix et Dovecot avec LDAP.

Self Service Password (SSP)

Self Service Password est une application développée par Clément Oudot permettant à un utilisateur de modifier/réinitialiser son mot de passe. Le service est accessible à l'adresse http(s)://mdp.hadoly.fr.

$ sudo vim /etc/apt/sources.list.d/ltb-project.list
Ajouter deb http://ltb-project.org/debian/jessie jessie main et sauvegarder
$ wget -O - http://ltb-project.org/wiki/lib/RPM-GPG-KEY-LTB-project | sudo apt-key add -
$ apt update && apt install self-service-password

La configuration se fait dans le fichier /usr/share/self-service-password/conf/config.inc.php

<?php
#==============================================================================
# LTB Self Service Password
#
# Copyright (C) 2009 Clement OUDOT
# Copyright (C) 2009 LTB-project.org
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# GPL License: http://www.gnu.org/licenses/gpl.txt
#
#==============================================================================

#==============================================================================
# Configuration
#==============================================================================
# LDAP
$ldap_url = "ldaps://leodagan.hadoly.fr:636";
$ldap_starttls = false;
$ldap_binddn = "cn=admin,dc=hadoly,dc=fr";
$ldap_bindpw = "xxxxxxxxx";
$ldap_base = "dc=hadoly,dc=fr";
$ldap_login_attribute = "uid";
$ldap_fullname_attribute = "cn";
$ldap_filter = "(&(objectClass=person)($ldap_login_attribute={login}))";

# Active Directory mode
# true: use unicodePwd as password field
# false: LDAPv3 standard behavior
$ad_mode = false;
# Force account unlock when password is changed
$ad_options['force_unlock'] = false;
# Force user change password at next login
$ad_options['force_pwd_change'] = false;
# Allow user with expired password to change password
$ad_options['change_expired_password'] = false;

# Samba mode
# true: update sambaNTpassword and sambaPwdLastSet attributes too
# false: just update the password
$samba_mode = false;
# Set password min/max age in Samba attributes
#$samba_options['min_age'] = 5;
#$samba_options['max_age'] = 45;

# Shadow options - require shadowAccount objectClass
# Update shadowLastChange
$shadow_options['update_shadowLastChange'] = false;

# Hash mechanism for password:
# SSHA
# SHA
# SMD5
# MD5
# CRYPT
# clear (the default)
# auto (will check the hash of current password)
# This option is not used with ad_mode = true
$hash = "SSHA";

# Prefix to use for salt with CRYPT
$hash_options['crypt_salt_prefix'] = "$6$";

# Local password policy
# This is applied before directory password policy
# Minimal length
$pwd_min_length = 10;
# Maximal length
$pwd_max_length = 0;
# Minimal lower characters
$pwd_min_lower = 0;
# Minimal upper characters
$pwd_min_upper = 1;
# Minimal digit characters
$pwd_min_digit = 1;
# Minimal special characters
$pwd_min_special = 1;
# Definition of special characters
$pwd_special_chars = "^a-zA-Z0-9";
# Forbidden characters
#$pwd_forbidden_chars = "@%";
# Don't reuse the same password as currently
$pwd_no_reuse = true;
# Check that password is different than login
$pwd_diff_login = true;
# Complexity: number of different class of character required
$pwd_complexity = 0;
# Show policy constraints message:
# always
# never
# onerror
$pwd_show_policy = "always";
# Position of password policy constraints message:
# above - the form
# below - the form
$pwd_show_policy_pos = "above";

# Who changes the password?
# Also applicable for question/answer save
# user: the user itself
# manager: the above binddn
$who_change_password = "user";
#$who_change_password = "binddn";

## Standard change
# Use standard change form?
$use_change = true;

## Questions/answers
# Use questions/answers?
# true (default)
# false
$use_questions = true;

# Answer attribute should be hidden to users!
$answer_objectClass = "extensibleObject";
$answer_attribute = "info";

# Extra questions (built-in questions are in lang/$lang.inc.php)
#$messages['questions']['ice'] = "What is your favorite ice cream flavor?";

## Token
# Use tokens?
# true (default)
# false
$use_tokens = true;
# Crypt tokens?
# true (default)
# false
$crypt_tokens = true;
# Token lifetime in seconds
$token_lifetime = "3600";

## Mail
# LDAP mail attribute
$mail_attribute = "mail";
# Who the email should come from
$mail_from = "admin@example.com";
$mail_from_name = "Self Service Password";
# Notify users anytime their password is changed
$notify_on_change = false;
# PHPMailer configuration (see https://github.com/PHPMailer/PHPMailer)
$mail_sendmailpath = '/usr/sbin/sendmail';
$mail_protocol = 'smtp';
$mail_smtp_debug = 0;
$mail_debug_format = 'html';
$mail_smtp_host = 'localhost';
$mail_smtp_auth = false;
$mail_smtp_user = '';
$mail_smtp_pass = '';
$mail_smtp_port = 25;
$mail_smtp_timeout = 30;
$mail_smtp_keepalive = false;
$mail_smtp_secure = 'tls';
$mail_contenttype = 'text/plain';
$mail_charset = 'utf-8';
$mail_priority = 3;
$mail_newline = PHP_EOL;

## SMS
# Use sms
$use_sms = true;
# GSM number attribute
$sms_attribute = "mobile";
# Partially hide number
$sms_partially_hide_number = true;
# Send SMS mail to address
$smsmailto = "{sms_attribute}@service.provider.com";
# Subject when sending email to SMTP to SMS provider
$smsmail_subject = "Provider code";
# Message
$sms_message = "{smsresetmessage} {smstoken}";

# SMS token length
$sms_token_length = 6;

# Max attempts allowed for SMS token
$max_attempts = 3;

# Reset URL (if behind a reverse proxy)
#$reset_url = $_SERVER['HTTP_X_FORWARDED_PROTO'] . "://" . $_SERVER['HTTP_X_FORWARDED_HOST'] . $_SERVER['SCRIPT_NAME'];

# Display help messages
$show_help = true;

# Language
$lang ="fr";

# Display menu on top
$show_menu = true;

# Logo
$logo = "images/ltb-logo.png";

# Background image
$background_image = "images/unsplash-space.jpeg";

# Debug mode
$debug = false;

# Encryption, decryption keyphrase
$keyphrase = "secret";

# Where to log password resets - Make sure apache has write permission
# By default, they are logged in Apache log
#$reset_request_log = "/var/log/self-service-password";

# Invalid characters in login
# Set at least "*()&|" to prevent LDAP injection
# If empty, only alphanumeric characters are accepted
$login_forbidden_chars = "*()&|";

## CAPTCHA
# Use Google reCAPTCHA (http://www.google.com/recaptcha)
$use_recaptcha = false;
# Go on the site to get public and private key
$recaptcha_publickey = "";
$recaptcha_privatekey = "";
# Customization (see https://developers.google.com/recaptcha/docs/display)
$recaptcha_theme = "light";
$recaptcha_type = "image";
$recaptcha_size = "normal";

## Default action
# change
# sendtoken
# sendsms
$default_action = "change";

## Extra messages
# They can also be defined in lang/ files
#$messages['passwordchangedextramessage'] = NULL;
#$messages['changehelpextramessage'] = NULL;

# Launch a posthook script after successful password change
#$posthook = "/usr/share/self-service-password/posthook.sh";

?>
  • documentation_technique/ldap_fusiondirectory.txt
  • Dernière modification : il y a 21 mois
  • de thomas