====== Client sssd (Debian) — login système via LLDAP ====== Dernière mise à jour : juin 2026 État : **validé sur Debian Trixie** — login en ligne ET **hors ligne** fonctionnels. C'est la config de référence à déployer sur les autres portables. Voir la doc serveur séparée pour LLDAP, le réseau, les UID/GID et le modèle de groupes. ===== Principe ===== sssd interroge LLDAP en LDAPS, résout users/groupes, et **cache les credentials localement** pour permettre le login hors réseau (cache offline éprouvé de sssd). ===== Machine de référence ===== * Portable : lat7400 — Debian Trixie (13) * Compte de test : ''testldap'' (uid 15000, gid primaire 302/famille) ===== Installation ===== sudo apt install -y sssd sssd-tools libnss-sss libpam-sss libsss-sudo ldb-tools (''ldb-tools'' fournit ''ldbsearch'', utile pour inspecter le cache.) ===== Certificat CA ===== Copier le CA auto-signé du serveur vers le portable : sudo mkdir -p /etc/ssl/lldap sudo scp maitre@192.168.1.9:/mnt/stockage/docker/data/lldap/ca-cert.pem /etc/ssl/lldap/ca-cert.pem ===== Configuration sssd ===== ''/etc/sssd/sssd.conf'' — **permissions 600 obligatoires** (sinon sssd refuse de démarrer). [sssd] services = nss, pam domains = beafrancois.fr [nss] filter_users = root filter_groups = root [pam] offline_credentials_expiration = 0 [domain/beafrancois.fr] enumerate = True id_provider = ldap auth_provider = ldap chpass_provider = ldap access_provider = simple simple_allow_groups = famille cache_credentials = True use_fully_qualified_names = False ldap_uri = ldaps://auth.beafrancois.fr:6360 ldap_schema = rfc2307bis ldap_search_base = dc=beafrancois,dc=fr ldap_default_bind_dn = uid=binduser,ou=people,dc=beafrancois,dc=fr ldap_default_authtok = MOT_DE_PASSE_BINDUSER ldap_tls_cacert = /etc/ssl/lldap/ca-cert.pem ldap_tls_reqcert = demand # Users (object class réel LLDAP = posixAccount) ldap_user_search_base = ou=people,dc=beafrancois,dc=fr?subtree?(uidNumber=*) ldap_user_object_class = posixAccount ldap_user_name = uid ldap_user_uid_number = uidNumber ldap_user_gid_number = gidNumber ldap_user_home_directory = homeDirectory # Groupes (object class réel LLDAP = groupOfNames, membres par DN) ldap_group_search_base = ou=groups,dc=beafrancois,dc=fr?subtree?(gidNumber=*) ldap_group_object_class = groupOfNames ldap_group_name = cn ldap_group_member = member ldap_group_gid_number = gidNumber dns_resolver_server_timeout = 500 dns_resolver_op_timeout = 1 dns_resolver_timeout = 2 ldap_opt_timeout = 3 ldap_network_timeout = 2 override_homedir = /home/%u ldap_user_shell = unixShell default_shell = /bin/bash Permissions + activation : sudo chmod 600 /etc/sssd/sssd.conf sudo chown root:root /etc/sssd/sssd.conf sudo sssctl config-check # doit retourner 0 issue ===== Intégration PAM / NSS ===== sudo pam-auth-update Cocher : **SSS authentication**, **Create home directory on login**, garder **Unix authentication**. **Décocher** tout autre fournisseur d'auth résiduel. ''nsswitch.conf'' : ''libnss-sss'' ajoute ''sss'' automatiquement. Vérifier : grep -E "^passwd|^group" /etc/nsswitch.conf # passwd: files systemd sss # group: files systemd sss Démarrage : sudo systemctl enable --now sssd sudo sssctl domain-status beafrancois.fr # doit afficher Online ===== ⚠️ PIÈGES MAJEURS (vécus, ne pas refaire) ===== ==== 1. Mapping object class — LE point critique ==== Les valeurs par défaut de sssd ne correspondent PAS au schéma LLDAP. Valeurs **correctes vérifiées** : * ''ldap_user_object_class = posixAccount'' (PAS ''person'') * ''ldap_group_object_class = groupOfNames'' (PAS ''posixGroup'') * ''ldap_group_member = member'' (LLDAP stocke les membres par **DN**, pas memberUid) * ''ldap_schema = rfc2307bis'' (obligatoire pour membres par DN) Un mauvais ''ldap_group_object_class'' = "Autorisation refusée" au login (le groupe ''famille'' n'est pas reconnu, l'access_provider simple refuse). ==== 2. NE PAS utiliser auto_private_groups / groupes privés ==== **Cause de l'échec offline pendant des heures.** Avec ''auto_private_groups = true'' OU des groupes privés portant le même nom que l'utilisateur, sssd génère un conflit MPG (« Group named X already exists in an MPG domain ») : l'**écriture du user dans le cache échoue**, donc pas de credential caché, donc **offline impossible**. **Solution validée :** groupe primaire **partagé** (''famille'', gid 302) pour tous les users. Pas de groupe privé, pas de ''auto_private_groups''. Le ''gidNumber'' primaire de chaque user pointe vers un groupe **qui existe** (famille). Règle générale : tout ''gidNumber'' primaire d'un user DOIT correspondre à un groupe existant dans LLDAP, sinon « impossible de trouver le nom pour l'ID de groupe » et l'initgroups offline casse. ==== 3. offline_credentials_expiration dans [pam] ==== Doit être dans la section **[pam]**, pas [domain]. Mal placé, ''sssctl config-check'' le signale et le offline illimité ne s'applique pas. Valeur ''0'' = cache offline **illimité** (exigence : login sans réseau indéfiniment). ==== 4. config_file_version interdit ==== Ne PAS mettre ''config_file_version'' (rejeté par sssctl config-check sur cette version). ==== 5. Reset de cache propre ==== Après tout changement de schéma/groupe, vider **entièrement** le cache (db + memory cache), sssd arrêté : sudo systemctl stop sssd sudo rm -f /var/lib/sss/db/cache_beafrancois.fr.ldb /var/lib/sss/db/timestamps_beafrancois.fr.ldb sudo rm -f /var/lib/sss/mc/* sudo systemctl start sssd **⚠️** Ne jamais faire ça si la machine est offline et dépend de sssd (on efface aussi les credentials cachés !). ===== Tests de validation ===== ==== En ligne ==== getent passwd testldap # testldap:*:15000:302:...:/home/testldap:/bin/bash id testldap # uid=15000(testldap) gid=302(famille) groupes=302(famille) su - testldap # crée le home, donne un shell ssh testldap@localhost ==== Vérifier que le credential est caché ==== sudo ldbsearch -H /var/lib/sss/db/cache_beafrancois.fr.ldb \ "name=testldap@beafrancois.fr" 2>/dev/null \ | grep -iE "uidNumber|gidNumber|cachedPassword|originalDN" Doit montrer ''cachedPassword: $6$...'' et ''originalDN: uid=testldap,ou=people,...''. (Note : le filtre ''(objectClass=user)'' ne marche PAS sur cette version de ldb — utiliser ''name=...''.) ==== Offline (l'objectif) ==== # 1. login en ligne (cache le credential) su - testldap ; exit # 2. couper le réseau (wifi off / ethernet débranché) # 3. login hors ligne su - testldap Doit donner un shell **sans réseau**. ✓ Validé. ===== Commandes utilisateur (comportement) ===== ==== passwd — FONCTIONNE (en ligne) ==== L'utilisateur change son mot de passe avec ''passwd''. Écrit dans LLDAP (''chpass_provider = ldap''). **Doit être en ligne** (impossible hors réseau). Voir doc serveur pour les détails de propagation du cache. ==== chsh — NE FONCTIONNE PAS ==== ''chsh'' échoue sur les comptes LLDAP : chsh: l'utilisateur 'testldap' n'existe pas dans /etc/passwd **Limitation de l'outil**, pas de la config : ''chsh'' (util-linux) ne lit/écrit que ''/etc/passwd'' local, il ne passe pas par sssd/NSS. Aucun contournement côté ''chsh''. Le shell des comptes LLDAP est géré autrement : * **Actuellement :** ''default_shell = /bin/bash'' dans sssd.conf — shell fixe identique pour tous. * **Pour des shells par utilisateur :** créer l'attribut ''unixShell'' (ou ''loginShell'') dans le schéma LLDAP, le remplir par user, et l'ajouter au mapping sssd : ''ldap_user_shell = unixShell''. Modifiable alors uniquement par l'admin via l'UI web (pas par l'utilisateur). ==== chfn (gecos / nom complet) ==== Même limitation que ''chsh'' (util-linux, ''/etc/passwd'' local). Le nom complet se gère dans l'UI web LLDAP (''displayName'' / ''cn''), pas par ''chfn''. ===== Purge d'un ancien résolveur d'identité ===== Si un portable a déjà eu un autre résolveur d'identité installé (autre que sssd), le purger avant/après l'installation de sssd, sinon il peut résoudre certains UID en parallèle et entrer en conflit avec sssd : # désactiver le service de l'ancien résolveur, le cas échéant sudo systemctl disable --now 2>/dev/null # retirer son module de /etc/nsswitch.conf (lignes passwd/group) sudo pam-auth-update # décocher l'ancien fournisseur Vérifier ensuite que ''/etc/nsswitch.conf'' ne contient plus que ''files systemd sss'' sur les lignes passwd/group. ===== Bascule des vrais comptes (à faire) ===== * UID cibles en plage haute (10000+) — voir doc serveur * Comptes locaux existants en UID 1000-1003 : leurs homes (''/home/francois'' etc.) appartiennent à l'ancien UID. Après bascule en 10000+, faire un ''chown -R'' du home vers le nouvel UID : sudo chown -R 10000:302 /home/francois * Supprimer le compte local SANS ''-r'' (préserve le home) une fois sssd validé : sudo userdel francois # le home reste * Procéder **PC par PC**, après validation, en gardant un accès admin local de secours. ===== Sécurité ===== * ''offline_credentials_expiration = 0'' (illimité) répond à l'exigence MAIS : un portable volé jamais reconnecté garde un cache valable indéfiniment. **Chiffrement disque LUKS recommandé** sur les portables. * Compte bind en lecture seule (''lldap_strict_readonly''), jamais l'admin. * Auth des serveurs (principal + proxy) : ne PAS passer par sssd — garder compte local + clé SSH (filet de sécurité). ===== Déploiement autres portables ===== * **Debian/Ubuntu** : même procédure (paquets ''sssd sssd-tools libnss-sss libpam-sss libsss-sudo'') * **Arch** : ''sudo pacman -S sssd'' (+ ''openldap'' pour ldapsearch). Mêmes sssd.conf et pièges. * Copier le même ''sssd.conf'' (adapter rien sauf si besoin), le CA, faire ''pam-auth-update''.