Outils pour utilisateurs

Outils du site


ateliers:serveurmail:ldap

Ceci est une ancienne révision du document !


LDAP

LDAP est un serveur permettant de gérer des répertoires. Notre but ici et de pouvoir s'en servir pour s'identifier sur le serveur, afin de n'avoir qu'un seul endroit depuis lequel gérer les utilisatrices et les droits d'accès.

Nous connecterons donc le tour via PAM, afin de bénéficier au maximum des fonctionnalités d'Unix pour ces comptes.

Nous allons garder le schéma de données relativement simple, avec une ou Users pour les comptes, et une ou Groups pour gérer les groupes (administratrices, mais aussi plus tard, mailing lists par exemple).

Client graphique

Comme pour beaucoup de chose, il est possible de tout faire à la ligne de commande, avec les commandes du paquet ldap-utils, mais pour ajouter beaucoup de monde, cela peut s'avérer rapidement fastidieux. Disposer d'un système graphique permet généralement de modifier facilement l'arbre du répertoire.

Sous GNU/Linux, le projet gnome propose LAT, qui s'installe avec la commande apt:

$ sudo apt install lat

KDE fournit un client aux fonctionnalité identique, Kldap, installable avec apt par exemple.

D'autres clients graphique existent et sont disponible pour toutes les plateformes.

Services utilisant LDAP

Une rapide liste des services utilisant LDAP, afin que tout le monde puisses'y retrouver rapidement.

  • PAM - Lisez donc la suite pour voir comment faire
  • SSH - afin de pouvoir stocker la clef publique ssh dans l'arbre LDAP

Installation

Sur notre machine debian, il faut commencer par installer les paquets nécessaire pour faire tourner LDAP.

  $ sudo apt install slapd ldap-utils
  • ldap-utils fournit des commandes permettant de modifier un arbre LDAP (via ldapmodify par exemple).
  • slapd est le nom du paquet debian pour le serveur openldap.

On conserve les choix par défaut et on donne un mot de passe au gestionnaire de l'arbre.

Pour créer le domaine dont nous aurons besoin, il faut reconfigurer slapd et garder les valeurs par défaut, sauf pour le nom de domaine (anarcha.pink dans notre cas), et le nom de l'organisation (Anarcha).

 $ sudo dpkg-reconfigure slapd

Redémarrage et vérification que tout se passe bien avec systemctl.

$ sudo systemctl restart slapd
$ sudo susytemctl status slapd
● slapd.service - LSB: OpenLDAP standalone server (Lightweight Directory Access Protocol)
   Loaded: loaded (/etc/init.d/slapd; generated; vendor preset: enabled)
   Active: active (running) since Wed 2018-06-27 17:03:09 CEST; 22min ago
     Docs: man:systemd-sysv-generator(8)
  Process: 18561 ExecStop=/etc/init.d/slapd stop (code=exited, status=0/SUCCESS)
  Process: 18568 ExecStart=/etc/init.d/slapd start (code=exited, status=0/SUCCESS)
    Tasks: 3 (limit: 4915)
   CGroup: /system.slice/slapd.service
           └─18576 /usr/sbin/slapd -h ldap:/// ldapi:/// -g openldap -u openldap -F /etc/ldap/slapd.d
[...]

Par la suite, les modifications à l'arbre cn=config de LDAP se feront en utilisant la commande ldapmodify comme suit:

$ sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f[/chemin/vers/un/fichier.ldif

TLS

Nous voulons avoir une connexion chiffrée lorsque nous nous connectons depuis l'extérieur du serveur, et cela va se faire grâce à [letsencrypt] sur le domaine ldap.anarcha.pink.

Il est nécessaire, pour que LDAP puisse démarrer avec TLS, que l'utilisateur openldap ait les droits d'accès en lecture aux certificats et clefs générées par letsencrypt, ne pas oublier d'ajouter l'utilisateur au groupe tls.

  $ sudo adduser openldap tls

Maintenant, il faut modifier la configuration de slapd afin de lui donner les valeurs nécessaires pour gérer des connexions tls. Cela se fait en utilisant ldapmodify sur l'arbre cn=config en passant via le protocole ldapi:\/\/\/ - qui est un accès par socket Unix au lieu de passer par l'interface réseau, tout en précisant que, comme il n'y a pas vraiment d'utilisateur pour le moment, nous voulons utiliser l'authentification Unix de SASL.

Toutes les commandes seront stockées dans un fichier ldif afin de pouvoir faciliter un peu l'utilisation de la ligne de commande.

/usr/local/lin/ldap/letsencrypt.ldif
dn: cn=config
add: olcTLSCipherSuite
olcTLSCipherSuite: NORMAL
-
add: olcTLSCRLCheck
olcTLSCRLCheck: none
-
add: olcTLSVerifyClient
olcTLSVerifyClient: never
-
add: olcTLSCACertificateFile
olcTLSCACertificateFile: /etc/letsencrypt/live/ldap.anarcha.pink/fullchain.pem
-
add: olcTLSCertificateFile
olcTLSCertificateFile: /etc/letsencrypt/live/ldap.anarcha.pink/cert.pem
-
add: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/letsencrypt/live/ldap.anarcha.pink/privkey.pem
-
add: olcTLSProtocolMin
olcTLSProtocolMin: 3.3

Pour plus d'information sur l'utilité des clefs utilisées il faut se référer à Zytrax.

Il faut ensuite modifier les options du daemon slapd pour lui dire comment se connecter sur nos interfaces réseau en allant modifier le fichier /etc/default/slapd

/etc/default/slpad
[...]
SLAPD_SERVICES="ldap:\/\/127.0.0.1:389\/ ldaps:\/\/\/ ldapi:\/\/\/"
[...]

Cela force l'ouverture d'un canal en clair uniquement sur la boucle locale, et ouvre une connexion chiffrée sur l'ensemble des interfaces réseau ainsi que le fonctionnement classique par socket Unix avec ldapi:\/\/\/.

Redémarrage et tests

Une fois ceci fait, redémarrons le service et vérifions qu'il est bien démarré.

  $ sudo systemctl restart slapd
  $ sudo systemctl status slapd
Test du fonctionnement de l'arbre

Une commande rapide que l'on peut utiliser est ldapsearch afin de lister l'ensemble de ce qu'il y a dans l'arbre. La commande doit fournir un résultat si tout va bien. Comme d'habitude, la page de man fournit l'explication de chaque option utilisée ici (LLL permet l'affiche dans un format compatible ldif, H précise l'endroit sur lequel on se connecte, b précise oú chercher.

  $ ldapsearch -LLL -H ldapi:/// -b dc=anarcha,dc=pink
  
SASL/EXTERNAL authentication started
SASL username: gidNumber=1006+uidNumber=1007,cn=peercred,cn=external,cn=auth
SASL SSF: 0
dn: dc=anarcha,dc=pink
objectClass: top
objectClass: dcObject
objectClass: organization
o: Anarcha
dc: anarcha
 
dn: cn=admin,dc=anarcha,dc=pink
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: admin
description: LDAP administrator
Test de la connexion TLS

Depuis une machine distante, il est possible de vérifier que la cnnexion est chiffrée et valide. LDAP éćoute sur le port 636 pour le TLS.

$ openssl s_client --connect ldap.anarcha.pink:636
CONNECTED(00000003)                                       
depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3
verify return:1                    
depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
verify return:1                       
depth=0 CN = ldap.anarcha.pink
verify return:1                                        
---             
Certificate chain
 0 s:/CN=ldap.anarcha.pink                         
   i:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
 1 s:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
   i:/O=Digital Signature Trust Co./CN=DST Root CA X3
---            
Server certificate
-----BEGIN CERTIFICATE-----
[...]
Certificat de ldap.anarcha.pink
[...]
-----END CERTIFICATE-----
subject=/CN=ldap.anarcha.pink
issuer=/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
---
No client certificate CA names sent
Peer signing digest: SHA512
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 3239 bytes and written 302 bytes
Verification: OK
---
New, TLSv1.2, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
    Session-ID: 97D588825098C4361F4046846C5F7819F18656403B9EDB525F279CCB876AB426
    Session-ID-ctx:
    Master-Key: 126ADE5FB2B02BF693212955F4DD151C8105A48FD9D1BECC886E63AB81065D6B9E0EB814C057DA6FF59FFF4800BA3E85
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1530115216
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
    Extended master secret: yes
---

Un SIGKILL permet de terminer la connexion.

Ajout d'Overlays

Un Overlay est une surcouche à la base de donnée voulue, permettant d'ajouter des fonctionnalités supplémentaires.

Les surcouches qui ont été configurés par ldapmodify avec les fichiers ldif supplémentaires qui sont dans /usr/local/lib/ldap/overlays.

La syntaxe du DN de chaque surcouche utilise une notation avec {0} précédant le nom du module, cela nous permet d'être sûr que l'on configure la bonne surcouche.

Chaque surcouche doit être activé en chargeant un module, et donc en modifiant l'objet ayant le dn suivant: cn={0}module,cn=config. Pour avoir une liste des paramètres disponible, il faut regarder les pages de man de chaque surcouche (``man slapo-<module>``) et regarder les schémas associés à chaque surcouche pour trouver le nom des attributs dans la syntaxe cn=config.

Surcouches activées
  • memberOf pour disposer d'un attribut dynamique pour chaque membre listant les groupes auxquels il appartient
  • refint pour maintenir l'intégrité référentielle

D'autres surcouches pourront être ajoutée plus tard, par exemple pour loguer certaines erreurs.

Remplacement du schéma NIS

Afin que memberOf fonctionne, il faut pouvoir ajouter un groupeOfNames à un posixGroup.

Un objet ne peut avoir qu'une seule classe structurelle. Or posixGroup et groupOfNames sont toutes les deux des classes structurelles, il n'est donc pas possible avec le schéma NIS installé par défaut de pouvoir utiliser memberof ET de disposer d'un gidNumber.

La RFC implémentée par NIS (RFC2307) a cependant reçu une proposition, mais qui n'a jamais atteint le stade final. Il y a donc un schéma - rfc2307bis - supprimant la classe structurelle de l'objet posixGroup, nous permettant donc de pouvoir avoir un gidNumber ET un attribut memberOf sur nos objets groupes.

Il faut cependant supprimer le schéma NIS d'abord, puis activer le schéma 2307bis.

Pensez à sauvegarder vos données AVANT de faire les modifications de schéma ci-dessous.

Suppression du schéma NIS

Il n'est pas possible de faire un ldapdelete sur les schémas. la solution consiste donc à arrêter le service, supprimer le schéma de la base qui est alors composée de fichiers plats, puis de redémarrer le service.

$ sudo systemctl stop slapd
$ sudo systemctl status slapd
  ● slapd.service - LSB: OpenLDAP standalone server (Lightweight Directory Access Protocol)
   Loaded: loaded (/etc/init.d/slapd; generated; vendor preset: enabled)
   Active: inactive (dead) since Thu 2018-06-28 15:39:22 CEST; 13s ago
     Docs: man:systemd-sysv-generator(8)
  Process: 25434 ExecStop=/etc/init.d/slapd stop (code=exited, status=0/SUCCESS)
  Process: 24877 ExecStart=/etc/init.d/slapd start (code=exited, status=0/SUCCESS)
    Tasks: 0 (limit: 4915)
   CGroup: /system.slice/slapd.service
   [...]

Il faut maintenant aller modifier la configuration des schémas. Elle est disponible sous /etc/ldap/slapd.d/cn=config/cn=schema/

Ce répertoire contient des fichiers ldif ordonnés (commençant par {Z}avec Z le numéro d'ordre)

$ sudo ls -l /etc/ldap/slapd.d/cn\=config/cn=schema
total 40
-rw------- 1 openldap openldap 15596 juin  27 16:24 cn={0}core.ldif
-rw------- 1 openldap openldap 11381 juin  27 16:24 cn={1}cosine.ldif
-rw------- 1 openldap openldap  6513 juin  27 16:24 cn={2}nis.ldif
-rw------- 1 openldap openldap  2875 juin  27 16:24 cn={3}inetorgperson.ldif

Dans notre cas, nous avons le schéma nis auquel est attribué le numéro 2. On supprime ce fichier (pensez à faire une sauvegarde de /etc/ldap/slap.d AVANT). Puis on renomme les schéna ayant un ordre supérieur pour obtenir une suite numérique continue de schémas.

$ sudo rm /etc/ldap/slapd.d/cn\=config/cn\=schema/cn\=\{2\}nis.ldif
$ sudo mv /etc/ldap/slapd.d/cn\=config/cn\=schema/cn\=\{{3,2}\}inetorgperson.ldif
$ sudo ls -l /etc/ldap/slapd.d/cn\=config/cn=schema
-rw------- 1 openldap openldap 15596 juin  27 16:24 cn={0}core.ldif
-rw------- 1 openldap openldap 11381 juin  27 16:24 cn={1}cosine.ldif
-rw------- 1 openldap openldap  2875 juin  27 16:24 cn={2}inetorgperson.ldif

Sur notre configuration, les ACL étaient définie sur un attribut shadowLastChange fourni par le schéma NIS, il a é nécessaire d'éditer le fichier contenant ls ACL avant de pouvoir redémarrer ldap (fichier situé dans /etc/ldap/slapd.d/cn=config/olcDatabase=\{1\}mdb.ldif dans notre cas)

Et on redémarre le tout.

$ sudo systemctl start slapd
$ sudo systemctl status slapd
● slapd.service - LSB: OpenLDAP standalone server (Lightweight Directory Access Protocol)
   Loaded: loaded (/etc/init.d/slapd; generated; vendor preset: enabled)
   Active: active (running) since Thu 2018-06-28 15:58:41 CEST; 3s ago
     Docs: man:systemd-sysv-generator(8)
  Process: 25434 ExecStop=/etc/init.d/slapd stop (code=exited, status=0/SUCCESS)
  Process: 25576 ExecStart=/etc/init.d/slapd start (code=exited, status=0/SUCCESS)
    Tasks: 3 (limit: 4915)
   CGroup: /system.slice/slapd.service
           └─25582 /usr/sbin/slapd -h ldap://127.0.0.1:389/ ldaps:/// ldapi:/// -g openldap -u openldap -F /etc/ldap/slapd.d

Tout fonctionne.

Installation du schéma rfc2307bis

Le remplacement du schéma NIS est disponible dans un paquet debian pour l'application gosa. On ne veut que les schémas LDAP.

$ sudo apt install gosa-schema

Les nouveaux schéma du paquet sont disponibles dans /etc/ldap/schema/gosa/. Pour chaque schéma, il y a deux fichiers. Le rfc2307bis.schema contient les déclaration formelle des types LDAP fournit par le schéma, alors que le fichier rfc2307bis.ldif contiens lui la déclaration au format ldif pour installer le schéma sur nos bases.

Cette modification se fait par root sur l'OLC cn=config

$ sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/gosa/rfc2307bis.ldif
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
adding new entry "cn=rfc2307bis,cn=schema,cn=config"

Un rapide coup d'œil à la configuration lisible dans /etc/ldap/slap.d/cn\=config/cn\=schema nous montre que le schéma rfc2307bis est bien actif.

$ sudo ls /etc/ldap/slapd.d/cn\=config/cn\=schema/ -l
-rw------- 1 openldap openldap 15596 juin  27 16:24 cn={0}core.ldif
-rw------- 1 openldap openldap 11381 juin  27 16:24 cn={1}cosine.ldif
-rw------- 1 openldap openldap  2875 juin  27 16:24 cn={2}inetorgperson.ldif
-rw------- 1 openldap openldap  9609 juin  28 16:07 cn={3}rfc2307bis.ldif

Modifications des ACL

LDAP permet de restreindre l'accès à certains attributs, ou a des parties entières d'un arbre, en utilisant des règles de contrôle d'accès (ou ACL).

Il faut les ajouter à la base cn=config, mais attention. leur ordre est important, elles sont exécutée l'une après l'autre. Une documentation complète et touffue du fonctionnement des ACL est disponible sur le site du projet openldap.

Pour référence, voici les ACL telles que fournies après l'installation d'OpenLDAP, On utilise la commande suivante pour les voir :

$ sudo ldapsearch -Y EXTERNAL -H ldapi:/// -b cn=config olcAccess
# {0}config, config
dn: olcDatabase={0}config,cn=config
olcAccess: {0}to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage by * break
 
# {1}mdb, config
dn: olcDatabase={1}mdb,cn=config
olcAccess: {0}to attrs=userPassword by self write by anonymous auth by * none
olcAccess: {1}to attrs=shadowLastChange by self write by * read
olcAccess: {2}to * by * read

Il y a deux bases concernées par les ACL. La première concerne cn=config et définit qui peut mdifier la base cn=config. En l'occurence, ici, on donne l'accès à root (gidNumber = 0 et uidNumber = 0), et personne d'autre n'y a accès.

Sur la seconde base, on définit l'accès à des attributs spécifiques au seul utilisateur (ou lors de la phase d'authentification), ce qui concerne les champs userPassword (règle {0})et shadowLastChange (règle {1}). Enfin, nous permettons à tout le monde de pouvoir lire l'intégralité de l'arbre.

Le fichier /usr/local/lib/ldap/acl.ldif contient l'ensemble des ACL en place. Pour plus de détail sur les ACL implémentée sur anarcha voir le fichier ACL commenté.

Peuplement des premiers items

Vu que LDAP est un annuaire structuré, commençons par créer deux Organizational Unit (ou) qui nous servirons par la suite. Une première ou pour les utilisateurs et une seconde pour les groupes.

Nous en profitons aussi pour ajouter une OU System qui contiendra des comptes nécessaire au fonctionnement de LDAP ou pour connecter certains services à l'annuaire, au lieu de les bnder sur le rootdn.

La structure de donnée de l'arbre Anarcha est détaillée dans notre schéma, avec notamment les attributs que l'on peut utiliser, les classes associées aux DN et autres. C'est cette page qui sert de référence pour la structure des arbres du LDAP anarcha.

Voici le fichier ldif à ajouter avec la commande ldapadd

/usr/local/lib/ldap/organizational.ldif
dn: ou=Users,dc=anarcha,dc=pink
ou: Users
objectClass: organizationalUnit
 
dn: ou=Groups,dc=anarcha,dc=pink
ou: Groups
objectClass: organizationalUnit
 
dn: ou=System,dc=anarcha,dc=pink
ou: System
objectClass: organizationalUnit

Nous utiliserons une syntaxe permettant de se connecter avec le compte admin.

  $ ldapadd -xWD cn=admin,dc=anarcha,dc=pink -H ldapi:/// -f /usr/local/lib/ldap/organizational.ldif

Il aurait été possible d'exécuter la commande ainsi, évitant ainsi de devoir taper le mot de passe admin (si vous avez les droits sudo, vous pouvez exécuter les commandes ldapadd, ldapmodify, etc).

  $ ldapadd -Y EXTERNAL -H ldapi:/// -f /usr/local/lib/ldap/organizational.ldif

Une recherche permet ensuite de vérifier que nos groupes ont bien été créé

  $ ldapsearch -H ldapi:/// "(objectClass=organizationalUnit)" -b dc=anarcha,dc=pink
SASL/EXTERNAL authentication started
SASL/EXTERNAL authentication started
SASL username: gidNumber=1006+uidNumber=1007,cn=peercred,cn=external,cn=auth
SASL SSF: 0
# extended LDIF
#
# LDAPv3
# base <dc=anarcha,dc=pink> with scope subtree
# filter: (objectClass=organizationalUnit)
# requesting: ALL
#
 
# Users, anarcha.pink
dn: ou=Users,dc=anarcha,dc=pink
ou: Users
objectClass: organizationalUnit
 
# Groups, anarcha.pink
dn: ou=Groups,dc=anarcha,dc=pink
ou: Groups
objectClass: organizationalUnit
 
# System, anarcha.pink
dn: ou=System,dc=anarcha,dc=pink
ou: System
objectClass: organizationalUnit
 
# search result
search: 4
result: 0 Success
 
# numResponses: 3
# numEntries: 2

Nos OU ont été créées, tout va bien Nous allons pouvoir passer à la suite des opérations.

Nobody

Afin de pouvoir créer des groupOfNames vide, nous avons besoin d'un utilisateur nobody. Il existe également comme compte Unix et, généralement, n'a pas de droits.

Sur le même principe, nous allons donc créer un utilisateur nobody, qui héritera des mêmes uid et gid que dans /etc/passwd d'Unix.

/usr/local/lib/ldap/nobody.ldif
dn: uid=nobody,ou=System,dc=anarcha,dc=pink
uid: nobody
cn: nobody
sn: nobody
objectClass: top
objectClass: person
objectClass: posixAccount
objectClass: shadowAccount
loginShell: /bin/nologin
homeDirectory: /nonexistent
uidNumber: 65534
gidNumber: 65534

Il s'agît ensuite, simplement, de l'ajouter avec ldapadd.

$ ldapadd -xcWD cn=admin,cn=anarcha,cn=pink -f nobody.ldif
$ ldapsearch -xb dc=anarcha,dc=pink '(uid=nobody)'
# nobody, System, anarcha.pink
dn: uid=nobody,ou=System,dc=anarcha,dc=pink
uid: nobody
cn: nobody
sn: nobody
objectClass: top
objectClass: person
objectClass: posixAccount
objectClass: shadowAccount
loginShell: /bin/nologin
homeDirectory: /nonexistent
uidNumber: 65534
gidNumber: 65534

Il faudra dans les ACL s'assurer que cet utilisateur n'a aucun droits car il sera présent dans tous les groupes et que nous voulons que, justement, cet utilisateur n'ait aucun droit.

Groupe sudo

Nous allons ajouter un groupe dans l'arbre LDAP qui donnera les droits sudo aux personnes en ayant besoin, sur le même principe que le groupe sudo unix, donc avec le même gid.

Récupération du gid du groupe sudo. Il s'agît de la 3eme colonne dans la commande suivante :

$ getent group sudo
sudo:x:27:some,username,here,but,i,removed,them,for,privacy

Il nous suffit ensuite de créer un groupe. La classe d'objet choisie est ``posixGroup``, elle permet d'associer un groupe à un champ gid, facilitant donc l'intégration dans unix.

/usr/local/lib/ldap/groups.ldif
dn: cn=sudo,ou=Groups,dc=anarcha,dc=pink
objectClass: top
objectClass: posixGroup
objectClass: groupOfNames
cn: sudo
gidNumber: 27
member: uid=nobody,ou=System,dc=anarcha,dc=pink

La ligne vide en fin de fichier est importante, elle permet de dire aux commandes ldap qu'il s'agît de la fin d'une entité. On peut maintenant ajouter ce groupe à l'annuaire. En utilisant l'option -c on permet à la commande de continuer, même en cas d'erreur, ce qui s'avèrera pratique pour pouvoir ajouter d'autres groupes par la suite.

$ ldapadd -cxWD "cn=admin,dc=anarcha,dc=pink" -f groups.ldif
Enter LDAP Password:  
adding new entry "cn=sudo,ou=Groups,dc=anarcha,dc=pink"

Mapping de comptes LDAP vers des com[tes Unix

Lorsque nous utilisons les outils LDAP depuis la ligne de commande, OpenLDAP utilise le fichier /etc/ldap/ldap.conf pour fournir quelques valeurs par défut, typiquement pour savoir oú se connecter et en tant que quel utilisateur.

C'est à ça que nous sert, entre autres, l'utilisateur dn=system,ou=System (voir le schéma et les ACL pourplus de détail sur cet utilisateur).

ldapwhoami est un outil du paquet openldap nous permettant de poser une question simple au serveur LDAP: Qui suis-je ?. ldapwhoami va donc utiliser la configuration de ldap.conf pour afficher le DN de l'utilisateur exécutant cette commande. Le fichier contenant ceci :

/etc/ldap/ldap.conf
#
# LDAP Defaults
#
 
# See ldap.conf(5) for details
# This file should be world readable but not world writable.
 
BASE    dc=anarcha,dc=pink
URI     ldapi:///
BINDDN  dc=system,ou=System,dc=anarcha,dc=pink
 
#SIZELIMIT      12
#TIMELIMIT      15
#DEREF          never
 
# TLS certificates (needed for GnuTLS)
TLS_CACERT      /etc/ssl/certs/ca-certificates.crt

Cela revient à préciser les paramètres suivant sur l'ensemble des commandes ldap:

$ ldapsearch -H ldappi:/// -b dc=anarcha,dc=pink -D "dc=system,ou=System,dc=anarcha,dc=pink"

Ce fichier mous permet de sensiblement réduire la liste des paramètres tapés à chaque commande. Et donc, comme nous utilison SASL, le serveur LDAP va utiliser unmécanisme approprié. Par défaut, et en absence d'un service sasl, le serveur OpenLDAP utilise le mécanise EXTERNAL.

$ ldapsearch -b cn=config -s base -b "" supportedSASLMechanisms
SASL/EXTERNAL authentication started
SASL username: gidNumber=1006+uidNumber=1007,cn=peercred,cn=external,cn=auth
SASL SSF: 0
# extended LDIF
#
# LDAPv3
# base <> with scope baseObject
# filter: (objectclass=*)
# requesting: supportedSASLMechanisms
#
 
#
dn:
supportedSASLMechanisms: EXTERNAL
 
# search result
search: 3
result: 0 Success
 
# numResponses: 2
# numEntries: 1

Ce que fait ce module EXTERNAL est de créer une authentification en utilisant l'UID et le GID de l'utilisateur connecté. ldapwhoami va donc, logiquement, nous dire que nous sommes un utilisateur système :

$ ldapwhoami
SASL/EXTERNAL authentication started 
SASL username: gidNumber=1006+uidNumber=1007,cn=peercred,cn=external,cn=auth
SASL SSF: 0                       
dn: gidNumber=1006+uidNumber=1007,cn=peercred,cn=external,cn=auth

Ce qui ne correspond pas à un utilisateur dans notre nbase LDAP. A noter aussi que l'utilisateur root (uid et gid = 0) correspond à l'identification suivante, que nous retrouvons régulièrement dans les ACL :

gidNumber=1006+uidNumber=1007,cn=peercred,cn=external,cn=auth

Ce que nous voulons faire, c'est associé cette authentification à une entrée de notre base LDAP. Notre schéma indique que notre utilisateurs, si il à la classe posixAccount dispose d'un champ uidNumber, ce qui nous permettra d'associer notre compte Unix à un compte LDAP.

Et LDAP fournit justement une variable permettant de mapper une authentification à un compte. En utilisant les Expressions Régulières (qui vaudraient le coup d'un atelier à part entière au Reset) et une syntaxe normalisée, les URL LDAP, il est possible d'effectuer une substitution grâce au paramètre olcAuthzRegexp.

Les URL LDAP obéissent à la RFC 4516 et sont un moyen universel de créer des requêtes LDAP pouvant de fait fonctionner sur n'importe quel serveur LDAP, peu importe sa structure.

Très rapidement, il s'agit d'une URI ayant cette structure là :

ldap://<server>:<port>/<baseDn>?<attrsList>?<scope>?<filter>

Des informations plus détaillée sont disponibles sur le site ldap.com

Nous voulons, pour faire simple, que cette authentification là :

gidNumber=1006+uidNumber=1007,cn=peercred,cn=external,cn=auth

Soit associé à cet utilisateur là (certains attributs ont été masqués):

# okhin, Users, anarcha.pink
dn: uid=okhin,ou=Users,dc=anarcha,dc=pink
uid: okhin
cn: okhin
sn: okhin
objectClass: top
objectClass: person
objectClass: posixAccount
objectClass: shadowAccount
objectClass: ldapPublicKey
uidNumber: 1007
gidNumber: 1006
memberOf: cn=sudo,ou=Groups,dc=anarcha,dc=pink

L'association va se faire par le gidNumber et on va donc commnecer par créer notre URL LDAP de destination.

ldap:///ou=Users,dc=anarcha,dc=pink??one?(uidNumber=\$1)

Nous ne précisons pas de nom d'hôte ou de port, nous nous connecterons donc en localhost. Le reste de l'URL correspond aux valeurs suivantes :

  • baseDN: ou=Users,dc=anarcha,dc=pink On ne veut mapper que vers les utilisateurs,, pas vers autre chose
  • attrsList: <vide> On prend tous les attributs (même si filtrer sur dn doit fonctionner)
  • scope: one On ne veut pas explorer tout l'arbre, mais seulement un niveau sous la base.
  • filter: (uidNumber=\$1) On veut que le champ uidNumber ait la valeur du premier motif trouvé dans l'expression régulière (motif qui doit donc être entre parenthèse dans l'expression)

L'expression régulière d'analyse de l'authentification correspond à ce qu'il y à ci-dessous :

gidNumber=[0-9]+\+uidNumber=**([0-9}+)**,cn=peercred,cn=external,cn=auth

Ne pas oublier d'échapper le + qui fait la jonction entre le gidNumber et l'uidNumber. Le motif renvoyé contient donc tous les chiffres composant l'uidNumber (ceux du gidNumber ne sont pas conservés). Ce qui nous permettra donc de pouvoir mapper notre authentification Unix avec un utilisateur LDAP - si celui-ci existe en base. On ajoute la modification suivante à notre cn=config :

/usr/local/lib/ldap/user_maps.ldif
dn: cn=config
changetype: modify
add: olcAuthzRegexp
olcAuthzRegexp: gidNumber=[0-9]+\+uidNumber=**([0-9}+)**,cn=peercred,cn=external,cn=auth
  ldap:///ou=Users,dc=anarcha,dc=pink??one?(uidNumber=$1)

Et on vérifie avec ldapwhoami que tout va bien :

$ ldapwhoami
SASL/EXTERNAL authentication started
SASL username: gidNumber=1006+uidNumber=1007,cn=peercred,cn=external,cn=auth
SASL SSF: 0
dn:uid=okhin,ou=users,dc=anarcha,dc=pink

Et voilà, nous sommes correctement identifié par LDAP. Nous n'avons qu'à peine effleuré l'auth dans LDAP, mais pour nos besoins actuels, c'est très largement suffisant.

ateliers/serveurmail/ldap.1548335771.txt.gz · Dernière modification : 2019/01/24 14:16 de okhin