LDAPS : OpenLDAP et GnuTLS – Debian

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
# base  with 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

http://wiki.acacs.org/doku.php?id=installer_openldap_slapd_en_version_2.4_en_ssl_tls_sous_debian_squeeze

https://wiki.debian.org/LDAP/OpenLDAPSetup

http://www.inetdoc.net/pdf/sysadm-net.ldap.qa.pdf

One thought on “LDAPS : OpenLDAP et GnuTLS – Debian

  1. Ajout de quatre utilisateurs
    # ldapadd -cxWD cn=admin,dc=ldap,dc=local -f users.ldif
    where is the example of file « users.ldif » ?

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *