LDAP directories store users, groups and their attributes in one central place, so many applications (Nextcloud, GitLab, Gitea, Jenkins, mail servers, VPNs, Authelia, Keycloak) can authenticate against the same accounts. OpenLDAP (slapd) is the classic open-source LDAP server. This guide sets up a small directory for your apps.

Before you start: OpenLDAP is powerful, but its configuration (cn=config, LDIF) has a learning curve. For many small teams, a modern identity provider with a built-in user store (Keycloak, Authentik, or LLDAP, a lightweight LDAP server with a web UI) is simpler. See Keycloak.

Install

sudo apt update
sudo apt install slapd ldap-utils
sudo dpkg-reconfigure slapd

The reconfigure dialog asks for:

  • DNS domain → example.com (becomes the base DN dc=example,dc=com);
  • organisation name;
  • admin password (for cn=admin,dc=example,dc=com);
  • the database backend (MDB is the default).

Check it:

sudo ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b cn=config dn | head
ldapsearch -x -H ldap://localhost -b dc=example,dc=com

Create the structure: OUs, users and groups

base.ldif:

dn: ou=people,dc=example,dc=com
objectClass: organizationalUnit
ou: people

dn: ou=groups,dc=example,dc=com
objectClass: organizationalUnit
ou: groups

users.ldif:

dn: uid=alice,ou=people,dc=example,dc=com
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
uid: alice
cn: Alice Smith
sn: Smith
givenName: Alice
mail: [email protected]
uidNumber: 10001
gidNumber: 10001
homeDirectory: /home/alice
loginShell: /bin/bash

dn: cn=developers,ou=groups,dc=example,dc=com
objectClass: groupOfNames
cn: developers
member: uid=alice,ou=people,dc=example,dc=com

Load them, and set a password:

ldapadd -x -D cn=admin,dc=example,dc=com -W -f base.ldif
ldapadd -x -D cn=admin,dc=example,dc=com -W -f users.ldif
ldappasswd -x -D cn=admin,dc=example,dc=com -W -S uid=alice,ou=people,dc=example,dc=com

Many apps use groupOfNames with a member attribute for group membership. Enable the memberOf overlay, so users get a memberOf attribute that apps can filter on.

Search and test

ldapsearch -x -H ldap://localhost -b dc=example,dc=com "(uid=alice)"
ldapwhoami -x -H ldap://localhost -D uid=alice,ou=people,dc=example,dc=com -W

Encrypt connections: LDAPS / StartTLS

Never send LDAP binds (passwords) over the network unencrypted. Get a certificate for ldap.example.com (Let’s Encrypt), copy it where openldap can read it, and configure it:

dn: cn=config
changetype: modify
replace: olcTLSCertificateFile
olcTLSCertificateFile: /etc/ldap/certs/fullchain.pem
-
replace: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/ldap/certs/privkey.pem
sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f tls.ldif

Enable ldaps:/// in /etc/default/slapd (SLAPD_SERVICES="ldap:/// ldapi:/// ldaps:///"), restart slapd, and test with ldapsearch -H ldaps://ldap.example.com -x …. Automate certificate copies on renewal with a Certbot deploy hook. See Let’s Encrypt.

Access control and binding

  • Create a read-only service account (e.g. cn=readonly,dc=example,dc=com) for applications to search the directory. Don’t give apps the admin DN.
  • Set ACLs (olcAccess) so users can change their own password, the service account can read but not see password hashes, and everything else is restricted.
  • Firewall: allow 389 and 636 only from your application servers or a VPN. Never expose LDAP to the whole internet. See UFW.

Connect applications

Typical settings in an app’s LDAP configuration:

Setting Example
Server ldaps://ldap.example.com:636
Bind DN cn=readonly,dc=example,dc=com
User base ou=people,dc=example,dc=com
User filter (&(objectClass=inetOrgPerson)(uid=%s))
Group filter (memberOf=cn=developers,ou=groups,dc=example,dc=com)

Linux logins against LDAP use SSSD.

Management tools

  • phpLDAPadmin or LDAP Account Manager (LAM): web UIs. Protect them behind authentication or a VPN.
  • Apache Directory Studio: a desktop LDAP browser.

Backups

sudo slapcat -n 0 > /backups/ldap-config-$(date +%F).ldif     # configuration
sudo slapcat -n 1 > /backups/ldap-data-$(date +%F).ldif       # directory data

Restore with slapadd (with slapd stopped). See backup strategy.

Quick reference

Task Command
Reconfigure sudo dpkg-reconfigure slapd
Add entries ldapadd -x -D cn=admin,… -W -f file.ldif
Search ldapsearch -x -b dc=example,dc=com "(uid=alice)"
Set password ldappasswd -x -D cn=admin,… -W -S uid=…
Modify config ldapmodify -Y EXTERNAL -H ldapi:/// -f file.ldif
Back up slapcat -n 0 / slapcat -n 1

Related: Authelia and least privilege.

  • Linux
  • Authentication
  • Self-Hosting