Single Sign On using LDAP + Kerberos

De wiki.nexiat.fr
Aller à la navigation Aller à la recherche
Fiche express
Domaine SSO Unix via LDAP + Kerberos
Composants OpenLDAP (annuaire) + MIT Kerberos (KDC)
Principe LDAP fournit l'identité, Kerberos l'authentification
Voir aussi LDAP · Kerberos · Securiser apache

Ce mémo décrit la mise en place d'un single sign-on (SSO) Unix classique combinant LDAP pour l'annuaire des comptes/groupes et Kerberos pour l'authentification : l'utilisateur s'authentifie une seule fois (kinit) et obtient ensuite un accès transparent (sans nouveau mot de passe) aux services du domaine qui font confiance au ticket Kerberos — typiquement SSH via GSSAPI.

Principe général

  • LDAP répond à la question « qui est cet utilisateur ? » : UID, GID, répertoire
 personnel, shell, appartenance aux groupes.
  • Kerberos répond à la question « cet utilisateur est-il bien celui qu'il prétend
 être ? » : il émet des tickets chiffrés à durée de vie limitée, sans jamais faire transiter
 de mot de passe sur le réseau après l'authentification initiale.
  • En combinant les deux, on sépare la gestion des comptes (LDAP) de l'authentification
 (Kerberos) — le mot de passe LDAP peut même être supprimé une fois Kerberos opérationnel,
 pour forcer tous les clients à passer par Kerberos.

Topologie de l'exemple

Trois machines, à adapter à l'environnement réel :

Rôle Nom IP (exemple)
Serveur OpenLDAP ldap.example.local 192.0.2.16
KDC Kerberos kdc.example.local 192.0.2.18
Client client.example.local 192.0.2.20

Ajouter ces entrées dans /etc/hosts des trois machines, et vérifier que hostname -f renvoie bien le FQDN sur chacune — un prérequis souvent négligé qui casse silencieusement Kerberos plus loin (les tickets sont liés au FQDN).

Mise en place de l'annuaire LDAP

yum install openldap-servers openldap-clients
slappasswd    # génère le hash à coller dans rootpw
# /etc/openldap/slapd.conf (extrait)
database    bdb
suffix      "dc=example,dc=local"
rootdn      "cn=Manager,dc=example,dc=local"
rootpw      {SSHA}<hash généré par slappasswd>
systemctl enable --now slapd

Base de l'annuaire (organisation)

# base.ldif
dn: dc=example,dc=local
objectClass: domain
objectClass: top
dc: example

dn: ou=People,dc=example,dc=local
objectClass: organizationalUnit
objectClass: top
ou: People

dn: ou=Group,dc=example,dc=local
objectClass: organizationalUnit
objectClass: top
ou: Group

Utilisateurs et groupes d'exemple

# users.ldif
dn: uid=alice,ou=People,dc=example,dc=local
objectClass: shadowAccount
objectClass: posixAccount
objectClass: account
objectClass: top
cn: Alice Martin
gidNumber: 1000
homeDirectory: /home/alice
uid: alice
uidNumber: 1000
gecos: Alice Martin
loginShell: /bin/bash
userPassword:: <hash base64>

dn: cn=web,ou=Group,dc=example,dc=local
objectClass: posixGroup
objectClass: top
cn: web
gidNumber: 1005
description: Websites
memberUid: alice
ldapadd -x -W -D "cn=Manager,dc=example,dc=local" -f base.ldif
ldapadd -x -W -D "cn=Manager,dc=example,dc=local" -f users.ldif

Brancher l'authentification système sur LDAP

authconfig --enableldap --enableldapauth --enablemkhomedir \
  --ldapserver=ldap.example.local \
  --ldapbasedn="dc=example,dc=local" --update

(authconfig est l'outil historique RHEL/CentOS 5-6 — sur les versions récentes, utiliser authselect ou sssd directement, plus robustes et toujours maintenus.)

À ce stade, ssh alice@ldap.example.local fonctionne avec le mot de passe LDAP et crée automatiquement le répertoire personnel (--enablemkhomedir).

Synchronisation horaire (NTP)

Kerberos est sensible à la dérive d'horloge : par défaut, un décalage de plus de 5 minutes entre client et KDC fait rejeter les tickets. NTP est donc un prérequis, pas une option, sur les trois machines :

yum install ntp
systemctl enable --now ntpd

Configuration du KDC Kerberos

yum install krb5-server krb5-workstation

Pare-feu

Ouvrir uniquement les ports Kerberos nécessaires depuis le réseau local, avec politique DROP par défaut :

# Réseau local example : 192.0.2.0/24
iptables -A INPUT -s 192.0.2.0/24 -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -s 127.0.0.0/8 -j ACCEPT

iptables -N KDC
iptables -I INPUT -j KDC
iptables -A KDC -s 192.0.2.0/24 -p tcp --dport 88  -j ACCEPT -m comment --comment "kerberos"
iptables -A KDC -s 192.0.2.0/24 -p udp --dport 88  -j ACCEPT -m comment --comment "kerberos"
iptables -A KDC -s 192.0.2.0/24 -p udp --dport 464 -j ACCEPT -m comment --comment "kerberos (kpasswd)"
iptables -A KDC -s 192.0.2.0/24 -p tcp --dport 749 -j ACCEPT -m comment --comment "kerberos admin"
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -P INPUT DROP

service iptables save

(à vérifier selon distribution : iptables/service iptables save sont l'outillage RHEL/CentOS 6 — remplacés par firewalld sur RHEL7+, voir [[Securiser apache]] pour l'équivalent applicatif.)

Realm et KDC

# /etc/krb5.conf
[libdefaults]
 default_realm = EXAMPLE.LOCAL
 dns_lookup_realm = false
 dns_lookup_kdc = false
 ticket_lifetime = 24h
 forwardable = yes

[realms]
 EXAMPLE.LOCAL = {
  kdc = kdc.example.local:88
  admin_server = kdc.example.local:749
 }

[domain_realm]
 .example.local = EXAMPLE.LOCAL
 example.local = EXAMPLE.LOCAL
# /var/kerberos/krb5kdc/kdc.conf
[realms]
 EXAMPLE.LOCAL = {
  default_principal_flags = +preauth
  acl_file = /var/kerberos/krb5kdc/kadm5.acl
  admin_keytab = /var/kerberos/krb5kdc/kadm5.keytab
  supported_enctypes = aes256-cts:normal aes128-cts:normal
 }
# /var/kerberos/krb5kdc/kadm5.acl — accorde tous les droits à *_/admin_
*/admin@EXAMPLE.LOCAL	*

Créer la base et les principaux

kdb5_util create -r EXAMPLE.LOCAL -s
kadmin.local
kadmin.local:  addprinc root/admin
kadmin.local:  addprinc alice
kadmin.local:  ktadd -k /var/kerberos/krb5kdc/kadm5.keytab kadmin/admin
kadmin.local:  ktadd -k /var/kerberos/krb5kdc/kadm5.keytab kadmin/changepw
kadmin.local:  exit
systemctl enable --now krb5kdc kadmin

Copier /etc/krb5.conf vers les autres machines (LDAP et client) — tous les hôtes du realm doivent partager la même configuration Kerberos.

Principaux de service (host principals)

Chaque machine a besoin de son propre principal de service et de son keytab local, pour pouvoir s'authentifier auprès du KDC sans mot de passe (nécessaire côté serveur SSH pour valider les tickets présentés par les clients) :

# sur chaque machine (kdc, ldap, client), remplacer le FQDN par le sien
kadmin -p root/admin
kadmin:  addprinc -randkey host/<fqdn-de-la-machine>
kadmin:  ktadd host/<fqdn-de-la-machine>
kadmin:  exit

Basculer complètement sur Kerberos

Une fois Kerberos validé, supprimer le mot de passe LDAP de l'utilisateur pour rendre l'authentification par mot de passe LDAP impossible et forcer le passage par Kerberos :

# supprimer-mdp.ldif
dn: uid=alice,ou=People,dc=example,dc=local
changetype: modify
delete: userPassword
ldapmodify -x -W -D "cn=Manager,dc=example,dc=local" -f supprimer-mdp.ldif

Activer l'authentification Kerberos système :

authconfig --enablekrb5 --enablemkhomedir \
  --krb5kdc=kdc.example.local --krb5adminserver=kdc.example.local \
  --krb5realm=EXAMPLE.LOCAL --update

Vérification du SSO

kinit alice
klist

Une fois le ticket obtenu, la connexion aux machines du realm ne redemande plus de mot de passe — c'est le ticket Kerberos (via GSSAPI) qui authentifie automatiquement :

ssh alice@ldap.example.local
# plus de prompt de mot de passe : authentification GSSAPI transparente

Côté serveur SSH, la configuration doit autoriser GSSAPI :

# /etc/ssh/sshd_config
GSSAPIAuthentication yes
GSSAPICleanupCredentials yes
# /etc/ssh/ssh_config (côté client)
Host *
    GSSAPIAuthentication yes

Sur le KDC, le journal confirme l'émission du ticket de service au moment de la connexion SSH (TGS_REQ pour host/<fqdn>), et sur le serveur SSH, /var/log/secure confirme l'authentification GSSAPI acceptée.

Références

Démarche initialement basée sur le tutoriel The Kerberos Haters Guide to Installing Kerberos (rackerhacker.com, 2012).

Voir aussi

  • LDAP — annuaire, gestion des comptes/groupes
  • Kerberos — protocole d'authentification
  • Securiser apache — durcissement système en général