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).
merci pour cet article
merci pour cet article