Cours 4: LDAP

(Lightweight Directory Access Protocol)

Annuaires électroniques (NIS/YP, LDAP, Active Directory)

Typiquement, gérer les utilisateurs:

  • Identifier: qui est-ce (nom, prénom, …)
  • Authentifier: vérifier que c’est bien cette personne (mot de passe, clé publique ssh/gpg, ..)
  • Autoriser: quel droit a-t-elle

De manière centralisée:

  • Ne pas avoir à configurer chaque poste
  • Pouvoir facilement sauvegarder cette information
  • Sans pour autant devenir un SPOF (Single Point Of Failure)
    • Redondance

Mais pas que des utilisateurs:

  • Peut être aussi des groupes d’utilisateurs, des machines, …
  • Essentiellement, un recensement

-> fonctionnement générique -> un peu abstrait…

Vocabulaire LDAP

  • dc = Domain Component: essentiellement comme un nom de domaine
  • ou = Organizational Unit: type de resource recensée
  • cn = Common Name: nom d’une resource recensée
            dc=fr
              |
          dc=exemple
         /          \
   ou=machines    ou=personnes
       /              \      \
cn=serveur5         cn=Jean  cn=Jacques

En assemblant le tout, on obtient un dn (distinguished name) qui peut donc désigner une personne, une machine, un groupe, …:

cn=serveur5,ou=machines,dc=exemple,dc=fr

Une entrée (ou object) dans la BASE ldap, désignée par le dn, est alors une fiche contenant les diverses informations utiles, par exemple:

dn: cn=Jean,ou=personnes,dc=exemple,dc=fr
cn: Jean
givenName: Jean
sn: Lapin
telephoneNumber: +33 12 34 56 78
telephoneNumber: +33 12 34 56 79
manager: cn=Jacques,ou=personnes,dc=exemple,dc=fr
mail: jean@exemple.fr
uid: jean
uidNumber: 1000
gidNumber: 1000
userPassword:: e1NTSEF9dXNhSFVzYWcvTXpsL2FsNE9Kd1NUL2JEUElTb3FhTzIK
loginShell: /bin/zsh
homeDirectory: /home/jean
objectClass: top
objectClass: person
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: posixAccount

Schémas

Beaucoup d’informations dans un objet LDAP ! (Il y a même un attribut drink pour indiquer la boisson favorite d’une personne :) )

Essentiellement des attributs sous forme de clé-valeur, mais comment s’y retrouver, comment est-on censé nommer les attributs ? Grâce aux schémas.

Ajouter objectClass: truc indique que la fiche respecte le schéma truc.

Chaque schéma précise quels attributs doivent (ou peuvent) être renseignés. Par exemple posixAccount:

$ grep -r posixAccount /etc/ldap/schema
/etc/ldap/schema/nis.schema:objectclass ( 1.3.6.1.1.1.2.0 NAME 'posixAccount'
$ less /etc/ldap/schema/nis.schema
[...]
objectclass ( 1.3.6.1.1.1.2.0 NAME 'posixAccount'
        DESC 'Abstraction of an account with POSIX attributes'
        SUP top AUXILIARY
        MUST ( cn $ uid $ uidNumber $ gidNumber $ homeDirectory )
        MAY ( userPassword $ loginShell $ gecos $ description ) )

On y voit qu’il est obligatoire d’avoir un cn (pas très étonnant), un uid, un uidNumbmer, un gidNumber, et un homeDirectory, pas très étonnant pour un compte unix.

On voit qu’il est possible de préciser le userPassword (pour pouvoir authentifier), mais aussi le loginShell par exemple.

Un objet respecte typiquement plusieurs schéma, pour répondre à différents besoins (compte unix, personne, organisation dans l’entreprise, …)

Requêtes

Une fois qu’on a créé différents objets dans notre base LDAP, on peut faire des requêtes, un peu comme SQL:

# ldapsearch -H ldapi:/// -Y EXTERNAL -b dc=exemple,dc=fr uid=jean
dn: cn=Jean,ou=personnes,dc=exemple,dc=fr
cn: Jean
[...]

L’option -H précise à quel serveur ldap on s’adresse (ici, la machine locale).

L’option -Y précise comment on s’authentifie (ici, on est root donc c’est immédiat avec le choix EXTERNAL).

L’option -b précise dans quelle partie de ldap on veut chercher.

uid=jean est le critère de recherche.

On aurait aussi pu mettre par exemple `telephoneNumber=+33 12 34 56 78” pour retrouver qui possède ce numéro de téléphone.

Ou mettre mail=jean@exemple.fr pour vérifier s’il y a quelqu’un qui possède cette adresse mail (et ensuite regarder homeDirectory pour savoir où déposer un mail reçu)

Authentification, “bind”

Ci-dessus, on a utilisé le fait d’être root pour gagner le droit à interroger ldap. C’est un peu triché…

Et quand on aura plusieurs serveurs (mail, web, …) qui voudront interroger voire modifier la base ldap, on voudra les mettre sur des machines différentes.

On crée donc plutôt un objet, par exemple pour permettre à postfix d’accéder à ldap:

dn: uid=postfix,ou=services,dc=exemple,dc=fr
objectClass: inetOrgPerson
cn: Postfix
sn: Postmaster
uid: postfix
userPassword:: e1NTSEF9dXNhSFVzYWcvTXpsL2FsNE9Kd1NUL2JEUElTb3FhTzIK

On peut essayer de l’utiliser pour faire une requête:

$ ldapsearch -H ldaps://ldap.exemple.fr -x -W -D uid=postfix,ou=services,dc=exemple,dc=fr -b dc=exemple,dc=fr mail=jean@exemple.fr
Enter LDAP Password:
dn: cn=Jean,ou=personnes,dc=exemple,dc=fr
cn: Jean
[...]

Ici on a utilisé avec -H une connexion via TCP/IP, mais chiffrée (ldaps).

On a demandé une authentification simple (-x -W) en utilisant l’objet ci-dessus pour s’authentifier (avec -D), et on a tapé le mot de passe.

Et on cherchait dans le champ mail.

Configurer un démon pour utiliser l’annuaire ldap, c’est donc essentiellement:

  • Indiquer quel serveur LDAP contacter
  • Quel objet LDAP utiliser pour s’authentifier
  • Le mot de passe associé
  • Quel champ utiliser pour chercher l’information

Outils de gestion

On peut faire tout à la main avec ldapsearch, ldapadd, ldapdelete, ldapmodify, c’est très pratique pour scripter des opérations.

On peut aussi utiliser des surcouches graphiques du genre phpLDAPadmin (PLA).