Outils pour utilisateurs

Outils du site


commun:serveur_d_authentification_lldap_sssd

Ceci est une ancienne révision du document !


Serveur d'authentification : LLDAP + sssd

Dernière mise à jour : juin 2026

Contexte : remplace Kanidm (abandonné car l'authentification hors ligne ne fonctionnait pas). LLDAP fournit l'annuaire LDAP ; sssd côté portables fournit le login système avec cache offline éprouvé.

État : serveur LLDAP déployé et fonctionnel (LDAPS chiffré). Reste à finaliser le schéma POSIX, le compte bind, et l'installation de sssd sur les portables.

Architecture

Internet
   |  443
   v
[ Routeur OpenWrt ] 192.168.1.90
   |
   v  LAN1 /26
[ Proxy Caddy ] 192.168.1.25
   |  reverse_proxy https://auth.beafrancois.fr -> 192.168.1.9:17170 (web admin)
   v
[ Serveur LLDAP ] 192.168.1.9
   :3890   LDAP clair       (NON exposé : localhost serveur uniquement)
   :6360   LDAPS chiffré     (LAN /26 + wifi 192.168.115.0/24)
   :17170  Web admin (HTTP)  (via Caddy / proxy uniquement)

[ Portables ] LAN filaire 192.168.1.x + WiFi 192.168.115.x
   sssd -> ldaps://auth.beafrancois.fr:6360  (chiffré, CA auto-signé)
   login offline via cache sssd (illimité)

Réseaux :

  • LAN filaire : 192.168.1.0/26 (serveur .9, proxy .25, routeur .90)
  • WiFi séparé : 192.168.115.0/24 (isolé du LAN et du WAN)
  • Tous les portables joignent LLDAP via le nom auth.beafrancois.fr

Pourquoi LLDAP + sssd plutôt que Kanidm

  • Kanidm : auth en ligne OK, mais offline cassé (signature hmac_s256 → Authentication Denied, voir doc Kanidm). Exigence fondamentale non remplie.
  • sssd : le cache offline est son métier depuis ~15 ans, éprouvé en production. C'est précisément le composant qui faisait défaut.
  • LLDAP : annuaire léger avec UI web, recommandé par Kanidm eux-mêmes comme alternative simple.
  • Contrepartie : 2 briques (LLDAP + sssd) au lieu d'une, et pas de SSO web natif (Authelia viendra par-dessus pour les services).

Déploiement serveur (FAIT)

Structure

/mnt/stockage/docker/
├── compose/lldap/docker-compose.yml
└── data/lldap/
    ├── lldap_config.toml      (généré au 1er démarrage)
    ├── users.db               (base SQLite)
    ├── ca-cert.pem            (CA auto-signé)
    ├── ca-key.pem             (clé du CA)
    ├── cert.pem               (cert serveur LDAPS, CN=auth.beafrancois.fr)
    ├── key.pem                (clé serveur)
    ├── san.ext                (extension SAN)
    └── secrets/
        ├── jwt_secret
        └── ldap_user_pass     (mot de passe admin LLDAP)

Génération des secrets

mkdir -p /mnt/stockage/docker/data/lldap/secrets
tr -cd '[:alnum:]' < /dev/urandom | fold -w 64 | head -n 1 > .../secrets/jwt_secret
tr -cd '[:alnum:]' < /dev/urandom | fold -w 24 | head -n 1 > .../secrets/ldap_user_pass
chmod 600 .../secrets/*

Certificat LDAPS auto-signé

cd /mnt/stockage/docker/data/lldap
 
# CA
sudo openssl req -x509 -newkey rsa:4096 -keyout ca-key.pem -out ca-cert.pem \
  -days 3650 -nodes -subj "/CN=LLDAP-CA-beafrancois"
 
# Clé serveur + CSR
sudo openssl req -newkey rsa:4096 -keyout key.pem -out server.csr \
  -nodes -subj "/CN=auth.beafrancois.fr"
 
# Extension SAN
sudo tee san.ext > /dev/null <<'EOF'
subjectAltName = DNS:auth.beafrancois.fr
EOF
 
# Signature
sudo openssl x509 -req -in server.csr -CA ca-cert.pem -CAkey ca-key.pem \
  -CAcreateserial -out cert.pem -days 3650 -extfile san.ext

Vérification LDAPS :

openssl s_client -connect 192.168.1.9:6360 -CAfile .../ca-cert.pem < /dev/null 2>/dev/null \
  | grep -E "subject=|Verify return code"
# Attendu : subject=CN=auth.beafrancois.fr / Verify return code: 0 (ok)

docker-compose.yml

Emplacement : /mnt/stockage/docker/compose/lldap/docker-compose.yml

services:
  lldap:
    image: lldap/lldap:stable
    container_name: lldap
    restart: unless-stopped
    ports:
      - "192.168.1.9:3890:3890"      # LDAP clair (interne)
      - "192.168.1.9:6360:6360"      # LDAPS chiffré
      - "192.168.1.9:17170:17170"    # Web UI
    volumes:
      - /mnt/stockage/docker/data/lldap:/data
      - /mnt/stockage/docker/data/lldap/secrets:/secrets:ro
    environment:
      - LLDAP_LDAP_BASE_DN=dc=beafrancois,dc=fr
      - LLDAP_JWT_SECRET_FILE=/secrets/jwt_secret
      - LLDAP_LDAP_USER_PASS_FILE=/secrets/ldap_user_pass
      - LLDAP_LDAPS_OPTIONS__ENABLED=true
      - LLDAP_LDAPS_OPTIONS__PORT=6360
      - LLDAP_LDAPS_OPTIONS__CERT_FILE=/data/cert.pem
      - LLDAP_LDAPS_OPTIONS__KEY_FILE=/data/key.pem
      - UID=0
      - GID=0

networks:
  default:
    name: lldap_net

Règles UFW

# LDAPS : LAN filaire /26 + wifi /24
sudo ufw allow from 192.168.1.0/26 to any port 6360 proto tcp
sudo ufw allow from 192.168.115.0/24 to any port 6360 proto tcp
# Web admin : via proxy Caddy uniquement
sudo ufw allow from 192.168.1.25 to any port 17170 proto tcp
# Port 3890 (LDAP clair) : NON ouvert (reste interne au serveur)

Reverse proxy Caddy (sur le proxy)

Bloc dans le Caddyfile :

auth.beafrancois.fr {
    reverse_proxy 192.168.1.9:17170
}

Recharge : docker compose exec caddy caddy reload –config /etc/caddy/Caddyfile

LLDAP web parle HTTP simple : pas de tls_insecure_skip_verify nécessaire (contrairement à Kanidm).

Comptes et groupes (FAIT)

Base DN : dc=beafrancois,dc=fr. Users sous ou=people, groupes sous ou=groups.

Groupe gidNumber Rôle
famille (GID serveur à reporter) accès commun aux 4 users
partage (GID serveur) partage /export/partage
multimedia (GID serveur) partage /export/multimedia
Utilisateur uidNumber Identifiant
François 1000 francois
Béatrice 1001 beatrice
Corentin 1002 corentin
Louis 1003 louis
Test 5000 testldap (groupe famille, pour validation)

Les UID/GID matchent les comptes locaux existants sur les PC (cohérence des partages NFS).

Connexion admin : https://auth.beafrancois.fr — user admin, mot de passe = contenu de secrets/ldap_user_pass.

RESTE À FAIRE (reprise)

1. Schéma POSIX dans LLDAP ⚠️ CRUCIAL

LLDAP n'a pas d'attributs POSIX par défaut. L'UUID affiché dans l'UI n'est PAS le uidNumber. sssd a besoin des vrais attributs POSIX, à créer manuellement dans le schéma LLDAP (UI : section Schema/Attributes).

Schéma User — ajouter :

  • uidNumber (entier)
  • gidNumber (entier)
  • homeDirectory (chaîne) — mettre le chemin réel ex. /home/francois
  • unixShell (chaîne, optionnel)

Schéma Group — ajouter :

  • gidNumber (entier)

Puis remplir ces attributs pour chaque user et groupe (valeurs du tableau ci-dessus). Note : unixShell et sshPublicKey sont optionnels ; tous les autres doivent être renseignés pour chaque user/groupe utilisé par sssd.

2. Compte bind (lecture seule)

Créer dans LLDAP un user binduser membre du groupe lldap_strict_readonly (pas l'admin, pour limiter les droits). Noter son mot de passe → ira dans sssd.conf.

3. Distribuer le certificat CA

Copier /mnt/stockage/docker/data/lldap/ca-cert.pem du serveur vers chaque portable (sssd doit faire confiance au CA auto-signé).

4. Installer sssd sur le portable Debian (lat7400)

sudo apt install -y sssd sssd-tools libnss-sss libpam-sss libsss-sudo

5. Configurer sssd

/etc/sssd/sssd.conf (permissions 600), schéma rfc2307bis, basé sur l'exemple officiel LLDAP pour PAM. Points clés :

[sssd]
services = nss, pam
domains = beafrancois.fr
 
[domain/beafrancois.fr]
id_provider = ldap
auth_provider = ldap
chpass_provider = ldap
access_provider = permit
enumerate = True
cache_credentials = True
offline_credentials_expiration = 0    # OFFLINE ILLIMITÉ (exigence fondamentale)
 
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/certs/lldap-ca.pem    # le ca-cert.pem copié
ldap_tls_reqcert = demand
 
# users
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
ldap_user_shell = unixShell
 
# groups
ldap_group_search_base = ou=groups,dc=beafrancois,dc=fr?subtree?(gidNumber=*)
ldap_group_object_class = posixGroup

Puis :

sudo chmod 600 /etc/sssd/sssd.conf
sudo systemctl enable --now sssd
sudo pam-auth-update    # cocher "create home dir" + sss

6. Valider (l'enjeu)

  1. Résolution : getent passwd testldap / id testldap
  2. Login en ligne : su - testldap puis ssh testldap@localhost
  3. Login OFFLINE : se connecter une fois en ligne, couper le réseau, re-tester. C'est le point qui a fait échouer Kanidm — le valider impérativement avant de basculer les vrais comptes.

7. Ne PAS désactiver kanidm-unixd avant validation

Garder le client Kanidm en place sur le portable jusqu'à ce que sssd soit validé (offline compris), comme filet de sécurité.

Sécurité / notes

  • offline_credentials_expiration = 0 (illimité) répond à l'exigence, mais : un portable volé et jamais reconnecté garde un cache valable indéfiniment. Mitiger avec chiffrement disque LUKS sur les portables.
  • Le port LDAP clair (3890) n'est jamais exposé hors du serveur ; seul le LDAPS (6360) l'est.
  • Compte bind en lecture seule (lldap_strict_readonly), pas l'admin.
  • Auth des serveurs (principal + proxy) : ne PAS passer par LLDAP/sssd — garder compte local + clé SSH.
  • WiFi 192.168.115.x : redirection spécifique à mettre en place pour joindre auth.beafrancois.fr.

Accès distant (hors LAN) — à traiter séparément

Pour les portables hors LAN : WireGuard (prévu aussi pour les partages réseau). Le LDAPS reste fermé au WAN ; le offline sssd gère le “aucun réseau”, WireGuard gère le “réseau distant” (provisionnement / rafraîchissement du cache).

commun/serveur_d_authentification_lldap_sssd.1782192168.txt.gz · Dernière modification : de francois

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki