Première partie de la série de tuto sur OpenLDAP. Nous allons voir présentement l’installation et la configuration de ce logiciel.
Article révisé en octobre 2022
I – Installation
Classique, une mise à jour et on installe le paquet slapd.
# apt update && apt upgrade
# apt install slapd
Cependant, la configuration par défaut du paquet n’est peut être pas celle que vous voulez (elle se base sur le FQDN de la machine), bref, pour être sur :
# dpkg-reconfigure slapd
La, vous répondez comme cela :
Omit OpenLDAP server configuration?No
DNS domain name:Organization name?
debugo.fr
Administrator password:
Debugo
Confirm password:
PASSWORD
PASSWORD
Do you want the database to be removed when slapd is purged?
YES
Ensuite, un petit tour dans le fichier /etc/ldap/ldap.conf pour le configurer comme il faut (utilisé par les outils ldap en ligne de commande) :
BASE dc=debugo,dc=fr URI ldap://IP.MACHINE/
On test avec :
# ldapsearch -xLLL
ou bien
# ldapsearch -Y external -H ldapi:/// -b dc=debugo,dc=fr -LLL
Ce qui doit retourner quelque chose comme :
dn: dc=debugo,dc=fr objectClass: top objectClass: dcObject objectClass: organization o: debugo dc: debugo
Note de MAJ :
Avant, la commande retournait également le compte admin :
dn: dc=debugo,dc=fr objectClass: top objectClass: dcObject objectClass: organization o: debugo dc: debugo dn: cn=admin,dc=debugo,dc=fr objectClass: simpleSecurityObject objectClass: organizationalRole cn: admin description: LDAP administrator
Maintenant ce n’est plus le cas.
Si on veut retrouver notre compte admin :
# ldapsearch -QLLLY EXTERNAL -H ldapi:/// -b "olcDatabase={1}mdb,cn=config" olcRootDN OlcRootPW
et tada :
dn: olcDatabase={1}mdb,cn=config olcRootDN: cn=admin,dc=debugo,dc=fr olcRootPW: {SSHA}xxxxxxxxxxxx
Pour avoir d’autres informations sur le serveur, vous pouvez utiliser les commandes suivantes :
# slapd -V # ldapsearch -Y external -H ldapi:/// -b cn=config "(objectClass=olcGlobal)" -LLL
-LLL : Permet de ne pas afficher certains informations superflues dans la sortie (testez avec et sans pour voir la différence …)
Comme je l’expliquais dans l’introduction de cette série de tutoriels, la configuration n’est plus dans un fichier unique, mais sous forme de DIT (cn=config). On peut en avoir un aperçu avec la commande
# tree /etc/ldap/slapd.d/
/etc/ldap/slapd.d/ |-- cn=config | |-- cn=module{0}.ldif | |-- cn=schema | | |-- cn={0}core.ldif | | |-- cn={1}cosine.ldif | | |-- cn={2}nis.ldif | | `-- cn={3}inetorgperson.ldif | |-- cn=schema.ldif | |-- olcBackend={0}mdb.ldif | |-- olcDatabase={-1}frontend.ldif | |-- olcDatabase={0}config.ldif | `-- olcDatabase={1}mdb.ldif `-- cn=config.ldif
Si la commande tree n’existe pas :
# apt-get install tree
A vrai dire, on peut encore configurer en passant par le fichier slapd.conf mais cela requiert un redémarrage du serveur à chaque modification. De plus, cette méthode n’est pas recommandée.
II – LDAP en détail
A – Les Schémas
Si vous regardez le résultat de la commande :
# tree /etc/ldap/slapd.d/
Vous voyez plusieurs entrées sous la branche cn=schema. En l’occurrence, core, cosine, nis et inetorgperson.
Ce sont en quelque sorte les modèles qu’utiliseront vos futurs enregistrement (quel attribut, de quel type, etc..). Ceux déjà intégrés sont les plus couramment utilisés, mais il en existe d’autres, soit déjà disponibles dans /etc/ldap/schema :
# ls /etc/ldap/schema/*.ldif
Il est aussi tout à fait possible de créer vos propres schémas, afin que votre annuaire réponde précisément à vos besoins.
B – Les commandes
Pour modifier la configuration du serveur nous utiliserons principalement les commandes ldapadd, ldapmodify, ldapdelete (installées avec le paquet ldap-utils) Ces dernières prennent en option un fichier (option -f) de format ldif (Ldap Data Interchange Format).
Nous allons rapidement voir de quoi il s’agit.
Pour effectuer des requêtes, nous utiliserons la commande ldapsearch.
Celle ci peut interroger le serveur LDAP de plusieurs façons.
Sur le socket interne :
# ldapsearch -Q -Y external -H ldapi:/// -b cn=config
L’option -Q cache les infos SASL, inutile à l’affichage.
Ou sur un socket réseau :
# ldapsearch -x -H ldap://localhost -D cn=admin,dc=debugo,dc=fr -W -b cn=config
Sur le socket réseau, nous indiquons les options :
- -x : authentification simple
- -H indique l’hôte (en l’occurrence, localhost)
- -D est le compte qui va se connecter
- -W sert à demander le mot de passe
- -b ou basedn est l’endroit ou nous voulons faire notre recherche
La commande fonctionne mais ne retourne rien. Le compte admin n’a pas accès à la configuration en passant par le socket réseau (nous allons y remédier après).
Au passage, pourquoi donc s’embêter alors qu’on ne pourrait qu’utiliser le socket interne ?
L’intérêt du socket réseau est qu’on peut lancer les commandes à distance (dans ce cas remplacer localhost par le nom de la machine distante).
C – BaseDn, Filtres, Attributs
Je reviens sur la commande :
# ldapsearch -Q -LLL -Y external -H ldapi:/// -b cn=config
Celle ci affiche donc l’intégralité de l’arbre cn=config (le baseDN de notre requête).
Au passage, on peut l’écrire sous la forme :
# ldapsearch -QLLLY EXTERNAL -H ldapi:/// -b "cn=config"
Si l’on veut n’afficher que les attributs dn des résultats, on fera alors :
# ldapsearch -QLLLY EXTERNAL -H ldapi:/// -b "cn=config" dn
Si par exemple, je veux afficher d’autres attributs :
# ldapsearch -QLLLY EXTERNAL -H ldapi:/// -b "cn=config" "(objectClass=olcModuleList)" dn olcModuleLoad
Dans la commande précédente, j’utilise un filtre. Pour les utiliser, il suffit de les indiquer après l’option -b et avant ce que l’on demande par ex :
# ldapsearch -QLLLY EXTERNAL -H ldapi:/// -b "cn=config" "(&(objectClass=olcDatabaseConfig))" dn
Cette commande n’affichera que les attributs dn des objectClass olcDatabaseConfig. Le & est facultatif. J’aurais très bien pu mettre :
# ldapsearch -QLLLY EXTERNAL -H ldapi:/// -b "cn=config" "(objectClass=olcDatabaseConfig)" dn
Si l’on ne veut pas que les attributs dn, mais toutes les infos :
# ldapsearch -QLLLY EXTERNAL -H ldapi:/// -b "cn=config" "(&(objectClass=olcDatabaseConfig))"
Et si je voulais les attributs dn des objectClass étant des olcDatabaseConfig ou ceux étant des olcModuleList, je vais utiliser le | pour indiquer un OU (le ET étant spécifié par &)
# ldapsearch -QLLLY EXTERNAL -H ldapi:/// -b "cn=config" "(|(objectClass=olcDatabaseConfig)(objectClass=olcModuleList))" dn
Petite explication sur l’utilisation des filtres. Ceux ci utilisent un principe qui rappelle la notation polonaise inversée, l’opérateur étant ici devant.
Exemple :
Si je veux A et B :
( & (A) (B) )
Si je veux A ou B
( | (A) (B) )
Si je veux A et B ou A et C :
( | ( & (A) (B) ) ( & (A) (C) ) )
ou, en simplifiant :
( & (A) ( | (B) (C) ))
On peut aussi inverser avec le !.
Si l’on veut par ex ce qui est A et ce qui n’est pas B :
( & (A) (! B) )
Au niveau des filtres, nous pouvons utiliser les opérateurs suivants :
- < : plus petit que
- <= : plus petit ou égal
- = : égal
- > : plus grand
- >= : plus grand ou égal
- =* : présence de (retourne les entrées ou l’attribut est présent)
- ~= : approximation ( par ex, ~=Nocolas pourra retourner Nicolas)
On peut utiliser un joker, par ex, = *toto* sortira tout ce qui contient toto comme sous chaîne.
Il existe également la notion de filtres étendus, utilisé ainsi : attribut:dn:=valeur.
Par ex :
# ldapsearch -xLLL -H ldap://localhost -D cn=admin,dc=debugo,dc=fr -w password -b "dc=debugo,dc=fr" ou=people dn
me donne :
dn: ou=people,dc=debugo,dc=fr
Et :
# ldapsearch -xLLL -H ldap://localhost -D cn=admin,dc=debugo,dc=fr -w password -b "dc=debugo,dc=fr" ou:dn:=people dn
me donne :
dn: ou=people,dc=debugo,dc=fr dn: ou=client,ou=people,dc=debugo,dc=fr dn: ou=debugo,ou=people,dc=debugo,dc=fr dn: uid=niko,ou=debugo,ou=people,dc=debugo,dc=fr dn: uid=ldap1,ou=debugo,ou=people,dc=debugo,dc=fr dn: uid=ldap2,ou=debugo,ou=people,dc=debugo,dc=fr
Ils permettent donc de considérer les éléments du DN comme faisant partie de l’entrée elle même.
On peut également utiliser les filtres étendus pour modifier les opérateurs.
# ldapsearch -xLLL -H ldap://localhost -D cn=admin,dc=debugo,dc=fr -w password -b "dc=debugo,dc=fr" title:2.5.13.5:=Admin dn
ne me sortira que les entrées ou l’attribut title est égal à Admin (et non pas admin, ADMIN, etc…). Par défaut, l’opération n’est pas sensible à la casse.
Pour connaitre l’ensemble des matchingRules disponibles :
# ldapsearch -xLLL -D cn=admin,dc=debugo,dc=fr -w password -b "cn=subschema" -s base matchingRuleUse | grep "matchingRule" | cut -d ' ' -f3,5
III – Configuration
Nous allons créer un répertoire /root/ldap/conf qui va centraliser tous nos fichiers de configuration :
# cd # mkdir ldap # cd ldap # mkdir conf # cd conf
A – Compte admin
1 – Mdp Admin dans un fichier
Afin d’éviter d’avoir à toujours retaper le mot de passe admin (mot de passe que nous avons créé lors de la configuration du paquet) lors des commandes, nous allons l’enregistrer dans un fichier.
On va créer un fichier /root/pwdldap et mettre le mot de passe dedans :
# echo -n "mdpadmin" > /root/pwdldap # chmod 600 /root/pwdldap
On test :
# ldapsearch -x -H ldap://localhost -D cn=admin,dc=debugo,dc=fr -y /root/pwdldap -b dc=debugo,dc=fr
2 – Droits d’accès à la configuration du serveur
Par défaut, l’accès à la configuration n’est pas possible en passant par le socket réseau avec le compte admin :
# ldapsearch -xLLL -H ldap://localhost -D cn=admin,dc=debugo,dc=fr -y /root/pwdldap -b cn=config
nous donne :
No such object (32)
Créez le fichier LDIF /root/ldap/conf/acces-conf-admin.ldif, et insérez :
dn: olcDatabase={0}config,cn=config changeType: modify add: olcAccess olcAccess: to * by dn.exact=cn=admin,dc=debugo,dc=fr manage by * break
Injectez :
# ldapmodify -Y external -H ldapi:/// -f acces-conf-admin.ldif
Et restestez :
# ldapsearch -x -H ldap://localhost -D cn=admin,dc=debugo,dc=fr -y /root/pwdldap -b dc=debugo,dc=fr
B – Logs à l’aide de Rsyslog
Par défaut, OpenLdap ne cause pas beaucoup. On va changer cela.
1 – Slapd
On extrait la configuration actuelle dans un fichier :
# ldapsearch -Y external -H ldapi:/// -b cn=config "(objectClass=olcGlobal)" olcLogLevel -LLL > log.ldif
Avant de continuer, jetez un œil à ce fichier :
dn: cn=config olcLogLevel: none
Explications :
La première ligne, DN est ce qu’on appelle le distinguished name, autrement dit, identifiant unique de l’entrée. La deuxième ligne contient l’attribut demandée lors de la requête (olcLogLevel), de valeur none. Vous comprendrez donc facilement que les logs sont, par défaut, désactivés.
On va modifier le fichier de la sorte :
dn: cn=config changetype: modify replace: olcLogLevel olcLogLevel: 256
Pour information, les différents niveau de log sont :
-1 : enable all debugging 0 : no debugging 1 : trace function calls 2 : debug packet handling 4 : heavy trace debugging 8 : connection management 16 : print out packets sent and received 32 : search filter processing 64 : configuration file processing 128 : access control list processing 256 : stats log connections/operations/results 512 : stats log entries sent 1024 : print communication with shell backends 2048 : print entry parsing debugging
On injecte :
# ldapmodify -Y EXTERNAL -H ldapi:/// -f log.ldif
On regarde le résultat :
# ldapsearch -Y external -H ldapi:/// -b cn=config "(objectClass=olcGlobal)" olcLogLevel
2 – Rsyslog
Éditez le fichier /etc/rsyslog.conf et ajoutez à la fin :
LOCAL4.* -/var/log/slapd.log
Il faut redémarrer rsyslog :
service rsyslog restart
Lancez une requête et consulter le contenu du fichier /var/log/slapd.log:
ldapsearch -Y external -H ldapi:/// -b dc=debugo,dc=fr tail /var/log/slapd.log
Normalement, on doit avoir un contenu assez significatif de ce qui a été exécuté par le serveur OpenLDAP.
Voila qui termine cette première partie de la série. Dans la suite, nous allons continuer la configuration de notre serveur en lui ajoutant des Overlays.
Bonjour,
je lance la seconde commande de votre tutoriel : dpkg-reconfigure slapd
Je suis chaque étape, sauf que la dernière ne met jamais proposé : Allow LDAPv2 protocol?
Au lieu, j’ai le droit à ceci : Move old database? [yes/no]
Ensuite j’édite mon fichier ldap.conf comme ceci : (je ne comprends pas exactement à quoi sert URI.)
BASE dc=debugo,dc=fr
URI ldap://IP.MACHINE/
Et quand je teste avec votre commande : # ldapsearch -xLLL il me répond :
ldap_sasl_bind(SIMPLE): Can’t contact LDAP server (-1)
Merci
pour la commande, c’est normal, pas d’inquiétude.
Pour le fichier, qu’avez vous mis exactement ?
le dc est celui que vous avez renseigné ?
L’IP est bien celle sur laquelle slapd écoute ?
Merci beaucoup pour cette série de Tutos Nicolas ! L’une des rares ressources en français ou c’est résumé et très clair.
Tu m’a sauvé la vie 😀
Si mes tutos sauvent des vies alors, c’est merveilleux 😉
Merci en tout cas pour le compliment !
ca fait 15 jours que j’essaye de comprendre mais merci d’écrire clairement la démarche pour avoir un accès réseau sur le cn=config avec le compte admin !!
Oups, je n’avais pas vu ce commentaire…
Peux tu me dire précisément ce qui bloque ?
Bonsoir Nicolas
La partie sur ldapsearch doit suivre la partie création des UO, car ensuite tu fais une requête sur des UO précises, alors qu’aucune n’est créée ?
Est ce cela ? cette partie manque t elle ?
Bonsoir Richard (désolé pour la réponse tardive)
Ici, on requête sur l’arbre de config (cn=config) donc, tout est normal 🙂
Bonjour, la mienne ne fonctionne pas lorsque j’essaye de contacter mon serveur avec ldapsearch, il écrit « can’t contact LDAP server » que puis je faire?