Mise en place OpenSSL sur OpenLDAP

La mise en place de SSL pour OpenLDAP permet de sécuriser les échanges, que ce soit en utilisant LDAPS ou START/TLS (dans ce dernier cas, la connexion démarre sur le port LDAP et passe ensuite en mode sécurisé).

En préalable, on aura généré une clé privée, récupéré un certificat, ainsi que celui de l'autorité de certification. (voir un article précédent sur le mémento OpenSSL ).

Les étapes pour la sécurisation sont :

  • Création d'un répertoire pour stocker les certificats / clés (optionnel)
  • Copie des certificats / clés
  • Paramétrage OpenLDAP pour activer l'écoute sur le port sécurisé LDAPS '636 par défaut)
  • Modification de la configuration pour déclarer les certificats utilisés

Création du répertoire de stockage des certificats

Cette opération est optionnelle. On peut aussi utiliser le répertoire /etc/openldap/cacerts (sous RedHat / CentOS) ou tout autre répertoire tel que /etc/ssl/certs (pour les certificats) ou /etc/ssl/private (pour les clés privées). Création du répertoire dans lequel seront stockés les certificats et clés, et copie des fichiers dans ce répertoire :

mkdir /product/openldap/certs

Copie des certificats / clés

Les certificats et clés doivent ensuite être copiés dans le répertoire. On doit normalement disposer de 3 fichiers :

  • La clé privée
  • Le certificat de l'annuaire
  • Le certificat de l'autorité de certification

On copie les trois fichiers dans le répertoire précédemment créé, et on met les droits restrictifs pour le ldap :

cp ldap_cert.pem /product/openldap/certs
cp ldap_key.pem /product/openldap/certs
cp ca-ldap-cert.pem /product/openldap/certs
cd /product/openldap/certs
chown ldap ldap*
chmod 400 ldap*

Attention : le fichier contenant la clé ne doit pas être protégé par mot de passe. Si c'est le cas, on peut utiliser la commande openssl suivante :

openssl rsa -in macleprive.key -out maclesanspass.key

Configuration du process SLAPD

Pour que le daemon slapd puisse écouter et servir ses requêtes sur le port ldaps (636), il faut activer l'option LDAPS dans la configuration de l'annuaire OpenLDAP.
Le paramétrage est différent selon le type de distribution (Redhat / Debian).

Pour une distribution type Red Hat, CentOS, il faut modifier le fichier /etc/sysconfig/ldap, et changer la valeur pour la variable SLAPD_LDAPS :

# Run slapd with -h "... ldaps:/// ..."
#   yes/no, default: no
SLAPD_LDAPS=yes

Pour une distribution type Debian, Ubuntu, la modification est à faire dans le fichier /etc/default/slapd. Il faut modifier la ligne correspondant à la variable SLAPD_SERVICES. Changer par exemple :

SLAPD_SERVICES="ldap:/// ldapi:///"

en

SLAPD_SERVICES="ldap:/// ldaps:/// ldapi:///"

 

On peut alors démarrer le daemon et vérifier qu'il écoute sur le port ldaps :

# service slapd start
Démarrage de slapd :                                       [  OK  ]
# ps -ef | grep slap
ldap      1632     1  4 11:18 ?        00:00:00 /usr/sbin/slapd -h  ldap:/// ldaps:/// ldapi:/// -u ldap

Configuration LDAP cn=config

La prochaine étape consiste à modifier le paramétrage de l'annuaire, pour qu'il active le mode TLS.
Ceci peut s'effectuer par un fichier LDIF (recommandé), ou en modifiant le fichier /etc/openldap/slapd.d/cn=config.ldif manuellement. Dans l'option 1, on crée un fichier LDIF qui contient les lignes :

cat > tls-config.ldif << EOF
dn: cn=config
add: olcTLSCACertificateFile
olcTLSCACertificateFile: /product/openldap/certs/ca-ldap-cert.pem

dn: cn=config
add: olcTLSCertificateFile
olcTLSCertificateFile: /product/openldap/certs/ldap_cert.pem

dn: cn=config
add: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /product/openldap/certs/ldap_key.pem

dn: cn=config
add: olcTLSVerifyClient
olcTLSVerifyClient: never
EOF

Puis on modifie la configuration via un ldapmodify:

ldapmodify -QY EXTERNAL -H ldapi:/// -f tls-config.ldif

Pour l'option 2 (modification du fichier), il faut s'assurer que le service slapd soit arrêté.

service slapd stop
echo "olcTLSCACertificateFile: /product/openldap/certs/ca-ldap-cert.pem" >> /etc/openldap/slapd.d/cn=config.ldif
echo "olcTLSCertificateFile: /product/openldap/certs/ldap_cert.pem" >> /etc/openldap/slapd.d/cn=config.ldif
echo "olcTLSCertificateKeyFile: /product/openldap/certs/ldap_key.pem" >> /etc/openldap/slapd.d/cn=config.ldif
service slapd start

Attention : sous Debian, il semble que slapd utilise un mécanisme de checksum CRC32 pour valider que les fichiers LDIF de configuration n'ont pas été modifiés manuellement ! On peut alors avoir dans les logs de l'annuaire une ligne telle que

ldif_read_file: checksum error on "/etc/ldap/slapd.d/cn=config/olcDatabase={0}config.ldif"

Ceci n'empêche pas l'annuaire de démarrer, mais signifie qu'une modification manuelle a été effectuée, plutôt que l'utilisation de ldapmodify

Tests

On peut alors tester avec la commande :

ldapsearch -x -H ldap://192.168.56.121  -b "dc=example,dc=corp" "objectclass=organizationalunit" -Z -D "cn=manager,dc=example,dc=corp" -w Secr@t -s one

L'option -Z permet de passer en mode TLS. Dans ce cas, on utilise le port 389 entre le client et le serveur LDAP, ce que l'on peut vérifier dans les logs de l'annuaire OpenLDAP (slapd.log):

Dec 18 11:51:13 ldapagd1 slapd[1806]: conn=1020 fd=21 ACCEPT from IP=192.168.56.1:48181 (IP=0.0.0.0:389)
Dec 18 11:51:13 ldapagd1 slapd[1806]: conn=1020 op=0 EXT oid=1.3.6.1.4.1.1466.20037
Dec 18 11:51:13 ldapagd1 slapd[1806]: conn=1020 op=0 STARTTLS
Dec 18 11:51:13 ldapagd1 slapd[1806]: conn=1020 op=0 RESULT oid= err=0 text=
Dec 18 11:51:13 ldapagd1 slapd[1806]: conn=1020 fd=21 TLS established tls_ssf=256 ssf=256
Dec 18 11:51:13 ldapagd1 slapd[1806]: conn=1020 op=1 BIND dn="cn=manager,dc=example,dc=corp" method=128
Dec 18 11:51:13 ldapagd1 slapd[1806]: conn=1020 op=1 BIND dn="cn=manager,dc=example,dc=corp" mech=SIMPLE ssf=0
Dec 18 11:51:13 ldapagd1 slapd[1806]: connection_input: conn=1020 deferring operation: binding
Dec 18 11:51:13 ldapagd1 slapd[1806]: conn=1020 op=1 RESULT tag=97 err=0 text=
Dec 18 11:51:13 ldapagd1 slapd[1806]: conn=1020 op=2 SRCH base="dc=example,dc=corp" scope=1 deref=0 filter="(objectClass=organizationalUnit)"
Dec 18 11:51:13 ldapagd1 slapd[1806]: conn=1020 op=3 UNBIND
Dec 18 11:51:13 ldapagd1 slapd[1806]: conn=1020 op=2 SEARCH RESULT tag=101 err=0 nentries=6 text=
Dec 18 11:51:13 ldapagd1 slapd[1806]: conn=1020 fd=21 closed

On peut combiner le TLS + SSL, en précisant le port et le protocolel ldaps, via la commande :

ldapsearch -x -H ldaps://192.168.56.121:636  -b "dc=example,dc=corp" "objectclass=organizationalunit" -Z -D "cn=manager,dc=example,dc=corp" -w Secr@t -s one

Dans les logs, on constate alors que le port est bien le 636 :

Dec 18 11:53:19 ldapagd1 slapd[1806]: conn=1022 fd=21 ACCEPT from IP=192.168.56.1:54692 (IP=0.0.0.0:636)
Dec 18 11:53:19 ldapagd1 slapd[1806]: conn=1022 fd=21 TLS established tls_ssf=256 ssf=256
Dec 18 11:53:19 ldapagd1 slapd[1806]: conn=1022 op=0 EXT oid=1.3.6.1.4.1.1466.20037
Dec 18 11:53:19 ldapagd1 slapd[1806]: conn=1022 op=0 STARTTLS
Dec 18 11:53:19 ldapagd1 slapd[1806]: conn=1022 op=0 RESULT oid= err=1 text=TLS already started
Dec 18 11:53:19 ldapagd1 slapd[1806]: conn=1022 op=1 BIND dn="cn=manager,dc=example,dc=corp" method=128
Dec 18 11:53:19 ldapagd1 slapd[1806]: conn=1022 op=1 BIND dn="cn=manager,dc=example,dc=corp" mech=SIMPLE ssf=0
Dec 18 11:53:19 ldapagd1 slapd[1806]: conn=1022 op=1 RESULT tag=97 err=0 text=
Dec 18 11:53:19 ldapagd1 slapd[1806]: conn=1022 op=2 SRCH base="dc=example,dc=corp" scope=1 deref=0 filter="(objectClass=organizationalUnit)"
Dec 18 11:53:19 ldapagd1 slapd[1806]: conn=1022 op=2 SEARCH RESULT tag=101 err=0 nentries=6 text=
Dec 18 11:53:19 ldapagd1 slapd[1806]: conn=1022 op=3 UNBIND
Dec 18 11:53:19 ldapagd1 slapd[1806]: conn=1022 fd=21 closed

Troubleshooting et Debug

Vérification du certificat

Certains clients LDAP veulent valider l'authenticité du certificat, ce qui peut poser problème lorsqu'on utilise un certificat auto-signé.

On peut se prémunir de ce type de problème en modifiant le fichier /etc/ldap/ldap.conf, et en ajoutant la variable TLS_REQCERT , et en déclarant le répertoire dans lequel on peut trouver les certificats des autorités de certification :

TLS_REQCERT allow
TLS_CACERTDIR /product/openldap/certs

Cette variable peut avoir plusieurs valeurs :

  • never : pas de vérification du certificat
  • allow : vérification effectuée, mais pas de blocage si le certificat n'est pas authentifié
  • demand : le certificat doit être connu

Dans le cas où le certificat doit être authentifié, il faut l'ajouter à la liste des certificats connus.

Tester l'échange de certificats

Afin d'éviter le côté "boîte noire" des commandes LDAP, on peut déjà tester l'échange des certificats via une commande ssl :

openssl s_client -connect 192.168.56.121:636
CONNECTED(00000003)
depth=0 C = XX, ST = FR, L = France, O = Hebinweb, OU = ldap, CN = ldap.hebinweb.com, emailAddress = admin@hebinweb.com
verify error:num=18:self signed certificate
verify return:1
depth=0 C = XX, ST = FR, L = France, O = Hebinweb, OU = ldap, CN = ldap.hebinweb.com, emailAddress = admin@hebinweb.com
verify return:1
---
Certificate chain
 0 s:/C=XX/ST=FR/L=France/O=Hebinweb/OU=ldap/CN=ldap.hebinweb.com/emailAddress=admin@hebinweb.com
   i:/C=XX/ST=FR/L=France/O=Hebinweb/OU=ldap/CN=ldap.hebinweb.com/emailAddress=admin@hebinweb.com
---
Server certificate
-----BEGIN CERTIFICATE-----
MIID7TCCAtWgAwIBAgIJAPsjys7PHwWQMA0GCSqGSIb3DQEBBQUAMIGMMQswCQYD
VQQGEwJYWDELMAkGA1UECAwCRlIxDzANBgNVBAcMBkZyYW5jZTERMA8GA1UECgwI
SGViaW53ZWIxDTALBgNVBAsMBGxkYXAxGjAYBgNVBAMMEWxkYXAuaGViaW53ZWIu
Y29tMSEwHwYJKoZIhvcNAQkBFhJhZG1pbkBoZWJpbndlYi5jb20wHhcNMTMxMjE4
MTAwNzQ4WhcNMTUxMjE4MTAwNzQ4WjCBjDELMAkGA1UEBhMCWFgxCzAJBgNVBAgM

...

Le client SSL récupère bien le certificat, qu'il identifie comme étant auto-signé (self signed certificate).

Catégorie