LDAP et mise en place d'une authentification unique
Je galère alors faut pas espérer que ce tuto soit au poil.
Il y a longtemps, on1) a écrit Authentification unique. Un seul endroit où s'identifier, ça reste important, mais ce n'est vraiment pas un sujet trivial.
Après moult pérégrinations, installations, désinstallation de rage, serveurs qui passent au lance-flamme etc, nous2) repartons sur cette aventure frustrante, fortes de plus d'expérience.
Tout commence par LDAP
LDAP est un service très basique d'annuaire. Oui, comme les gros machins en papier qui listaient les noms, prénoms, adresse, numéro de téléphone voir métier.
C'est bien la seule chose de basique, parce que ça se corse très vite.
Donc, il y a généralement un backend LDAP qui stocke les informations, et un frontend qui permet de les manipuler (idéalement une interface web).
Nous avons testé divers trucs, cette fois ce sera LLDAP.
LLDAP
La bonne nouvelle c'est qu'il y a un paquet Debian, bien que ce ne soit pas dans les dépôts officiels. C'est plutôt un avantage dans ce cas précis, car plus à jour.
Pour l'installer on va sur https://software.opensuse.org//download.html?project=home%3AMasgalor%3ALLDAP&package=lldap (adresse donnée dans le README du dépôt officiel) et on suit les instructions, que je recopie ici mais qu'il faudra vérifier si vous suivez ce tuto dans quelques mois :
echo 'deb http://download.opensuse.org/repositories/home:/Masgalor:/LLDAP/Debian_12/ /' | sudo tee /etc/apt/sources.list.d/home:Masgalor:LLDAP.list curl -fsSL https://download.opensuse.org/repositories/home:Masgalor:LLDAP/Debian_12/Release.key | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/home_Masgalor_LLDAP.gpg > /dev/null sudo apt update sudo apt install lldap
La configuration se fait ensuite sur /etc/lldap/lldap_config.toml
. Tout lire et pester un peu. Notre version commentée sera sans doute ici à un moment, quand j'aurais la foi pour l'y mettre et mieux comprendre ce que j'ai mis.
Veillez à installer tout ça sur un container sans apache/nginx. LLDAP se débrouille tout seul.
Ensuite, tout simplement :
sudo lldap run
Rendez-vous sur l'adresse de votre site et hop : ça marche, vous avez une interface web pour bidouiller un annuaire LDAP. Ce qui vous fais une belle jambe à ce stade.
En cas d'erreur
J'avais bidouillé encore et encore, et à un moment j'ai eu l'erreur suivante :
Error: A key_seed was given, but a key file already exists at `server_key`. Which one to use is ambiguous, aborting.
Il ne dit évidement pas où est ce “server_key” et malgré la purge du paquet, le reboot, etc, ça reste. Faites la commande suivante :
sudo find / -name "server_key" 2>/dev/null
Dans mon cas, j'avais lancé LLDAP avec mon user de base, et ce fichier était dans mon home…
Comprendre un annuaire
Histoire de créer les bons groupes etc.
LDAP est une norme d'annuaire. Il faut comprendre son modèle de nommage et d'organisation avant de le bidouiller.
Il fonctionne selon un modèle hiérarchique, et c'est souvent plus compréhensible de le représenter en schéma (en “arbre”) que de façon linéaire.
Voici une représentation :
dc=example,dc=org ├── ou=users │ ├── uid=arina.aldoru,ou=users,dc=example,dc=org │ ├── uid=benvai.brisin,ou=users,dc=example,dc=org ├── ou=groups │ ├── cn=admin,ou=groups,dc=example,dc=org │ ├── cn=joueuses,ou=groups,dc=example,dc=org
Attributs
Chaque donnée dans l'annuaire est un objet (par exemple, une identité), à laquelle divers attributs sont reliés. Ces attributs et la façon dont ils sont reliés aux objets obéit à une syntaxe particulière. Les attributs par défaut montrent à quel point LDAP est héritier d'une culture impérialiste bien précise. Mais bon, on peut quand même l'adapter à nos besoins et ajouter des attributs pour améliorer les choses. Et on peut supprimer ce qui ne nous sert pas, tant que ce n'est pas requis par la classe d'objet (cf chapitre suivant).
Ce qui suit n'est pas exhaustif. C'est juste le plus commun dans ce qu'on peut croiser.
Organisation et groupes
dc
(Domain Component) : le nom de domaine. Un attribut pour chaque composant individuel (un mot, quoi), ainsi on auradc=example,dc=org
et nondc=example.org
: il faut diviser example.org en composants distinct.o
(Organization) : identifie le nom de l'organisation dans l'annuaire. Il peut y avoir plusieurs organisations et les gens faire partie de plusieurs.ou
(Organizational Unit) : “unité organisationnelle”. Par exemple des groupes, des utilisatrices, des ressources. Dit autrement : “un tas de trucs”. Il y a des mots-clefs pour cet attribut qui sont “standards”, mais on peut en avoir d'autres et mettre ce qu'on veut en valeur :ou=Groups
est standards pour les groupes mais on peut l'écrire en français. Cependant il faut rester cohérent. Et si l'annuaire est destiné à un public international, le mettre en français n'est pas forcément pertinent. Préférez le lojbanmember
oumemberOf
: Membre d'un groupe. Va établir des relations entre utilisatrices et groups.
Identification des personnes :
cn
(Common Name) : un nom commun, donc pour désigner une personne ou un objet spécifique (tel que “OrdiBureau”).sn
(Surname) : non, pas “surnom, c'est de l'anglais. C'est le nom de famille.givenName
: prénom.mail
: l'adresse mail de l'objet.uid
(User Identifier) : identifiant unique pour un utilisateur. Pratique quand vous avez plusieurs Jean Dupont dans le groupe. C'est aussi ce code qu'on va utiliser pour l'authentification.- additionalName : quand il y a plus d'un nom (clan, famille élargie…).
- prefix/suffix : pour les titres, préfixes et suffixes honorifiques (mr, mme, docteur, etc).
- name : champ plus générique pour le nom
- preferredName / displayName : spécifie le nom à afficher
- Il existe encore d'autres attributs possible…
Localisation :
c
(Country) : le pays.l
(Locality) : localité, ville. Pour localiser un peu plus.st
(State) : État ou Province. On reste dans de la description géographique.
Autre
objectClass
: Classe d'objet. Définit des règles pour l'entrée, par exempleobjectClass=inetOrgPerson
pour un objet de type utilisatrice.
Classes d'objets
Les classes d'objets définissent les types d'entrées (ou objets) et les attributs associés à chaque type. Par exemple, quand on a un humain dans la base, on attend en général de pouvoir lui donner un nom et un identifiant.
Il n'y a pas d'attributs strictement obligatoires dans LDAP, mais certaines classes d'objets imposent des attributs minimaux pour une entrée valide.
Je ne vais pas tout lister, c'est juste pour pointer les conventions/attendus :
inetOrgPerson
(pour les personnes) :- Obligatoires :
cn
,uid
,sn
(parfois optionnel mais… faut pas y compter) - Recommandés :
givenName
,mail
,displayName
,telephoneNumber
organizationalUnit
(pour les unité organisationnelle)- Obligatoire :
ou
- Recommandés :
description
groupOfNames
:- Obligatoires :
cn
,member
organizationalRole
(rôles organisationnels comme administrateur, etc.)- Obligatoires :
cn
,description
Et se poursuit avec (Oauth2 ? OpenID ?)
La plupart des logiciels peuvent utiliser directement les informations de LDAP : il suffit de renseigner l'adresse de l'annuaire, sa structure etc et hop : vos utilisatrices peuvent se connecter avec les mêmes identifiants et phrase de passe partout. Ce qui est pratique mais n'enlève pas l'agacement de se connecter sur 10 CMS différents.
Pour ça, on ajoute une surcouche à LDAP. Il existe énormément de méthodes, mais Oauth2 est sans doute celui qui sera le mieux reconnu par les divers CMS et le plus souple.
C'est des concepts bien velus, mais heureusement quelqu'un a réussi à expliquer ça bien dans une vidéo, avec une très bonne métaphore : concernant les accès dans un hôtel. C'est vraiment une ressource à voir pour se sentir un peu moins dépassé !
Par contre LLDAP ne suffit pas à gérer ça. Il faut installer un autre frontend qui va aussi avoir en backend de quoi servir Oauth2. On va donc avoir un serveur Oauth2, qui va papoter avec notre serveur LDAP, qui vont permettre (ou pas) aux utilisatrices de se connecter d'office une fois qu'elles ont été identifiée à un moment.
Il y a plusieurs options, et je n'y suis pas encore, mais dans les concurrents :
- https://kanidm.com/ : semble léger, en rust, y'en a ici qui l'aiment bien ;)
- LemonLDAP::NG ? J'ai un doute s'il fournit vraiment le serveur Oauth.
- Authelia : a l'air d'une terrible machine de guerre. Mais moins que Keyclock (et en même temps, peut-on faire plus affreux ?).
- Autre ?