Version courte : à partir de sa version 3.6.0 incluse, la bibliothèque GnuTLS, l'une des implémentations de TLS (entre autres choses), ne prend plus en charge l'algorithme de signature SHA-1. Ainsi, les logiciels qui se reposent sur elle, comme les outils de manipulation LDAP (ldapsearch, ldapmodify, etc.) ne peuvent plus valider les certificats x509 signés avec SHA-1.
Version longue :
Nous avons un serveur LDAP OpenLDAP 2.4 configuré pour écouter en TLS (port dédié et STARTLS). Le certificat x509 utilisé par ce serveur est signé par notre autorité de certification interne/privée. Nous sommes en mesure d'effectuer des requêtes LDAP protégées par TLS (ldaps://). Une nouvelle informaticienne n'y parvient pas, elle obtient l'erreur « ldap_sasl_bind(SIMPLE): Can't contact LDAP server (-1) ». Elle utilise Ubuntu 18.10. Pourtant, cela fonctionne avec Ubuntu 18.04 et Debian Stretch.
J'active le mode debug (« -d 5 ») des outils de manipulation LDAP :
$ ldapsearch -d5 -x -LLL -H ldaps://monserveurldap.exemple:636 -b ou=people,dc=monorganisation,dc=fr
ldap_url_parse_ext(ldaps://monserveurldap.exemple:636)
ldap_create
ldap_url_parse_ext(ldaps://monserveurldap.exemple:636/??base)
ldap_sasl_bind
ldap_send_initial_request
ldap_new_connection 1 1 0
ldap_int_open_connection
ldap_connect_to_host: TCP monserveurldap.exemple:636
ldap_new_socket: 3
ldap_prepare_socket: 3
ldap_connect_to_host: Trying 192.0.2.1:636
ldap_pvt_connect: fd: 3 tm: -1 async: 0
attempting to connect:
connect success
TLS: peer cert untrusted or revoked (0x102)
TLS: can't connect: (unknown error code).
ldap_err2string
ldap_sasl_bind(SIMPLE): Can't contact LDAP server (-1)
La ligne importante est « TLS: peer cert untrusted or revoked (0x102) ». Notre autorité de certification privée/interne ne met pas en ouvre les mécanismes permettant à un logiciel de vérifier si un certificat est révoqué, donc la deuxième partie de ce message d'erreur est sans fondement. En revanche, la première partie indique que le logiciel ne parvient pas à valider le certificat x509 présenté par le serveur LDAP durant l'échange TLS. Cela peut être normal, puisqu'il s'agit d'une autorité de certification privée / interne qui ne fait donc pas partie des autorités fournies dans les magasins de certificats des systèmes d'exploitation (et des navigateurs web et autres logiciels).
Je vérifie le contenu du fichier /etc/ldap/ldap.conf
. Il y a bien la configuration requise pour utiliser une autorité de certification interne (et tout le reste est commenté), à savoir :
TLS_CACERT /chemin/vers/le/certificat/racine/de/notre/autorite.pem
TLS_REQCERT demand
Je vérifie l'existence du certificat racine indiqué : OK. Je vérifie ses droits d'accès : lecture pour tout le monde. Je vérifie les droits des dossiers parents : lecture + possibilité de traverser pour tout le monde.
Je vérifie la structure globale du certificat x509 avec openssl x509 -in /chemin/vers/le/certificat/racine/de/notre/autorite.pem -text -noout
: il s'agit bien de notre certificat racine (les attributs « Subject » et « Serial » sont OK). De plus, un sha256sum
de ce fichier certificat entre la machine défectueuse et une machine fonctionnelle nous retourne le même résultat, ce qui prouve que le fichier certificat est identique à celui d'une machine fonctionnelle.
Je vérifie la chaîne de certification avec openssl s_client -connect monserveurldap.exemple:636 -CAfile /chemin/vers/le/certificat/racine/de/notre/autorite.pem | grep 'Verification'
. J'obtiens « Verification: OK », ce qui confirme que toute la chaîne de certification est OK, ce qui renforce le doute sur les outils de manipulation LDAP.
Le certificat x509 est OK.
Je me dis que le fichier ldap.conf n'est pas lu / n'est pas pris en compte. Je remplace « TLS_REQCERT demand » par « TLS_RECERT none ». Cela a pour effet de désactiver la vérification du certificat x509 du serveur. Évidemment, cet état n'est pas souhaitable puisqu'il permet des attaques actives (MiTM) contre la confidentialité et l'intégrité mises en place par TLS… Je teste : ldapsearch fonctionne. Donc le fichier ldap.conf est lu et interprété.
Le fichier ldap.conf est OK.
Il y a donc un problème dans la manière dont les outils LDAP effectuent le dialogue TLS. En général, les logiciels n'implémentent pas TLS eux-mêmes, mais ils se reposent sur des bibliothèques de fonctions. Il existe plusieurs bibliothèques TLS (OpenSSL, GnuTLS, LibreSSL, PolarSSL, etc.). Sur laquelle se reposent les outils LDAP ?
$ whereis ldapsearch
ldapsearch: /usr/bin/ldapsearch /usr/share/man/man1/ldapsearch.1.gz
$ ldd /usr/bin/ldapsearch | grep -i tls
libgnutls.so.30 => /usr/lib/x86_64-linux-gnu/libgnutls.so.30 (0x00007fe2e1237000)
Il s'agit de GnuTLS. Quelle version de cette bibliothèque est empaquetée dans la version Stretch de Debian ?
$ apt-cache policy libgnutls30 | grep -i installé
Installé : 3.5.8-5+deb9u4
Et sur Ubuntu 18.04 ? 3.5.18. Et sur Ubuntu 18.10 ? 3.6.4. Hum… On change de version majeure.
Quelles différences y-a-t-il entre la version 3.5.18 et la version 3.6.4 ? Pour le savoir, il faut lire la doc' : zless /usr/share/doc/libgnutls30/NEWS.gz
. C'est copieux. Je soupçonne quelque chose en rapport avec x509 puis avec SHA-1 (dont la vulnérabilité est établie depuis mi-2017), donc je procède à une recherche par mot-clé avec zgrep
. Bingooooo :
* Version 3.6.0 (released 2017-08-21)
[…]
** libgnutls: SHA1 was marked as insecure for signing certificates. Verification
of certificates signed with SHA1 is now considered insecure and will
fail, unless flags intended to enable broken algorithms are set. Other uses
of SHA1 are still allowed. This can be reverted on compile time with the configure
flag --enable-sha1-support.
SHA-1, l'algorithme de signature utilisé par notre autorité de certification x509 n'est plus pris en charge à partir de la version 3.6.0 de GnuTLS, la bibliothèque sur laquelle se reposent les outils LDAP…
Néanmoins, comment être sûr que SHA-1 n'a pas été activé lors de la compilation dans Ubuntu / Debian ? Comment prendre connaissance des drapeaux positionnés lors de la compilation par les mainteneurs de notre système GNU/Linux ? La réponse est ici : il faut regarder les lignes « ./configure » ou « dh_auto_configure » (Debian-Helper configure ?) contenues dans le fichier « rules » du dossier « debian » du paquet contenant les sources du logiciel (pas celui contenant les binaires !).
Pour ce faire, il faut activer la récupération des sources par apt, c'est-à-dire les lignes qui commencent par « deb-src » dans /etc/apt/sources.list
. Ensuite : apt-get update
. Puis : apt-get source libgnutls30
. Enfin, nous pouvons ouvrir l'archive « gnutls28_3.5.5-2+deb9u1.debian.tar.xz » et constater par nous-même l'absence du drapeau « --enable-sha1-support ».
Quelle conclusion ? Que doit faire notre informaticienne ?
Changer de système d'exploitation ? :P
Nous motiver à changer l'algorithme de notre autorité de certification ? Nous avons encore des logiciels qui ne prennent pas en charge SHA256, donc la transition va être longue. Sans compter qu'il faut re-signer tous les certificats émis (et, si l'on a perdu les requêtes de certification, il faut les générer à nouveau)…
Ne pas utiliser TLS pour interroger notre LDAP ? Les données personnelles qui circulent en clair, ce n'est jamais sympa.
Utiliser TLS en désactivant la vérification du certificat ? C'est pas top, mais elle travaille sur le même réseau que le serveur LDAP, donc le risque d'une attaque active est très faible (et si elle a lieu, peut-être que nous devrions focaliser notre attention sur ce fauteur de trouble), et, au moins, les données circulent de manière chiffrée, c'est un début et cela protège des attaques passives.