LDAPS : OpenLDAP et GnuTLS – Debian Wheezy
Introduction : LDAPS : OpenLDAP et GnuTLS – Debian Wheezy
Cet article traite l’installation, la configuration et la sécurisation de LDAP (Lightweight Directory Access Protocol) avec OpenLDAP et GnuTLS sous Debian Wheezy.
Depuis la version 2.4 de OpenLDAP la gestion de la configuration se fait par défaut via la On-Line Configuration (cn=config). OLC remplace la gestion de la configuration via le fichier slapd.conf. Elle permet une gestion dynamique de la configuration sans redémarrage systématique du service LDAP.
Debian Wheezy installe la version slapd 2.4.31-1
Le nom du serveur ici est srv.ldap.local. La base est dc=ldap,dc=local
INSTALLATION de OpenLDAP sous Debian Wheezy
# aptitude install slapd ldap-utils
Vérification
# ps aux | grep l[d]ap openldap 3094 0.0 0.3 25408 3980 ? Ssl 15:45 0:00 /usr/sbin/slapd -h ldap:/// ldapi:/// -g openldap -u openldap -F /etc/ldap/slapd.d
CONFIGURATION
Par défaut une base nodomain est créé
# ldapsearch -LLL -Y EXTERNAL -H ldapi:/// -b "cn=config" olcSuffix | grep ^olcSuffix SASL/EXTERNAL authentication started SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth SASL SSF: 0 olcSuffix: dc=nodomain
Vérification des schémas installés par défaut :
ldapsearch -LLL -Y EXTERNAL -H ldapi:/// -b "cn=config" olcSchemaConfig | grep ^cn SASL/EXTERNAL authentication started SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth SASL SSF: 0 cn: config cn: module{0} cn: schema cn: {0}core cn: {1}cosine cn: {2}nis cn: {3}inetorgperson
Reconfiguration de l’annuaire : création d’une seule base ldap.local
# dpkg-reconfigure -plow slapd
Voulez vous omettre la configuration d'OpenLDAP → Non Nom de domaine : ldap.local Nom d'entité (« organization ») : ldap.local Mot de passe de l'administrateur : motdepasse Module de base de données à utiliser : HDB Faut-il supprimer la base de données à la purge du paquet ? Oui Faut-il déplacer l'ancienne base de données ? Oui Faut-il autoriser le protocole LDAPv2 ? Non
Vérification après reconfiguration
# ldapsearch -LLL -Y EXTERNAL -H ldapi:/// -b "cn=config" olcSuffix | grep ^olcSuffix SASL/EXTERNAL authentication started SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth SASL SSF: 0 olcSuffix: dc=ldap,dc=local
La base dc=ldap,dc=local a bien été créée
PEUPLEMENT DE L’ANNUAIRE
Attention, Le mode « list » de vim ( :set list ) est privilège pour l’édition des fichiers LDIF afin d’être stricte sur la syntaxe (ne pas laisser d’espace en trop, LDIF est sensible à ça).
Ajout d’une OU people (Organizational Unit) et d’un groupe groups
Création du fichier LDIF
# cat ou.ldif dn: ou=people,dc=ldap,dc=local objectClass: organizationalUnit ou: people dn: ou=groups,dc=ldap,dc=local objectClass: organizationalUnit ou: groups
Injection du fichier ou.ldif dans la configuration
# ldapadd -cxWD cn=admin,dc=ldap,dc=local -f ou.ldif Enter LDAP Password: adding new entry "ou=people,dc=ldap,dc=local" adding new entry "ou=groups,dc=ldap,dc=local"
Vérification
# ldapsearch -LLL -x -H ldap:/// -b "dc=ldap,dc=local" -D cn=admin,dc=ldap,dc=local -W Enter LDAP Password: dn: dc=ldap,dc=local objectClass: top objectClass: dcObject objectClass: organization o: ldap.local dc: ldap dn: cn=admin,dc=ldap,dc=local objectClass: simpleSecurityObject objectClass: organizationalRole cn: admin description: LDAP administrator userPassword:: e1NTSEF9SlZRNEdkbURJNGRDNUhSUHR1a3VXbGUzQkZTYkxmdjI= dn: ou=people,dc=ldap,dc=local objectClass: organizationalUnit ou: people dn: ou=groups,dc=ldap,dc=local objectClass: organizationalUnit ou: groups
Ajout de quatre utilisateurs
# ldapadd -cxWD cn=admin,dc=ldap,dc=local -f users.ldif Enter LDAP Password: adding new entry "uid=padme,ou=people,dc=ldap,dc=local" adding new entry "uid=anakin,ou=people,dc=ldap,dc=local" adding new entry "uid=leia,ou=people,dc=ldap,dc=local" adding new entry "uid=luke,ou=people,dc=ldap,dc=local"
Vérification
slapcat dn: dc=ldap,dc=local objectClass: top objectClass: dcObject objectClass: organization o: ldap.local dc: ldap structuralObjectClass: organization entryUUID: aac46d3a-f303-1033-8e5d-45d6f2932b4e creatorsName: cn=admin,dc=ldap,dc=local createTimestamp: 20141028153436Z entryCSN: 20141028153436.269442Z#000000#000#000000 modifiersName: cn=admin,dc=ldap,dc=local modifyTimestamp: 20141028153436Z dn: cn=admin,dc=ldap,dc=local objectClass: simpleSecurityObject objectClass: organizationalRole cn: admin description: LDAP administrator userPassword:: e1NTSEF9SlZRNEdkbURJNGRDNUhSUHR1a3VXbGUzQkZTYkxmdjI= structuralObjectClass: organizationalRole entryUUID: aacb4f1a-f303-1033-8e5e-45d6f2932b4e creatorsName: cn=admin,dc=ldap,dc=local createTimestamp: 20141028153436Z entryCSN: 20141028153436.314557Z#000000#000#000000 modifiersName: cn=admin,dc=ldap,dc=local modifyTimestamp: 20141028153436Z dn: ou=people,dc=ldap,dc=local objectClass: organizationalUnit ou: people structuralObjectClass: organizationalUnit entryUUID: bc0417de-f304-1033-8b72-8b44c99db207 creatorsName: cn=admin,dc=ldap,dc=local createTimestamp: 20141028154214Z entryCSN: 20141028154214.704697Z#000000#000#000000 modifiersName: cn=admin,dc=ldap,dc=local modifyTimestamp: 20141028154214Z dn: ou=groups,dc=ldap,dc=local objectClass: organizationalUnit ou: groups structuralObjectClass: organizationalUnit entryUUID: bc051512-f304-1033-8b73-8b44c99db207 creatorsName: cn=admin,dc=ldap,dc=local createTimestamp: 20141028154214Z entryCSN: 20141028154214.711179Z#000000#000#000000 modifiersName: cn=admin,dc=ldap,dc=local modifyTimestamp: 20141028154214Z dn: uid=padme,ou=people,dc=ldap,dc=local objectClass: person objectClass: shadowAccount objectClass: inetOrgPerson cn: Padme sn:: UGFkbcOpIEFtaWRhbGEgU2t5d2Fsa2Vy uid: padme userPassword:: e1NTSEF9azdrVlBCNi9MYkM4eDM2UHl5WFQxUFV4c0M2Y2dnR3M= mail: padme@ldap.local structuralObjectClass: inetOrgPerson entryUUID: 0d250ba0-f6ed-1033-98bd-db7881564dff creatorsName: cn=admin,dc=ldap,dc=local createTimestamp: 20141102150247Z entryCSN: 20141102150247.545692Z#000000#000#000000 modifiersName: cn=admin,dc=ldap,dc=local modifyTimestamp: 20141102150247Z dn: uid=anakin,ou=people,dc=ldap,dc=local objectClass: person objectClass: shadowAccount objectClass: inetOrgPerson cn: Anakin sn: Anakin Skywalker uid: anakin userPassword:: e1NTSEF9azdrVlBCNi9MYkM4eDM2UHl5WFQxUFV4c0M2Y2dnR3M= mail: anakin@ldap.local structuralObjectClass: inetOrgPerson entryUUID: 0d26fb22-f6ed-1033-98be-db7881564dff creatorsName: cn=admin,dc=ldap,dc=local createTimestamp: 20141102150247Z entryCSN: 20141102150247.558381Z#000000#000#000000 modifiersName: cn=admin,dc=ldap,dc=local modifyTimestamp: 20141102150247Z dn: uid=leia,ou=people,dc=ldap,dc=local objectClass: person objectClass: shadowAccount objectClass: inetOrgPerson cn: Leia sn: Leia Organa uid: leia userPassword:: e1NTSEF9azdrVlBCNi9MYkM4eDM2UHl5WFQxUFV4c0M2Y2dnR3M= mail: leia@ldap.local structuralObjectClass: inetOrgPerson entryUUID: 0d2acfcc-f6ed-1033-98bf-db7881564dff creatorsName: cn=admin,dc=ldap,dc=local createTimestamp: 20141102150247Z entryCSN: 20141102150247.583494Z#000000#000#000000 modifiersName: cn=admin,dc=ldap,dc=local modifyTimestamp: 20141102150247Z dn: uid=luke,ou=people,dc=ldap,dc=local objectClass: person objectClass: shadowAccount objectClass: inetOrgPerson cn: Luke sn: Luke Skywalker uid: luke userPassword:: e1NTSEF9azdrVlBCNi9MYkM4eDM2UHl5WFQxUFV4c0M2Y2dnR3M= mail: luke@ldap.local structuralObjectClass: inetOrgPerson entryUUID: 0d2b542e-f6ed-1033-98c0-db7881564dff creatorsName: cn=admin,dc=ldap,dc=local createTimestamp: 20141102150247Z entryCSN: 20141102150247.586883Z#000000#000#000000 modifiersName: cn=admin,dc=ldap,dc=local modifyTimestamp: 20141102150247Z
Des vérifications supplémentaires peuvent être faite à distance :
# ldapsearch -x -H ldap://srv.ldap.local -b dc=ldap,dc=local -D "uid=luke,ou=people,dc=ldap,dc=local" -W Enter LDAP Password: # extended LDIF # # LDAPv3 # basewith scope subtree # filter: (objectclass=*) # requesting: ALL # # ldap.local dn: dc=ldap,dc=local objectClass: top objectClass: dcObject objectClass: organization o: ldap.local dc: ldap # admin, ldap.local dn: cn=admin,dc=ldap,dc=local objectClass: simpleSecurityObject objectClass: organizationalRole cn: admin description: LDAP administrator # people, ldap.local dn: ou=people,dc=ldap,dc=local objectClass: organizationalUnit ou: people # groups, ldap.local dn: ou=groups,dc=ldap,dc=local objectClass: organizationalUnit ou: groups # padme, people, ldap.local dn: uid=padme,ou=people,dc=ldap,dc=local objectClass: person objectClass: shadowAccount objectClass: inetOrgPerson cn: Padme sn:: UGFkbcOpIEFtaWRhbGEgU2t5d2Fsa2Vy uid: padme mail: padme@ldap.local # anakin, people, ldap.local dn: uid=anakin,ou=people,dc=ldap,dc=local objectClass: person objectClass: shadowAccount objectClass: inetOrgPerson cn: Anakin sn: Anakin Skywalker uid: anakin mail: anakin@ldap.local # leia, people, ldap.local dn: uid=leia,ou=people,dc=ldap,dc=local objectClass: person objectClass: shadowAccount objectClass: inetOrgPerson cn: Leia sn: Leia Organa uid: leia mail: leia@ldap.local # luke, people, ldap.local dn: uid=luke,ou=people,dc=ldap,dc=local objectClass: person objectClass: shadowAccount objectClass: inetOrgPerson cn: Luke sn: Luke Skywalker uid: luke userPassword:: e1NTSEF9azdrVlBCNi9MYkM4eDM2UHl5WFQxUFV4c0M2Y2dnR3M= mail: luke@ldap.local # search result search: 2 result: 0 Success # numResponses: 9 # numEntries: 8
Sécurisation de LDAP avec GnuTLS
OpenLDAP est compilé avec GnuTLS (et pas OpenSSL).
Vérification pour s’en convaincre :
# apt-rdepends slapd | grep tls Reading package lists... Done Building dependency tree Reading state information... Done Depends: libgnutls26 (>= 2.12.17-0) libgnutls26 Depends: libgnutls26 (>= 2.12.17-0)
Installation de GnuTLS
# apt-get install gnutls-bin
Les certificats seront placés dans un répertoire spécifique volontairement. Et le certificat serveur sera auto-signé par soucis de simplicité (c’est mal).
# mkdir /etc/ldap/ssl && chown openldap: /etc/ldap/ssl && cd /etc/ldap/ssl
Génération des certificats
# certtool --generate-privkey --outfile ca-key.pem
# certtool --generate-self-signed --load-privkey ca-key.pem --outfile ca-cert.pem
Generating a self signed certificate... Please enter the details of the certificate's distinguished name. Just press enter to ignore a field. Country name (2 chars): FR Organization name: ldap Organizational unit name: ldap Locality name: Paris State or province name: Paris Common name: srv.ldap.local UID: This field should not be used in new certificates. E-mail: mail@ldap.local Enter the certificate's serial number in decimal (default: 1414942800): Activation/Expiration time. The certificate will expire in (days): 1000 Extensions. Does the certificate belong to an authority? (y/N): Is this a TLS web client certificate? (y/N): Will the certificate be used for IPsec IKE operations? (y/N): Is this also a TLS web server certificate? (y/N): Y Enter a dnsName of the subject of the certificate: srv.ldap.local Enter a dnsName of the subject of the certificate: Enter the IP address of the subject of the certificate: Will the certificate be used for signing (DHE and RSA-EXPORT ciphersuites)? (y/N): Will the certificate be used for encryption (RSA ciphersuites)? (y/N): Y Enter the URI of the CRL distribution point: X.509 Certificate Information: Version: 3 Serial Number (hex): 54565050 Validity: Not Before: Sun Nov 02 15:40:20 UTC 2014 Not After: Sat Jul 29 15:40:24 UTC 2017 Subject: C=FR,O=ldap,OU=ldap,L=Paris,ST=Paris,CN=srv.ldap.local,EMAIL=mail@ldap.local Subject Public Key Algorithm: RSA Certificate Security Level: Normal Modulus (bits 2432): 00:bd:8b:1b:e5:66:82:21:da:42:d1:ec:4c:34:06:78 00:9e:bc:b4:70:57:d2:35:77:55:d5:63:f0:2a:93:d0 f8:52:f7:d3:b3:32:ce:d2:2d:dc:c5:4c:f4:a4:2d:5f 35:68:4b:2a:af:a1:c3:4d:f7:51:50:86:68:c2:bc:47 d1:42:4a:eb:e8:c4:7b:c5:c4:31:ad:e3:3f:15:f4:49 9d:78:f5:54:2f:1e:36:47:2b:87:4a:17:5a:87:91:2b ca:fa:d0:8a:5b:a4:ad:bd:03:62:18:9a:cb:6a:2c:e1 b5:e8:c9:dd:77:3c:ea:30:9c:fa:01:0d:92:fa:4b:49 06:39:1a:7f:00:39:ca:e6:bf:01:ae:85:e3:d1:0a:69 a7:6b:9d:2a:2c:9a:40:f2:a1:cd:07:1f:7a:61:4f:85 f7:5e:1b:94:ed:56:fc:a9:39:f0:85:c7:32:38:6d:29 0a:77:3f:f9:0e:4f:cb:5e:79:50:c6:12:3b:d4:48:6d 45:f7:2b:b6:2b:29:5e:39:02:b0:07:3d:2e:d0:4d:c1 57:39:60:0c:3e:c6:60:79:0d:ef:91:af:4e:c3:17:04 3b:69:c8:9c:44:44:7e:c3:7f:ce:4b:2b:a5:cf:76:f0 93:f7:5e:e1:ef:cc:e6:3b:4b:ce:f5:6b:fc:60:1e:fd 5b:e2:41:40:a9:ec:1a:19:2c:0e:cb:aa:a9:2b:cf:48 c0:71:83:c5:c1:0c:9f:bf:7b:42:7d:9e:8c:df:cc:99 86:5f:ec:07:25:35:93:73:c1:8e:de:d7:1a:f1:82:0a 91 Exponent (bits 24): 01:00:01 Extensions: Basic Constraints (critical): Certificate Authority (CA): FALSE Subject Alternative Name (not critical): DNSname: srv.ldap.local Key Purpose (not critical): TLS WWW Server. Key Usage (critical): Key encipherment. Subject Key Identifier (not critical): 4651006619055a0a69e37ddc8ffc41f47586c3ed Other Information: Public Key Id: 4651006619055a0a69e37ddc8ffc41f47586c3ed Is the above information ok? (y/N): Y
Modification des droits sur le répertoire qui contient les certificats
# chown openldap: /etc/ldap/ssl/* ls -lat /etc/ldap/ssl/* -rw-r--r-- 1 openldap openldap 1566 nov. 2 16:41 /etc/ldap/ssl/ca-cert.pem -rw------- 1 openldap openldap 1968 nov. 2 16:38 /etc/ldap/ssl/ca-key.pem
Le hostname du serveur doit est égal au CN
# hostname -f srv.ldap.local
Ajout des configuration dans le cn=config
# cat tls.ldif dn: cn=config add: olcTLSCertificateKeyFile olcTLSCertificateKeyFile: /etc/ldap/ssl/ca-key.pem - add: olcTLSCertificateFile olcTLSCertificateFile: /etc/ldap/ssl/ca-cert.pem
# ldapmodify -Y EXTERNAL -H ldapi:/// -f tls.ldif SASL/EXTERNAL authentication started SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth SASL SSF: 0 modifying entry "cn=config"
Il faut ajouter ldaps:/// dans le /etc/default/slapd
#/etc/default/slapd SLAPD_SERVICES="ldap:/// ldaps:/// ldapi:///"
La configuration globale peut être vérifiée comme suit
# ldapsearch -LLL -Y EXTERNAL -H ldapi:/// -b cn=config
ou directement
# less /etc/ldap/slapd.d/cn=config.ldif
Redémarrage du service slapd
# /etc/init.d/slapd restart [ ok ] Stopping OpenLDAP: slapd. [ ok ] Starting OpenLDAP: slapd.
Vérification
# ps axu | grep slapd openldap 2472 0.0 0.3 25520 3984 ? Ssl 17:03 0:00 /usr/sbin/slapd -h ldap:/// ldapi:/// ldaps:/// -g openldap -u openldap -F /etc/ldap/slapd.d # netstat -tunlp | grep slapd tcp 0 0 0.0.0.0:636 0.0.0.0:* LISTEN 2472/slapd tcp 0 0 0.0.0.0:389 0.0.0.0:* LISTEN 2472/slapd tcp6 0 0 :::636 :::* LISTEN 2472/slapd tcp6 0 0 :::389 :::* LISTEN 2472/slapd
Tests Local et distant
Ajustement à faire pour tenir compte du certificat auto signé
# cat /etc/ldap/ldap.conf URI ldap:/// ldaps:/// TLS_REQCERT hard TLS_CACERT /etc/ldap/ssl/ca-cert.pem
# ldapsearch -h srv.ldap.local -ZZ -D "cn=admin,dc=ldap,dc=local" -W -b 'dc=ldap,dc=local' '(objectclass=*)'
# ldapsearch -x -H ldaps://srv.ldap.local -b dc=ldap,dc=local -D "uid=luke,ou=people,dc=ldap,dc=local" -W
Des tests peuvent être réalisés avec le carnet d’adresse LDAP de Thunderbird (ajouter une exception de sécurité, gestion des certificats, ajoutez : srv.ldap.local:636)
Ajustement pour rendre LDAPS obligatoire et LDAP seulement en localhost
SLAPD_SERVICES="ldap://127.0.0.1:389/ ldapi:/// ldaps:///"
# /etc/init.d/slapd restart[ ok ] Stopping OpenLDAP: slapd. [ ok ] Starting OpenLDAP: slapd.
# ps axu | grep slapd openldap 2568 0.0 0.3 25520 3988 ? Ssl 17:43 0:00 /usr/sbin/slapd -h ldap://127.0.0.1:389/ ldapi:/// ldaps:/// -g openldap -u openldap -F /etc/ldap/slapd.d
# netstat -tunlp | grep slapd tcp 0 0 0.0.0.0:636 0.0.0.0:* LISTEN 2568/slapd tcp 0 0 127.0.0.1:389 0.0.0.0:* LISTEN 2568/slapd tcp6 0 0 :::636 :::* LISTEN 2568/slapd
ACL
Afin d’ajuster les accès à l’annuaire, il est nécessaire de modifier les ACLs par défaut.
# ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -W -b cn=config '(olcDatabase={1}hdb)' olcAccess Enter LDAP Password: dn: olcDatabase={1}hdb,cn=config olcAccess: {0}to attrs=userPassword,shadowLastChange by self write by anonymou s auth by dn="cn=admin,dc=ldap,dc=local" write by * none olcAccess: {1}to dn.base="" by * read olcAccess: {2}to * by self write by dn="cn=admin,dc=ldap,dc=local" write by * read
Par défaut tout le monde peut lister les entrées de l’annuaire. Nous allons limiter la lecture aux utilisateurs authentifiés
# cat acl.ldif dn: olcDatabase={1}hdb,cn=config changetype: modify add: olcAccess olcAccess: {1}to * by dn="cn=admin,dc=ldap,dc=local" write by self write by users read
# ldapmodify -Y EXTERNAL -H ldapi:/// -f acl.ldif SASL/EXTERNAL authentication started SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth SASL SSF: 0 modifying entry "olcDatabase={1}hdb,cn=config"
Pas besoin de redémarrer le service LDAP. Les modifications sont prises en compte dynamiquement
# ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -W -b cn=config '(olcDatabase={1}hdb)' olcAccess Enter LDAP Password: dn: olcDatabase={1}hdb,cn=config olcAccess: {0}to attrs=userPassword,shadowLastChange by self write by anonymou s auth by dn="cn=admin,dc=ldap,dc=local" write by * none olcAccess: {1}to * by dn="cn=admin,dc=ldap,dc=local" write by self write by us ers read
CONCLUSION
Cet article (un peu long) a traité principalement de l’installation, de la configuration et de la sécurisation de OpenLDAP.
Dans un prochain article, il sera question de traiter la sécurisation de l’authentification (SASL), de l’optimisation par la mise en place des index, et de la réplication.
Références
http://fr.wikipedia.org/wiki/Lightweight_Directory_Access_Protocol
http://www.openldap.org/doc/admin24/index.html
https://wiki.debian.org/LDAP/OpenLDAPSetup
http://www.inetdoc.net/pdf/sysadm-net.ldap.qa.pdf
Cet article LDAPS : OpenLDAP et GnuTLS – Debian Wheezy est apparu en premier sur PointRoot.org.