📂 OpenLDAP et authentification centralisée SSSD
| Formation | BTS SIO option SISR — IRIS Mediaschool |
|---|---|
| Cours | C2.2.7 — Annuaire LDAP et Active Directory avancé (7h) |
| Bloc | B2 — Administration Systèmes & Réseaux |
| Module | M2.2 — Administration Linux |
| Compétences | B2.2 / B2.3 / Lien B3.2 |
| Durée séance | 3h30 |
| Prérequis | Connaissances de base Linux (bash, systemd) et réseau ; notions élémentaires d'annuaires et d'authentification |
🎯 Objectifs
- Comprendre le modèle d'annuaire (DIT, DN, RDN) et les principaux attributs et classes d'objets LDAP.
- Savoir administrer un serveur OpenLDAP (
cn=config) : suffix, rootDN, rootPW, exporter/importer la base avecslapcat/slapadd. - Maîtriser le format LDIF et les opérations de base (
ldapsearch,ldapadd,ldapmodify,ldapdelete) avec filtres RFC 4515. - Configurer SSSD pour une authentification centralisée Linux et vérifier l'obtention des comptes via
getent.
📖 Matériel et environnements
| Machine | Rôle | Paquets |
|---|---|---|
debian-srv01 | Serveur LDAP | OpenLDAP (slapd), ldap-utils |
debian-srv02 | Client Linux | SSSD, libnss-sss, libpam-sss |
Des attaquants ont maintenu une persistance durable dans des environnements Active Directory en abusant des mécanismes d'authentification Kerberos (Golden Ticket). Comprendre les annuaires et les baux d'authentification est donc critique pour la sécurité d'une entreprise.
📖 00:15 — Modèle LDAP : DIT, DN, RDN, attributs et classes d'objets (45 min)
DIT — Directory Information Tree
Le DIT (Directory Information Tree) est l'organisation hiérarchique des entrées d'un annuaire LDAP. Il ressemble à une structure d'arbre inversé, avec une racine au sommet et des branches représentant des unités organisationnelles (ou=), des domaines (dc=) ou d'autres conteneurs.
- Bonne pratique : utiliser
dc=(domain component) pour la racine du domaine, etou=(organizational unit) pour les branches. - Exemple de racine :
dc=innovattech,dc=local
DN et RDN
| Concept | Définition | Exemple |
|---|---|---|
| DN (Distinguished Name) | Chemin complet et unique d'une entrée dans le DIT | uid=jmartin,ou=Users,dc=innovattech,dc=local |
| RDN (Relative Distinguished Name) | Portion unique par niveau de la hiérarchie | uid=jmartin |
Attributs usuels
| Attribut | Description |
|---|---|
cn | Common Name — nom complet de la personne ou de l'objet |
sn | Surname — nom de famille |
uid | User Identifier — identifiant de connexion |
mail | Adresse e-mail |
telephoneNumber | Numéro de téléphone |
memberOf | Groupes dont l'entrée est membre |
uidNumber / gidNumber | Identifiants numériques POSIX (Unix/Linux) |
homeDirectory | Répertoire personnel de l'utilisateur |
loginShell | Shell de connexion par défaut |
Chaque attribut est identifiable de façon unique dans le schéma par son OID (Object Identifier), une séquence de chiffres standardisée.
Classes d'objets
| Classe | Description | Attributs requis |
|---|---|---|
person | Personne de base | cn, sn |
inetOrgPerson | Personne avec attributs Internet étendus (hérite de person) | idem + uid, mail… |
posixAccount | Compte Unix/Linux POSIX | uid, uidNumber, gidNumber, homeDirectory |
groupOfNames | Groupe avec liste de membres (DN) | cn, member |
organizationalUnit | Unité organisationnelle (conteneur) | ou |
Les classes d'objets suivent un mécanisme d'héritage : inetOrgPerson hérite de organizationalPerson qui hérite de person. Le schéma est extensible : on peut ajouter des attributs et des classes via des modifications de cn=schema,cn=config.
📖 01:00 — OpenLDAP (slapd) et configuration via cn=config (30 min)
Deux modes de configuration
| Mode | Description | Statut |
|---|---|---|
slapd.conf | Fichier de configuration statique (nécessite un redémarrage) | Legacy — déprécié |
cn=config | Configuration dynamique via des LDIF — modifiable à chaud | Recommandé |
Paramètres importants (cn=config)
| Paramètre | Description | Exemple |
|---|---|---|
olcSuffix | Suffixe (racine) de la base de données | dc=innovattech,dc=local |
olcRootDN | DN du super-administrateur | cn=admin,dc=innovattech,dc=local |
olcRootPW | Mot de passe haché de l'administrateur | {SSHA}… (généré par slappasswd) |
Exemple : LDIF de configuration du suffixe
dn: olcDatabase={1}mdb,cn=config
changetype: modify
replace: olcSuffix
olcSuffix: dc=innovattech,dc=local
-
replace: olcRootDN
olcRootDN: cn=admin,dc=innovattech,dc=local
-
replace: olcRootPW
olcRootPW: {SSHA}REPLACE_WITH_SLAPPASSWD_OUTPUT
Application de ce LDIF :
ldapmodify -Y EXTERNAL -H ldapi:/// -f config.ldif
Sauvegarde et restauration de la base
# Export de toute la base (arrêt non nécessaire avec slapcat)
sudo slapcat -v -l backup.ldif
# Import : arrêter slapd AVANT slapadd
sudo service slapd stop
sudo slapadd -v -l backup.ldif
sudo service slapd start
slapcat lit directement la base Berkeley DB/MDB et peut s'exécuter en parallèle d'un slapd actif. En revanche, slapadd requiert l'arrêt du service pour éviter la corruption de la base.
📖 01:30 — Format LDIF et exemples (30 min)
Structure d'une entrée LDIF
Un fichier LDIF (LDAP Data Interchange Format) est un format texte standard pour représenter et modifier des entrées LDAP. Chaque entrée commence par dn: suivi des paires attribut: valeur.
| changetype | Action |
|---|---|
add | Ajouter une nouvelle entrée |
modify | Modifier une entrée existante (replace, add, delete d'attribut) |
delete | Supprimer une entrée |
Exemple : entrée utilisateur
dn: uid=jdupont,ou=Users,dc=innovattech,dc=local
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
cn: Jean Dupont
sn: Dupont
uid: jdupont
uidNumber: 10010
gidNumber: 1000
homeDirectory: /home/jdupont
loginShell: /bin/bash
mail: j.dupont@innovattech.local
telephoneNumber: +33 1 23 45 67 89
Exemple : entrée de groupe
dn: cn=Developers,ou=Groups,dc=innovattech,dc=local
objectClass: groupOfNames
cn: Developers
member: uid=jdupont,ou=Users,dc=innovattech,dc=local
member: uid=jmartin,ou=Users,dc=innovattech,dc=local
Exemple : structure de base (OU)
dn: dc=innovattech,dc=local
objectClass: top
objectClass: dcObject
objectClass: organization
o: InnovatTech
dc: innovattech
dn: ou=Users,dc=innovattech,dc=local
objectClass: organizationalUnit
ou: Users
dn: ou=Groups,dc=innovattech,dc=local
objectClass: organizationalUnit
ou: Groups
📖 02:00 — Opérations LDAP usuelles et filtres RFC 4515 (30 min)
Commandes clés
| Commande | Rôle | Exemple |
|---|---|---|
ldapsearch | Rechercher des entrées | ldapsearch -x -b dc=innovattech,dc=local "(objectClass=inetOrgPerson)" |
ldapadd | Ajouter des entrées depuis un LDIF | ldapadd -x -D "cn=admin,dc=innovattech,dc=local" -W -f users.ldif |
ldapmodify | Modifier des entrées existantes | ldapmodify -x -D "cn=admin,dc=innovattech,dc=local" -W -f modify.ldif |
ldapdelete | Supprimer une entrée par son DN | ldapdelete -x -D "cn=admin,dc=innovattech,dc=local" -W "uid=jmartin,ou=Users,dc=innovattech,dc=local" |
Filtres RFC 4515
Les filtres LDAP permettent d'affiner les recherches. Ils utilisent une syntaxe préfixée (polonaise) :
| Filtre | Signification |
|---|---|
(attribut=valeur) | Égalité exacte |
(attribut=val*) | Commence par val (wildcard) |
(&(filtre1)(filtre2)) | ET logique |
(|(filtre1)(filtre2)) | OU logique |
(!(filtre)) | NON logique |
# Recherche des personnes dont le CN commence par "Jean"
ldapsearch -x -b dc=innovattech,dc=local "(&(objectClass=person)(cn=Jean*))"
# Recherche avec OU (mail local OU téléphone français)
ldapsearch -x -b dc=innovattech,dc=local "(|(mail=*@innovattech.local)(telephoneNumber=+33*))"
# Lister tous les utilisateurs POSIX
ldapsearch -x -b ou=Users,dc=innovattech,dc=local "(objectClass=posixAccount)" uid cn mail
📖 02:30 — Authentification Linux centralisée avec SSSD (60 min)
Présentation de SSSD
SSSD (System Security Services Daemon) est un service qui centralise la résolution d'identités et l'authentification sur des systèmes Linux. Il agit comme un proxy entre le système local et les fournisseurs d'identités (LDAP, Active Directory, Kerberos…).
- NSS (Name Service Switch) : résolution des comptes et groupes via
getent - PAM (Pluggable Authentication Modules) : authentification à la connexion
- Cache local des identités pour la continuité de service (connexion possible même si le serveur LDAP est temporairement inaccessible)
Configuration minimale /etc/sssd/sssd.conf
[sssd]
services = nss, pam
config_file_version = 2
domains = innovattech.local
[domain/innovattech.local]
id_provider = ldap
auth_provider = ldap
chpass_provider = ldap
ldap_uri = ldap://debian-srv01
ldap_search_base = dc=innovattech,dc=local
ldap_schema = rfc2307
ldap_default_bind_dn = cn=admin,dc=innovattech,dc=local
ldap_default_authtok_type = password
ldap_default_authtok = CHANGE_ME_PASSWORD
cache_credentials = True
enumerate = False
[pam]
[nss]
Étapes de mise en place sur le client (debian-srv02)
# 1. Installer SSSD et les modules NSS/PAM
sudo apt install -y sssd libnss-sss libpam-sss
# 2. Protéger le fichier de configuration (requis par SSSD)
sudo chmod 600 /etc/sssd/sssd.conf
sudo chown root:root /etc/sssd/sssd.conf
# 3. Vérifier /etc/nsswitch.conf
# passwd: sss files
# group: sss files
# shadow: sss files
# 4. Redémarrer SSSD
sudo systemctl restart sssd
sudo systemctl enable sssd
# 5. Vérifier la résolution des comptes LDAP
getent passwd jdupont
getent passwd | grep innovattech
id jdupont
Sur les distributions basées sur Red Hat, utilisez sudo authselect select sssd pour configurer automatiquement PAM et NSS pour SSSD. Sur Debian/Ubuntu, l'adaptation manuelle de /etc/nsswitch.conf est requise.
Récapitulatif flux d'authentification
| Étape | Composant | Action |
|---|---|---|
| 1 | Utilisateur | Lance ssh jdupont@debian-srv02 |
| 2 | PAM (pam_sss) | Appelle SSSD pour valider le mot de passe |
| 3 | SSSD | Interroge debian-srv01 (LDAP ldap://debian-srv01) via LDAP BIND |
| 4 | OpenLDAP | Vérifie le DN et le mot de passe, retourne le profil POSIX |
| 5 | NSS (nss_sss) | Fournit uidNumber, gidNumber, homeDirectory au noyau |
| 6 | Système | Crée la session, monte le home si configuré (pam_mkhomedir) |
💻 TP S1 — Déployer OpenLDAP et configurer SSSD
Objectif : déployer un annuaire centralisé OpenLDAP et permettre l'authentification d'un poste Linux via SSSD.
Livrables attendus : LDIF des 10 utilisateurs, captures d'écran des commandes et sorties.
Sur debian-srv01 (serveur LDAP)
Étape 1 — Installer OpenLDAP et outils
sudo apt update && sudo apt install -y slapd ldap-utils
sudo dpkg-reconfigure slapd # optionnel : configuration interactive
Étape 2 — Générer le mot de passe administrateur
sudo slappasswd -s ChangeMeSecret
# Copier la sortie {SSHA}... dans olcRootPW
Étape 3 — Créer et charger la structure de base (base.ldif)
# base.ldif
dn: dc=innovattech,dc=local
objectClass: top
objectClass: dcObject
objectClass: organization
o: InnovatTech
dc: innovattech
dn: ou=Users,dc=innovattech,dc=local
objectClass: organizationalUnit
ou: Users
dn: ou=Groups,dc=innovattech,dc=local
objectClass: organizationalUnit
ou: Groups
ldapadd -x -D "cn=admin,dc=innovattech,dc=local" -W -f base.ldif
Étape 4 — Créer les 10 utilisateurs (users.ldif)
# Exemple users.ldif (10 entrées)
dn: uid=jmartin,ou=Users,dc=innovattech,dc=local
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
cn: Jean Martin
sn: Martin
uid: jmartin
uidNumber: 10011
gidNumber: 1000
homeDirectory: /home/jmartin
loginShell: /bin/bash
mail: j.martin@innovattech.local
userPassword: {SSHA}REPLACE_WITH_HASH
dn: uid=jdupont,ou=Users,dc=innovattech,dc=local
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
cn: Jean Dupont
sn: Dupont
uid: jdupont
uidNumber: 10012
gidNumber: 1000
homeDirectory: /home/jdupont
loginShell: /bin/bash
mail: j.dupont@innovattech.local
userPassword: {SSHA}REPLACE_WITH_HASH
# Répéter pour : jlegrand (10013), jdurand (10014), jbernard (10015),
# jblanc (10016), jmoreau (10017), jrobin (10018), jdaubry (10019), jaubert (10020)
ldapadd -x -D "cn=admin,dc=innovattech,dc=local" -W -f users.ldif
Étape 5 — Vérifier l'annuaire
ldapsearch -x -b dc=innovattech,dc=local "(objectClass=posixAccount)" uid cn
# Doit lister les 10 utilisateurs
Sur debian-srv02 (client Linux)
# Installer SSSD
sudo apt install -y sssd libnss-sss libpam-sss
# Éditer /etc/sssd/sssd.conf (voir configuration ci-dessus)
# ldap_uri = ldap://debian-srv01
# ldap_search_base = dc=innovattech,dc=local
sudo chmod 600 /etc/sssd/sssd.conf
sudo systemctl restart sssd
# Vérification finale
getent passwd jmartin
id jmartin
Critères de réussite
- L'annuaire contient 10 utilisateurs vérifiés par
ldapsearch. - Le poste client résout les comptes LDAP via
getent passwd. - L'utilisateur peut s'authentifier (test
id jmartinousu - jmartin).
📌 Annexes — Rappel des commandes utiles
# Export de la base
sudo slapcat -v -l backup.ldif
# Import de la base (slapd arrêté)
sudo service slapd stop && sudo slapadd -v -l backup.ldif && sudo service slapd start
# Modifier cn=config
ldapmodify -Y EXTERNAL -H ldapi:/// -f config.ldif
# Générer un hash de mot de passe SSHA
slappasswd -s <motdepasse>
📚 Ressources
- RFC 4511 & 4512 (LDAP) / RFC 4515 (Filtres LDAP)
- Documentation OpenLDAP : openldap.org/doc
- SSSD :
man sssd.confet sssd.io
📝 QCM — Testez vos connaissances
-
Q1 (QCM) — Que représente le DN (Distinguished Name) dans un annuaire LDAP ?
- A) Le mot de passe chiffré d'un utilisateur
- B) Le chemin complet et unique identifiant une entrée dans le DIT
- C) Le nom du serveur OpenLDAP
- D) Le filtre de recherche par défaut
-
Q2 (QCM) — Quelle commande OpenLDAP permet d'exporter toute la base vers un fichier LDIF ?
- A)
ldapexport -v -l backup.ldif - B)
slapadd -v -l backup.ldif - C)
slapcat -v -l backup.ldif - D)
ldapdump -f backup.ldif
- A)
-
Q3 (QCM) — Quel filtre LDAP (RFC 4515) permet de rechercher tous les utilisateurs dont le
cncommence par "Jean" et qui sont de la classeperson?- A)
(cn=Jean AND objectClass=person) - B)
(&(objectClass=person)(cn=Jean*)) - C)
(|(objectClass=person)(cn=Jean*)) - D)
(objectClass=person)(cn=Jean*)
- A)
-
Q4 (QCM) — Dans
/etc/sssd/sssd.conf, à quoi correspond le paramètreldap_search_base?- A) Le DN de l'administrateur LDAP
- B) L'adresse IP du serveur LDAP
- C) La racine (base) de l'arbre à partir de laquelle SSSD effectue ses recherches
- D) Le chemin local vers la base de cache SSSD
-
Q5 (Vrai / Faux) — "
slapd.confest le mode de configuration recommandé dans les versions récentes d'OpenLDAP."- A) Vrai
- B) Faux
📝 Afficher les corrections
- B — Le chemin complet et unique identifiant une entrée dans le DIT. Exemple :
uid=jmartin,ou=Users,dc=innovattech,dc=local. Le RDN est la partie unique par niveau (uid=jmartin). - C —
slapcat -v -l backup.ldif.slapcatlit directement la base MDB et peut s'exécuter slapd actif.slapaddest l'opération inverse (import, nécessite l'arrêt de slapd). - B —
(&(objectClass=person)(cn=Jean*)). L'opérateur&est le ET logique en syntaxe préfixée RFC 4515 ;cn=Jean*utilise le wildcard pour "commence par". - C — La racine de l'arbre à partir de laquelle SSSD effectue ses recherches. Exemple :
ldap_search_base = dc=innovattech,dc=local. SSSD interrogera toutes les entrées sous ce suffixe. - B — Faux.
slapd.confest le mode legacy désormais déprécié. Le mode recommandé estcn=config(OLC — Online Configuration), qui permet des modifications dynamiques sans redémarrage de slapd.
LDAP structure les identités dans un arbre hiérarchique (DIT) adressable par DN unique. OpenLDAP se configure dynamiquement via cn=config et se sauvegarde avec slapcat. Les filtres RFC 4515 permettent des recherches précises. SSSD branche le système Linux sur l'annuaire LDAP pour centraliser authentification et résolution d'identités — vérifiable immédiatement avec getent passwd.
