Grand-père Castor raconte : bind LDAP en clair, corrigé
- Accueil
- Identités, accès & habilitations
- Grand-père Castor raconte : bind LDAP en clair, corrigé
Grand-père Castor raconte : bind LDAP en clair, corrigé
Section intitulée « Grand-père Castor raconte : bind LDAP en clair, corrigé »Grand-père Castor se souvient d’une époque où LDAPv2 transportait les identifiants en clair par défaut : le bind simple non chiffré et l’anonymous bind restaient acceptés sur la plupart des annuaires. Cette dette, la plus ancienne du protocole, a été colmatée par StartTLS, LDAPS et SASL/GSSAPI, et LDAPv2 a été rangé au rayon « historique » par le RFC 3494 en 2003. Elle explique encore des comportements de produits récents qui n’ont jamais coupé le repli en clair.
Un annuaire d’entreprise ressemble à un registre qui indique qui travaille où, avec quel rôle et quels moyens de contact. Laisser ce registre ouvert ou dicter un mot de passe à voix haute accélère le travail des personnes légitimes, et fournit dans la foulée l’organigramme et la liste des adresses à qui traîne dans le couloir.
Voir la section « Explication de la marmotte » en fin de page pour la version détaillée.
LDAPv2, bind simple et dette de protocole
Section intitulée « LDAPv2, bind simple et dette de protocole »LDAP version 2 a été défini par le RFC (Request for Comments) 1777, publié en 1995. Le RFC 1487, publié en 1993, décrivait une première approche d’accès léger aux services X.500, mais ne constitue pas la spécification LDAPv2 finale. Cette précision compte : l’héritage du protocole explique des comportements encore présents dans des produits modernes, il ne fonde aucune politique de sécurité actuelle.
Un bind simple place un nom distinctif, ou DN (Distinguished Name), et un mot de passe dans la requête LDAP, en octets bruts, sans hachage ni défi-réponse. LDAP ne chiffre rien de tout ça. Sur une connexion TCP (Transmission Control Protocol) en clair, un tcpdump sur le port 389 rend le mot de passe, les filtres de recherche et les attributs retournés lisibles à l’œil nu dans le BER décodé.
Le compromis est direct. Le bind simple fonctionne partout, se diagnostique en une commande et parle encore aux clients de 2004 (imprimantes, boîtiers VPN (Virtual Private Network), agents de supervision). En échange, toute la sécurité repose sur le canal de transport et sur la validation de son certificat. Le marché devient mauvais dès que le trafic quitte la boucle locale : réseau partagé, commutateur virtuel, VLAN (Virtual Local Area Network (réseau local virtuel)) d’administration, lien inter-sites.
Le RFC 3494 a déclaré LDAPv2 historique en 2003. LDAP version 3, spécifié par le RFC 4511, conserve le bind simple. Une version rangée au placard ne désactive donc rien : un serveur LDAPv3 accepte un bind simple non chiffré aussi longtemps que sa politique ne l’interdit pas, ligne de configuration à l’appui (olcSecurity: ssf=128 côté OpenLDAP, nsslapd-require-secure-binds: on côté 389 Directory Server).
Une migration ne consiste pas à remplacer ldap:// par ldaps:// dans les fichiers de configuration. Elle consiste à prouver que chaque client contrôle trois choses : le nom du serveur contre le SAN du certificat, la chaîne jusqu’à une autorité de certification connue, et les dates de validité. Un canal chiffré sans vérification d’identité arrête l’écoute passive et laisse passer le serveur imposteur qui a monté son propre ldaps:// sur le même VLAN.
Anonymous bind et exposition des métadonnées LDAP
Section intitulée « Anonymous bind et exposition des métadonnées LDAP »Un anonymous bind est une opération LDAP sans identité authentifiée. Certains serveurs l’acceptent implicitement quand un client ouvre la connexion et enchaîne sur un searchRequest sans envoyer de bind. D’autres acceptent un bind simple avec DN vide et mot de passe vide. Même effet : les droits appliqués sont ceux de l’utilisateur anonyme.
L’anonymat n’est pas un mode dégradé inoffensif. Une règle de lecture en apparence restreinte laisse souvent fuiter les unités d’organisation, les cn de groupes, les mail, les comptes de service, les objets machine, le subschemaSubentry et la hiérarchie complète. De quoi construire une liste de cibles d’hameçonnage nominative, choisir les comptes de service à attaquer par mot de passe, et repérer les groupes qui mènent aux privilèges. Le tout sans un seul identifiant valide.
La règle qui tient dans le temps : refuser tout accès anonyme, sauf besoin fonctionnel documenté et isolé. Un carnet d’adresses consultable par des partenaires ne justifie pas d’ouvrir l’annuaire d’autorité. On publie une vue dédiée, avec un schéma réduit à cn, mail, telephoneNumber, alimentée par réplication. Répliquer coûte une instance de plus ; maintenir une liste d’exceptions d’ACL sur l’annuaire d’autorité coûte une fuite le jour où quelqu’un ajoute une branche.
Les erreurs les plus chères viennent des permissions héritées. Une ACL de lecture accordée à *, à anonymous ou à un groupe qui englobe les identités non authentifiées ouvre une branche entière, sous-arbres compris. Ces contrôles se vérifient depuis une connexion sans certificat client, sans mot de passe, depuis un segment réseau équivalent à celui d’un consommateur externe. Tester avec un compte administrateur ne valide rien : ses droits recouvrent la politique effective.
L’exposition LDAP fait partie de l’énumération des métadonnées anonymes en environnement Active Directory, où le 7e caractère de l’attribut dsHeuristics décide si les opérations anonymes autres que rootDSE sont autorisées (valeur 2) ou refusées, ce qui est le comportement par défaut depuis Windows Server 2003. Même quand le bind anonyme échoue, la rootDSE, les codes d’erreur, les référencements LDAP et le certificat présenté livrent déjà defaultNamingContext, noms de domaine et noms d’hôtes. Fermer le bind anonyme retire une porte, pas le filtrage réseau ni la discrétion des services périphériques.
StartTLS, LDAPS et SASL/GSSAPI
Section intitulée « StartTLS, LDAPS et SASL/GSSAPI »TLS (Transport Layer Security) protège la confidentialité et l’intégrité de la connexion entre client et serveur. LDAP l’établit de deux manières.
LDAPS négocie TLS dès l’ouverture de la connexion, par convention sur le port 636. La convention n’est pas normalisée en tant que telle, elle est simplement universelle, et elle fonctionne dès que équipements réseau et bibliothèques clientes acceptent ce port. Avantage pratique : aucun octet LDAP ne circule avant le handshake.
StartTLS ouvre une session LDAP sur le port 389, puis demande le passage sous TLS via l’opération étendue OID 1.3.6.1.4.1.1466.20037, avant toute authentification applicative. Normalisée d’abord par le RFC 2830, la mécanique est décrite aujourd’hui par les RFC 4511 et 4513. Elle ne protège rien si le client accepte de continuer quand la négociation échoue.
Le choix entre les deux dépend du parc client et du contrôle des chemins réseau. LDAPS supprime le scénario du client qui « oublie » de déclencher StartTLS. StartTLS garde un seul port à ouvrir sur les pare-feux et les proxys. Ni l’un ni l’autre ne justifie d’accepter un bind avec mot de passe avant chiffrement : le serveur doit répondre confidentialityRequired (code de résultat LDAP 13) tant que le canal n’est pas protégé.
SASL (Simple Authentication and Security Layer) sort LDAP du tête-à-tête avec le mot de passe transporté. GSSAPI (Generic Security Services Application Program Interface) en est le mécanisme le plus déployé, adossé à Kerberos : le client présente un ticket de service ldap/serveur@REALM, le mot de passe du compte ne quitte jamais le poste, et le serveur LDAP n’a aucun secret utilisateur à stocker.
SASL/GSSAPI ne supprime pas le besoin de TLS. Kerberos authentifie le bind ; TLS chiffre les filtres de recherche, les attributs retournés et authentifie le serveur, sauf si la couche de sécurité GSSAPI négociée assure elle-même le chiffrement (ssf non nul). Là où les clients parlent Kerberos, SASL/GSSAPI couvre les identités humaines et les services intégrés au domaine. Pour les applications hétérogènes, bind simple sur TLS validé reste défendable, à condition d’être imposé côté serveur et surveillé dans les journaux.
Exemple de contrôle d’un serveur LDAP
Section intitulée « Exemple de contrôle d’un serveur LDAP »La commande suivante utilise ldapsearch, fourni par OpenLDAP. Elle vérifie d’abord qu’un accès anonyme ne retourne aucun attribut, puis effectue une recherche authentifiée sur TLS. Les noms, certificats et identifiants doivent correspondre à un environnement de test.
# L'accès anonyme doit échouer ou ne retourner aucun objet lisible.ldapsearch \ -H ldap://ldap.example.test:389 \ -x \ -b "dc=example,dc=test" \ -s base \ "(objectClass=*)"
# Le bind simple passe seulement après StartTLS.# -ZZ impose StartTLS : la commande échoue si TLS ne peut pas être négocié.# LDAPTLS_REQCERT=hard impose la validation du certificat serveur.LDAPTLS_REQCERT=hard ldapsearch \ -H ldap://ldap.example.test:389 \ -ZZ \ -x \ -D "uid=svc-inventory,ou=services,dc=example,dc=test" \ -W \ -b "ou=people,dc=example,dc=test" \ "(uid=alice)" \ cn mailL’option -Z seule demande StartTLS et laisse le client continuer en clair si la négociation échoue, selon l’implémentation. -ZZ échoue, ce qui est exactement le comportement attendu d’un test de conformité. La validation exige en plus une autorité de certification présente dans le magasin du système et un nom d’hôte dans l’URL qui corresponde au SAN du certificat. Passer une adresse IP à la place du nom fait échouer la commande, et c’est le signe que la validation fonctionne.
Un test réussi ne démontre pas que le serveur refuse le clair. Il faut tenter un bind simple sans -Z ni -ZZ avec un compte de test : la réponse attendue est le code 13, confidentialityRequired. Puis un bind DN vide et mot de passe vide, puis une recherche anonyme sur dc=example,dc=test. Ces trois cas couvrent trois protections distinctes : chiffrement obligatoire, authentification obligatoire, autorisation minimale. ldapwhoami -x -H ldap://... donne au passage l’identité effective vue par le serveur.
Politique de migration et contrôles d’architecture
Section intitulée « Politique de migration et contrôles d’architecture »La séquence commence par l’inventaire des consommateurs LDAP. Applications métier, agents de supervision, imprimantes multifonctions, commutateurs et boîtiers VPN, passerelles de messagerie, scripts d’administration : la liste dépasse presque toujours ce qu’annonce la documentation. Les journaux du serveur donnent la matière : type de bind, DN présenté, adresse source, code de résultat. Sur OpenLDAP, un loglevel stats suffit à sortir les lignes BIND dn=... method=128 (bind simple) et method=163 (SASL).
La bascule sûre suit cet ordre :
- publier un certificat valide pour chaque nom de service LDAP ;
- activer LDAPS ou StartTLS et contrôler la validation côté clients ;
- migrer les clients vers TLS ou SASL/GSSAPI ;
- traquer les derniers binds simples en clair dans les journaux ;
- imposer TLS côté serveur ;
- désactiver l’anonymous bind et repasser les listes de contrôle d’accès.
L’ordre inverse casse les dépendances silencieuses, celles qui n’apparaissent que le lundi matin quand la pointeuse ne répond plus. Maintenir une exception par adresse IP est pire que de reporter la migration : les adresses changent, les flux sont réécrits par un load-balancer, et l’exception survit à la personne qui l’a créée. Si une compatibilité temporaire est inévitable, elle se limite à un segment réseau dédié, à un compte de service en lecture sur une seule branche, et à une date de retrait inscrite dans la configuration, pas dans un ticket.
Les mots de passe de comptes de service demandent un traitement séparé. TLS les protège en transit, jamais au repos dans un application.properties, une variable d’environnement d’un conteneur ou une trace de débogage niveau DEBUG. Leur cycle de vie suit les mêmes principes que la rotation de clés : inventaire, propriétaire nommé, rotation datée, révocation, preuve de consommation. Un compte LDAP partagé entre six applications rend la rotation impossible, puisque personne ne sait laquelle tombera.
Les alertes doivent séparer les échecs de routine des signes de reconnaissance. Une hausse des recherches anonymes, des searchRequest répétés avec scope=sub sur la racine de l’arbre, une série de codes 13 ou 49, une énumération de objectClass=group : autant de motifs à corréler avec les journaux réseau. La supervision conserve identifiant de connexion, type de bind, DN, base de recherche, code de résultat et adresse source. Elle ne conserve ni mot de passe, ni attributs retournés, sinon le SIEM devient la copie non chiffrée de l’annuaire.
🐝 Ce que ça change côté sécurité
Section intitulée « 🐝 Ce que ça change côté sécurité »L’annuaire se défend en couches. À l’entrée : aucune authentification par mot de passe hors TLS validé, bind anonyme refusé par défaut, et accès publics servis par une vue répliquée à schéma réduit plutôt que par des exceptions d’ACL sur l’annuaire d’autorité. Au-dessus : des journaux qui gardent type de bind, DN, base de recherche, code de résultat et adresse source, sans mot de passe ni attributs, pour repérer les recherches anonymes en hausse et les balayages de la racine. Enfin la réponse, outillée à l’avance : révocation des comptes de service exposés, rotation des secrets, retrait daté de chaque exception de compatibilité, jamais reconduite sans propriétaire nommé.
🪵 Comment le vérifier
Section intitulée « 🪵 Comment le vérifier »Monter un annuaire de test avec une dizaine d’entrées fictives, puis enchaîner trois tentatives : recherche anonyme sans bind, bind simple avec DN et mot de passe vides, bind simple en clair sur le port 389 sans StartTLS. Comparer ensuite avec -ZZ et LDAPTLS_REQCERT=hard. Rejouer la série depuis un autre segment réseau, sans certificat client et sans compte privilégié. Si l’un des trois premiers essais retourne des objets ou accepte le mot de passe au lieu de renvoyer le code 13 confidentialityRequired, la configuration ne tient que sur la bonne volonté des clients. Remplacer enfin le nom du serveur par son adresse IP : la commande doit échouer sur une erreur de certificat, sinon la validation n’est pas effective.
🦫 Explication de la marmotte 🍫
Section intitulée « 🦫 Explication de la marmotte 🍫 »Un annuaire informatique conserve des informations sur des personnes, des groupes, des machines et des services. Pour les consulter, un logiciel ouvre une connexion vers le serveur de l’annuaire. Il peut s’identifier avec un nom et un mot de passe : c’est l’authentification simple. Si la connexion n’est pas chiffrée avant cet envoi, le mot de passe et les données demandées circulent en toutes lettres, lisibles par qui observe le réseau.
Une connexion anonyme ne fournit ni nom ni mot de passe. Le serveur décide alors ce qu’une personne non identifiée peut lire. Quand les règles sont trop larges, elle récupère des noms de comptes, des adresses électroniques, des listes de groupes et l’organisation interne. De quoi savoir à qui écrire pour tromper quelqu’un, et sur quel serveur insister.
La protection commence par chiffrer la connexion et vérifier l’identité du serveur grâce à son certificat. Le logiciel doit couper la connexion si ce certificat ne correspond pas au serveur attendu, ou si le chiffrement ne démarre pas. Le serveur, de son côté, refuse les connexions anonymes et les mots de passe envoyés sans chiffrement.
Une autre méthode évite complètement d’envoyer le mot de passe de l’annuaire : le poste présente un ticket d’identité délivré plus tôt par un service dédié, valable quelques heures. Si le chiffrement échoue, si le certificat ne correspond pas au serveur ou si l’identité n’a pas les droits demandés, la consultation s’arrête là.
À lire aussi
- Kerberos et KDC dans Active Directory, attaques et durcissementFonctionnement du protocole Kerberos v5 et de son centre de distribution de clés, intégration dans Active Directory, attaques classiques sur les tickets et mesures de durcissement.
- Comment limiter le mouvement latéral après compromissionLe mouvement latéral permet à un attaquant déjà présent de progresser vers des systèmes plus sensibles, mais la segmentation et la détection interne en réduisent fortement la portée.
- Sécuriser les imprimantes réseau en entrepriseLes imprimantes réseau sont des systèmes exposés qui exigent segmentation, mises à jour, contrôle des accès et supervision.
- Comment structurer Active Directory et déléguer sans escaladeConcevoir la structure Active Directory, limiter les délégations et réduire les chemins d’attaque vers les privilèges de domaine.
Pages voisines
La citent
- Kerberos et KDC dans Active Directory, attaques et durcissement
- Gouverner les comptes de service et agents autonomes
- Gouverner les facteurs d’authentification en entreprise
- Séparer plan de contrôle et plan de données
- Attaque de l'intercepteur par ARP, DHCP, DNS, Wi-Fi et proxy TLS
- Auditer les comptes orphelins Active Directory
- Calculer le coût total de possession d'un contrôle de sécurité
- Calculer le coût-bénéfice d’un incident évité
- Comment attribuer techniquement une cyberattaque
- Comment automatiser la recertification des accès sensibles
Grand-père Castor raconte : bind LDAP en clair, corrigé
Elle cite
: les deux pages se citent l’une l’autre.
