Aller au contenu
English
Compte : non connecté, synchronisation possible Mon apprentissage
Selectionner le thème
English

Monter un annuaire LDAP léger avec LLDAP

Par mis à jour le

Améliorer cette page

Cette leçon monte LLDAP, un serveur d'annuaire LDAP léger, et vérifie avec ldapsearch qu'il répond. C'est l'annuaire de test du module « Fédération et annuaires » : vous l'installez ici, puis Keycloak s'y branche. Le protocole LDAP (Lightweight Directory Access Protocol) sert à centraliser les comptes et à les partager entre services, mais OpenLDAP ou 389 Directory Server demandent une configuration lourde. LLDAP se limite à l'essentiel, pour les petites équipes et les laboratoires.

  • Situer LLDAP face à OpenLDAP et à Active Directory
  • Installer LLDAP sur Ubuntu 24.04 et générer un certificat TLS de test
  • Configurer le serveur (base DN, compte d'administration, LDAPS) et le démarrer
  • Interroger l'annuaire avec ldapsearch et relever les classes et attributs que Keycloak aura à connaître

Pourquoi LLDAP plutôt qu'un serveur LDAP classique ?

Section intitulée « Pourquoi LLDAP plutôt qu'un serveur LDAP classique ? »

Le protocole LDAP a été conçu dans les années 1990 pour centraliser les utilisateurs, les groupes et les droits d'accès. Des serveurs comme OpenLDAP ou Microsoft Active Directory répondent encore aux besoins des grandes entreprises, mais leur complexité est disproportionnée pour une petite équipe qui veut seulement un annuaire pour quelques utilisateurs.

LLDAP est né de ce constat : proposer un annuaire léger, rapide et facile à mettre en place. Avec l'adoption des conteneurs et des microservices, il fallait un serveur LDAP moderne, qui se déploie en quelques minutes et s'intègre facilement à des fournisseurs d'identité comme Keycloak. Son succès tient, à mon avis, à son approche minimaliste, un exemple du principe KISS (Keep It Simple, Stupid) : il fait ce dont on a besoin, sans surplus.

LLDAP ne cherche pas à réinventer la roue, mais à simplifier son utilisation : une solution légère et moderne pour la gestion des annuaires LDAP, qui conserve les standards du protocole. Voici ce qui en fait un choix intéressant :

  • Léger et performant : Avec un backend basé sur SQLite, LLDAP est optimisé pour être léger tout en restant performant. Pas besoin d’une infrastructure massive pour le faire tourner : il peut s’exécuter sur une petite machine ou un conteneur avec un minimum de ressources.
  • Simplicité de déploiement et de configuration : Contrairement à des solutions plus lourdes comme OpenLDAP, LLDAP brille par sa facilité de mise en place. Que vous l’installiez localement ou via un conteneur Docker ou Podman, tout est pensé pour être opérationnel en quelques minutes. Fini les heures passées à éplucher des manuels ou des fichiers de configuration interminables !
  • Interface Web intégrée : C’est un vrai point fort : LLDAP propose une interface Web simple et intuitive pour gérer vos utilisateurs et groupes. Pas besoin de connaître par cœur les commandes LDAP ou de manipuler les fichiers de manière manuelle. Tout se fait via un navigateur et en quelques clics.
  • Chiffrement TLS : LLDAP prend en charge TLS (LDAPS) pour chiffrer les communications. Sa mise en place est décrite plus bas, avec la limite rencontrée lors du test.
  • Compatibilité avec les outils standards LDAP : Même si LLDAP est conçu pour la simplicité, il reste compatible avec les outils et bibliothèques LDAP classiques. Vous pouvez continuer à utiliser des commandes comme ldapsearch ou des bibliothèques Python pour interagir avec lui.

En résumé, LLDAP se démarque par sa modernité, sa légèreté et son adaptabilité. Pour moi, il incarne l'équilibre entre la puissance d'un serveur LDAP et la simplicité d'un outil pensé pour les équipes agiles.

LLDAP s'installe directement sur le système à partir d'un dépôt de paquets : cette installation sans conteneur garde l'exemple lisible. Elle cible Ubuntu 24.04, dont le dépôt est utilisé à l'étape 2 ; sous Debian, adaptez l'URL du dépôt à votre version.

  1. Installation des pré-requis : Avant de commencer, assurez-vous d’avoir les éléments suivants :

    • SQLite3 : LLDAP utilise SQLite comme backend par défaut, donc assurez-vous qu’il est installé. Par exemple, sous Debian/Ubuntu :

      Fenêtre de terminal
      sudo apt update && sudo apt install sqlite3 libsqlite3-dev
    • mkcert : Pour générer des certificats TLS auto-signés, vous aurez besoin de mkcert. Installez-le avec :

      Fenêtre de terminal
      sudo apt install mkcert
    • les outils ldap : Pour tester votre serveur LDAP, vous aurez besoin de ldapsearch. Installez-le avec :

      Fenêtre de terminal
      sudo apt install ldap-utils
  2. Installation de LLDAP : Une fois les pré-requis en place, installez directement LLDAP avec la commande suivante :

    Fenêtre de terminal
    curl -fsSL https://download.opensuse.org/repositories/home:Masgalor:LLDAP/xUbuntu_24.04/Release.key | \
    gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/lldap.gpg > /dev/null
    echo "deb http://download.opensuse.org/repositories/home:/Masgalor:/LLDAP/xUbuntu_24.04/ /" | \
    sudo tee /etc/apt/sources.list.d/home:Masgalor:LLDAP.list > /dev/null
    sudo apt update
    sudo apt install lldap
  3. Une fois l’installation terminée, vérifiez que LLDAP est correctement installé avec :

Fenêtre de terminal
lldap --version

Vous devriez voir une version s’afficher, confirmant que tout est en place.

Pour chiffrer les communications avec votre serveur LDAP, générez un certificat TLS auto-signé avec mkcert, l'outil installé à l'étape 1. Son installation et sa configuration sont détaillées dans cet article sur mkcert. Le nom ldap.robert.local est celui du lab : remplacez-le par le vôtre.

Voici comment procéder :

  1. Générez le certificat TLS pour votre serveur LDAP :
Fenêtre de terminal
cd ~
mkcert 'ldap.robert.local' localhost 127.0.0.1 ::1
  1. Installez le certificat dans un répertoire appartenant à l’utilisateur LLDAP :
Fenêtre de terminal
sudo mkdir /etc/lldap/certs
sudo mv ~/ldap.robert.local+3-key.pem /etc/lldap/certs/lldap.key
sudo mv ~/ldap.robert.local+3.pem /etc/lldap/certs/lldap.pem
sudo chown -R lldap:lldap /etc/lldap/certs

Le fichier de configuration de LLDAP est au format TOML et contient plusieurs paramètres pour personnaliser le serveur. Voici le contenu de mon fichier :

## Tune the logging to be more verbose by setting this to be true.
## You can set it with the LLDAP_VERBOSE environment variable.
# verbose=false
## The host address that the LDAP server will be bound to.
## To enable IPv6 support, simply switch "ldap_host" to "::":
## To only allow connections from localhost (if you want to restrict to local self-hosted services),
## change it to "127.0.0.1" ("::1" in case of IPv6)".
#ldap_host = "0.0.0.0"
## The port on which to have the LDAP server.
#ldap_port = 3890
## The host address that the HTTP server will be bound to.
## To enable IPv6 support, simply switch "http_host" to "::".
## To only allow connections from localhost (if you want to restrict to local self-hosted services),
## change it to "127.0.0.1" ("::1" in case of IPv6)".
#http_host = "0.0.0.0"
## The port on which to have the HTTP server, for user login and
## administration.
#http_port = 17170
## The public URL of the server, for password reset links.
#http_url = "http://localhost"
## Random secret for JWT signature.
## This secret should be random, and should be shared with application
## servers that need to consume the JWTs.
## Changing this secret will invalidate all user sessions and require
## them to re-login.
## You should probably set it through the LLDAP_JWT_SECRET environment
## variable from a secret ".env" file.
## This can also be set from a file's contents by specifying the file path
## in the LLDAP_JWT_SECRET_FILE environment variable
## You can generate it with (on linux):
## LC_ALL=C tr -dc 'A-Za-z0-9!#%&'\''()*+,-./:;<=>?@[\]^_{|}~' </dev/urandom | head -c 32; echo ''
#jwt_secret = "REPLACE_WITH_RANDOM"
## Base DN for LDAP.
## This is usually your domain name, and is used as a
## namespace for your users. The choice is arbitrary, but will be needed
## to configure the LDAP integration with other services.
## The sample value is for "example.com", but you can extend it with as
## many "dc" as you want, and you don't actually need to own the domain
## name.
ldap_base_dn = "dc=robert,dc=local"
## Admin username.
## For the LDAP interface, a value of "admin" here will create the LDAP
## user "cn=admin,ou=people,dc=example,dc=com" (with the base DN above).
## For the administration interface, this is the username.
ldap_user_dn = "admin"
## Admin email.
## Email for the admin account. It is only used when initially creating
## the admin user, and can safely be omitted.
ldap_user_email = "admin@example.com"
## Admin password.
## Password for the admin account, both for the LDAP bind and for the
## administration interface. It is only used when initially creating
## the admin user.
## It should be minimum 8 characters long.
## You can set it with the LLDAP_LDAP_USER_PASS environment variable.
## This can also be set from a file's contents by specifying the file path
## in the LLDAP_LDAP_USER_PASS_FILE environment variable
## Note: you can create another admin user for user administration, this
## is just the default one.
ldap_user_pass = "changeme"
## Force reset of the admin password.
## Break glass in case of emergency: if you lost the admin password, you
## can set this to true to force a reset of the admin password to the value
## of ldap_user_pass above.
## Alternatively, you can set it to "always" to reset every time the server starts.
force_ldap_user_pass_reset = false
## Database URL.
## This encodes the type of database (SQlite, MySQL, or PostgreSQL)
## , the path, the user, password, and sometimes the mode (when
## relevant).
## Note: SQlite should come with "?mode=rwc" to create the DB
## if not present.
## Example URLs:
## - "postgres://postgres-user:password@postgres-server/my-database"
## - "mysql://mysql-user:password@mysql-server/my-database"
##
## This can be overridden with the LLDAP_DATABASE_URL env variable.
database_url = "sqlite:///var/lib/lldap/users.db?mode=rwc"
## Private key file.
## Not recommended, use key_seed instead.
## Contains the secret private key used to store the passwords safely.
## Note that even with a database dump and the private key, an attacker
## would still have to perform an (expensive) brute force attack to find
## each password.
## Randomly generated on first run if it doesn't exist.
## Env variable: LLDAP_KEY_FILE
#key_file = "/var/lib/lldap/private_key"
## Seed to generate the server private key, see key_file above.
## This can be any random string, the recommendation is that it's at least 12
## characters long.
## Env variable: LLDAP_KEY_SEED
key_seed = "RanD0m STR1ng"
## Ignored attributes.
## Some services will request attributes that are not present in LLDAP. When it
## is the case, LLDAP will warn about the attribute being unknown. If you want
## to ignore the attribute and the service works without, you can add it to this
## list to silence the warning.
#ignored_user_attributes = [ "sAMAccountName" ]
#ignored_group_attributes = [ "mail", "userPrincipalName" ]
## Options to configure SMTP parameters, to send password reset emails.
## To set these options from environment variables, use the following format
## (example with "password"): LLDAP_SMTP_OPTIONS__PASSWORD
[smtp_options]
## Whether to enabled password reset via email, from LLDAP.
#enable_password_reset=true
## The SMTP server.
#server="smtp.gmail.com"
## The SMTP port.
#port=587
## How the connection is encrypted, either "NONE" (no encryption), "TLS" or "STARTTLS".
#smtp_encryption = "TLS"
## The SMTP user, usually your email address.
#user="sender@gmail.com"
## The SMTP password.
#password="password"
## The header field, optional: how the sender appears in the email. The first
## is a free-form name, followed by an email between <>.
#from="LLDAP Admin <sender@gmail.com>"
## Same for reply-to, optional.
#reply_to="Do not reply <noreply@localhost>"
## Options to configure LDAPS.
## To set these options from environment variables, use the following format
## (example with "port"): LLDAP_LDAPS_OPTIONS__PORT
[ldaps_options]
## Whether to enable LDAPS.
enabled=true
## Port on which to listen.
port=6360
## Certificate file.
cert_file="/etc/lldap/certs/lldap.pem"
## Certificate key file.
key_file="/etc/lldap/certs/lldap.key"

Les valeurs de cet exemple sont celles du lab, à remplacer par les vôtres. Quatre réglages comptent pour la suite de la leçon : ldap_base_dn fixe la racine de l'annuaire (dc=robert,dc=local), ldap_user_dn et ldap_user_pass définissent le compte administrateur, et la section [ldaps_options] active LDAPS sur le port 6360 avec le certificat généré plus haut. Avant tout usage hors lab, remplacez changeme et le key_seed d'exemple, et décommentez jwt_secret avec une valeur aléatoire fournie en variable d'environnement, jamais écrite dans un dépôt Git.

Pour démarrer LLDAP, utilisez la commande suivante :

Fenêtre de terminal
sudo systemctl enable lldap --now

Vous pouvez vérifier que le serveur est en cours d’exécution avec :

Fenêtre de terminal
sudo systemctl status lldap

Vous pouvez également consulter les journaux pour voir les messages de démarrage :

Fenêtre de terminal
journalctl -u lldap

Vérifiez que le serveur est bien en écoute sur les ports 3890 (LDAP), 6360 (LDAPS) et 17170 (interface Web) :

Fenêtre de terminal
sudo ss -tulnp | grep lldap
tcp LISTEN 0 2048 0.0.0.0:6360 0.0.0.0:* users:(("lldap",pid=995582,fd=11))
tcp LISTEN 0 2048 0.0.0.0:3890 0.0.0.0:* users:(("lldap",pid=995582,fd=10))
tcp LISTEN 0 2048 0.0.0.0:17170 0.0.0.0:* users:(("lldap",pid=995582,fd=12))

L'interface Web de LLDAP est accessible sur http://localhost:17170 : connectez-vous avec les identifiants d'administration configurés (ldap_user_dn et ldap_user_pass). Vous pourrez y ajouter des utilisateurs et des groupes, et gérer les paramètres du serveur.

Interface Web de LLDAP

Pour vous assurer que LLDAP fonctionne, interrogez l'annuaire avec ldapsearch. Les options à connaître : -H donne l'URL du serveur (port 3890, LDAP en clair), -D le DN du compte qui se connecte (le bind), -w son mot de passe (à ne jamais passer ainsi hors lab : il reste visible dans l'historique et la liste des processus) et -b la base de recherche. Attention : la commande ci-dessous vise la base dc=robert,dc=local de cette leçon, mais la sortie qui suit a été capturée sur un annuaire de base par défaut, dc=example,dc=com, d'où l'écart entre les DN de la commande et ceux du résultat :

Fenêtre de terminal
ldapsearch -H ldap://localhost:3890 -D "uid=admin,ou=people,dc=robert,dc=local" -w "changeme" -b "dc=robert,dc=local" "(objectClass=*)"
# extended LDIF
#
# LDAPv3
# base <dc=example,dc=com> with scope subtree
# filter: (objectClass=*)
# requesting: ALL
#
# admin, people, example.com
dn: uid=admin,ou=people,dc=example,dc=com
cn: Administrator
createtimestamp: 2025-01-27T13:56:43.252453685+00:00
entryuuid: 666964a9-a2d8-36ca-a19d-6149e3a5aac6
mail: admin@example.com
objectclass: inetOrgPerson
objectclass: posixAccount
objectclass: mailAccount
objectclass: person
uid: admin
# lldap_admin, groups, example.com
dn: cn=lldap_admin,ou=groups,dc=example,dc=com
cn: lldap_admin
entryuuid: 2dbd571f-e20a-3195-ad85-51fa1232e20c
member: uid=admin,ou=people,dc=example,dc=com
objectclass: groupOfUniqueNames
uid: lldap_admin
uniquemember: uid=admin,ou=people,dc=example,dc=com
# lldap_password_manager, groups, example.com
dn: cn=lldap_password_manager,ou=groups,dc=example,dc=com
cn: lldap_password_manager
entryuuid: 094c5f0d-2a80-3192-935c-38f3912fd41d
objectclass: groupOfUniqueNames
uid: lldap_password_manager
# lldap_strict_readonly, groups, example.com
dn: cn=lldap_strict_readonly,ou=groups,dc=example,dc=com
cn: lldap_strict_readonly
entryuuid: c37db72c-e43c-3ca4-a150-97484638d1c1
objectclass: groupOfUniqueNames
uid: lldap_strict_readonly
# search result
search: 2
result: 0 Success
control: 1.2.840.113556.1.4.319 false MAUCAQQEAA==
pagedresults: estimate=4 cookie=
# numResponses: 5
# numEntries: 4

Le bind réussit et l'annuaire liste l'administrateur et trois groupes prédéfinis : lldap_admin, lldap_password_manager et lldap_strict_readonly. Comme annoncé, la sortie vient d'un annuaire de base par défaut dc=example,dc=com ; avec la configuration de cette leçon, tous les DN se terminent par dc=robert,dc=local.

Que retenir de la sortie avant de brancher Keycloak ?

Section intitulée « Que retenir de la sortie avant de brancher Keycloak ? »

La leçon Fédérer un annuaire LDAP ou AD avec Keycloak prend OpenLDAP en exemple et explique chaque réglage côté Keycloak. Elle n'a pas été rejouée contre LLDAP : les valeurs exactes à saisir dans Keycloak ne sont donc pas données ici. Ce que cette leçon établit, c'est ce que votre annuaire LLDAP expose réellement, et la sortie de ldapsearch ci-dessus le montre :

Ce que la sortie montreValeur observée
Utilisateursrangés sous ou=people, avec l'attribut uid (par exemple uid=admin)
Classes d'objet d'un utilisateurinetOrgPerson, posixAccount, mailAccount, person
Attributs d'un utilisateuruid, cn, mail, entryuuid (LDAP ne distingue pas les majuscules des noms d'attributs)
Groupesrangés sous ou=groups, de classe groupOfUniqueNames
Attributs de membre d'un groupemember et uniquemember sont tous deux présents sur lldap_admin
Ports en écoute3890 (LDAP), 6360 (LDAPS), 17170 (interface Web), vus dans la sortie de ss

Pour paramétrer le provider de fédération, comparez ces observations aux champs décrits dans la leçon de fédération (DN des utilisateurs, attribut d'identifiant, UUID, classes d'objet, groupes). Les groupes LLDAP sont de classe groupOfUniqueNames, là où la leçon de fédération cite groupOfNames pour OpenLDAP : c'est un point à contrôler en jouant l'intégration, pas une valeur à recopier. Le base DN de votre annuaire remplace celui de l'exemple.

LLDAP convient aux petites équipes, aux laboratoires et aux projets modestes : installation en quelques minutes, interface Web, compatibilité avec les outils LDAP standards. Il ne remplace ni OpenLDAP ni Active Directory dans une grande organisation, dont il n'a pas la richesse fonctionnelle. Dans cette formation, il sert d'annuaire de test à brancher sur Keycloak ; la leçon de fédération a été jouée avec OpenLDAP.

La référence reste le dépôt du projet : son README décrit les options de configuration du fichier TOML, les variables d'environnement équivalentes et les intégrations testées par la communauté avec d'autres services.

  • LLDAP est un serveur LDAP léger, avec une interface Web, adapté aux petites équipes et aux labs.
  • La racine de l'annuaire vient de ldap_base_dn ; le compte administrateur est uid=admin,ou=people,<base DN>.
  • Les ports par défaut sont 3890 (LDAP), 6360 (LDAPS) et 17170 (interface Web).
  • Les valeurs d'exemple (changeme, key_seed, jwt_secret) se remplacent avant tout usage hors lab.
  • LDAPS n'a pas été validé ici : en lab, LDAP en clair sur 3890, sur une machine isolée.
  • Dans la sortie observée, les groupes LLDAP sont de classe groupOfUniqueNames ; les réglages côté Keycloak sont dans la leçon de fédération, qui n'a pas été rejouée contre LLDAP.

Six questions tirées sur huit : la racine de l'annuaire, les ports de LLDAP, les options de ldapsearch, la classe des groupes, les valeurs d'exemple à remplacer et le contexte où LLDAP convient.

Contrôle de connaissances

Validez vos connaissances avec ce quiz interactif

6 questions
6 min.
70% requis

Informations

  • Le chronomètre démarre au clic sur Démarrer
  • Questions à choix multiples, vrai/faux et réponses courtes
  • Vous pouvez naviguer entre les questions
  • Les résultats détaillés sont affichés à la fin

Lance le quiz et démarre le chronomètre

Ce projet vous est utile ?

Les guides, formations, quiz et labs restent gratuits. Si vous les utilisez régulièrement, vous pouvez contribuer à leur maintenance et à leur développement.

Devenir membre de soutien (nouvel onglet) Soutenir une fois (nouvel onglet) En savoir plus

Suivez aussi le projet sur LinkedIn