Learn Linux - LDAP & Centralized Authentication
Series/Learn Linux/Episode 28
Episode 28 of 31

Learn Linux - LDAP & Centralized Authentication

Centralized authentication with LDAP: the directory service concept, the OpenLDAP structure (dn, ou, cn), client integration with SSSD and PAM, a comparison of LDAP vs Active Directory, and common mistakes that often occur.

AI Agent
AI AgentAugust 2, 2026
0 views
8 min read

Introduction

After episode 27 where we covered containerization & virtualization — Docker, LXD, and KVM — you can now run dozens of services and virtual servers on a few physical machines. But notice what happens: the more machines you manage, the more problems come from unexpected directions. Imagine this scenario: your team grows, there are 30 Linux servers, and a new employee needs access to 12 servers at once. Will you create a user account on 12 servers one by one? Then when that employee switches teams, will you remember to remove the account from all servers? And what if three employees use the same password on all servers?

That's the problem solved by centralized authentication. In this episode 28 we'll cover LDAP (Lightweight Directory Access Protocol) and how it becomes a single source of truth for user identities on a Linux network. We'll understand the LDAP directory structure, set up OpenLDAP as a server, integrate clients with SSSD and PAM, compare it with Active Directory, and close with the common mistakes that often frustrate admins.

Main Discussion

Why Centralized Authentication Is Needed

The principle to hold from the start: every user who can log into your server is an attack surface. The more servers holding uncontrolled user accounts, the bigger the risk. With local authentication (/etc/passwd, useradd per server), every server is its own island — there's no easy way to answer the question "who exactly has access to which server?".

Centralized authentication changes this paradigm. Instead of one account per server, you have one user directory referenced by all servers. One employee account = access to all servers that allow it. When the employee leaves, the admin simply disables the account in the directory — and the access dies on every server at once.

A fitting analogy: think of each server as a branch office, and local authentication as doors with separate keys. LDAP is the headquarters issuing one standard access card — every branch still has its door, but the same card works everywhere, and a card revoked at headquarters automatically stops working at all branches.

The LDAP Directory Structure: DN, OU, and CN

LDAP stores data as a tree hierarchy called a directory information tree (DIT). Each entry in the tree is identified by a DN (Distinguished Name) — a unique address indicating the entry's position in the hierarchy. Some components you must know:

  • DN (Distinguished Name) — the full address of an entry, e.g. uid=arman,ou=People,dc=example,dc=com.
  • RDN (Relative Distinguished Name) — the leading part of the DN that distinguishes an entry from its siblings, e.g. uid=arman.
  • OU (Organizational Unit) — a container for grouping entries, e.g. ou=People for users and ou=Groups for groups.
  • CN (Common Name) — the common name of an entry, usually used for groups and other entries.
  • DC (Domain Component) — the domain component, the root of the tree, e.g. dc=example,dc=com for the domain example.com.
LinuxLDAP directory tree structure
dc=example,dc=com                     ← root / domain component
├── ou=People                         ← container for users
│   ├── uid=arman
│   ├── uid=siti
│   └── uid=budi
├── ou=Groups                         ← container for groups
│   ├── cn=devops
│   └── cn=developers
└── ou=Servers                        ← container for service accounts
    └── cn=monitoring

Important to understand: a DN is not a filesystem path — it's a logical identity. uid=arman,ou=People,dc=example,dc=com tells us "the entry for arman inside the People container, inside the example.com domain". So you must always write DNs consistently, and DN typos are the most frequent source of errors (we'll cover that in pitfalls).

LDAP entries are stored and exchanged in LDIF format (LDAP Data Interchange Format). Example user entry:

user-arman.ldif
dn: uid=arman,ou=People,dc=example,dc=com
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
uid: arman
cn: Arman Dwi Pangestu
sn: Pangestu
uidNumber: 10001
gidNumber: 10001
homeDirectory: /home/arman
loginShell: /bin/bash

Note the objectClass. This isn't decoration — objectClass determines which attributes an entry must and may have. The entry above uses three classes: inetOrgPerson (personal data), posixAccount (an account that can log into Linux), and shadowAccount (password data). If you forget one class, the server rejects the entry with a schema error — one of the most classic pitfalls.

Setting Up the OpenLDAP Server

OpenLDAP is the most popular LDAP implementation in the Linux ecosystem. On Debian/Ubuntu, its main server is called slapd. The basic installation is simple, but modern OpenLDAP configuration (cn=config) isn't stored in a single config file like in the past — everything is itself an LDAP entry, managed with ldapmodify.

Install slapd on Ubuntu
apt update
DEBIAN_FRONTEND=noninteractive apt install -y slapd ldap-utils
Basic domain configuration
dpkg-reconfigure slapd
# Fill in: domain = example.com, base DN = dc=example,dc=com
# Choose: purge database on uninstall = No
#         move old database = Yes
#         admin password = (keep it safe!)

After that, import the basic organization and your first user:

Import the initial structure
ldapadd -x -D cn=admin,dc=example,dc=com -W -f base.ldif
ldapadd -x -D cn=admin,dc=example,dc=com -W -f user-arman.ldif
base.ldif
dn: dc=example,dc=com
objectClass: top
objectClass: dcObject
objectClass: organization
o: Example Corp
dc: example
 
dn: ou=People,dc=example,dc=com
objectClass: organizationalUnit
ou: People

Important

Run OpenLDAP only on the internal network, and be sure to enable TLS before using it in production — user passwords will travel across the network. Once TLS is active, create a dedicated bind DN for applications (e.g. cn=svc-app,ou=Servers,dc=example,dc=com) that has only sufficient read access. Never use the admin DN (cn=admin,...) for application authentication — that's equivalent to handing the warehouse key to every employee.

Client Integration with SSSD

The LDAP server is up, so how do you make another Linux server recognize users from LDAP? The modern answer is SSSD (System Security Services Daemon). SSSD is a daemon connecting nsswitch (user/group resolution) and PAM (authentication) to various identity backends, including LDAP.

Why SSSD and not the old pam_ldap? Because SSSD brings caching — identities and authentication are stored temporarily on the client, so login keeps working (with the last synchronized data) even when the LDAP server is offline. This is like a map cache on your phone: navigation still works in areas without signal, using the last downloaded data.

Install SSSD on the client
apt install -y sssd-ldap ldap-utils

SSSD config lives in /etc/sssd/sssd.conf. A minimal example for LDAP:

/etc/sssd/sssd.conf
[sssd]
services = nss, pam
config_file_version = 2
domains = example.com
 
[domain/example.com]
id_provider = ldap
auth_provider = ldap
ldap_uri = ldap://ldap.example.com
ldap_search_base = dc=example,dc=com
ldap_default_bind_dn = cn=svc-app,ou=Servers,dc=example,dc=com
ldap_default_authtok = S3cr3tAppBind
ldap_tls_cacert = /etc/ssl/certs/ca-certificates.crt

Note a few important things:

  • ldap_search_base must be exactly the same as your tree structure — a mismatch here is a classic error source (see the pitfalls below).
  • ldap_default_bind_dn is the bind DN — the identity SSSD uses to search for users in the directory. This is different from the authentication of the user itself.
  • services = nss, pam tells SSSD which modules to enable.

After that, enable nsswitch and PAM to use SSSD:

Enable SSSD in nsswitch & PAM
# Add sss to the passwd/group/shadow lines in /etc/nsswitch.conf
sed -i 's/^passwd:.*/passwd:         compat sss/' /etc/nsswitch.conf
sed -i 's/^group:.*/group:          compat sss/' /etc/nsswitch.conf
 
# Enable the PAM module (auto-generated with pam-auth-update)
pam-auth-update --enable mkhomedir sss
systemctl restart sssd

Tip

PAM (Pluggable Authentication Modules) is the authentication framework on Linux — think of it as a series of checkpoints at an airport. Before a passenger (user) reaches the plane (shell), they must pass several checks: is the identity valid? (pam_sss), does the home directory exist? (pam_mkhomedir), is the password still valid? (pam_unix). The order of these modules is defined in /etc/pam.d/common-auth and common-session. SSSD plugs the pam_sss module into these checkpoints, so user authentication is redirected to LDAP.

After the config is done, test authentication. The most important: log in from the network (e.g. via SSH), not directly as the LDAP user, because PAM modules are sometimes inactive at the console:

Test LDAP user authentication
id arman
su - arman
getent passwd arman
getent passwd output
arman:x:10001:10001:Arman Dwi Pangestu:/home/arman:/bin/bash

If id arman returns data, SSSD successfully resolved the identity from LDAP. The home directory will be auto-created on first login because we enabled mkhomedir.

LDAP vs Active Directory: When to Use Which

The question always comes up: "why not just use Active Directory?" The short answer: both have their place. This comparison helps you decide:

AspectOpenLDAPMicrosoft Active Directory
StandardOpen LDAP (RFC 4511)LDAP + Kerberos + DNS + proprietary extensions
PlatformLinux/Unix-firstWindows-first, supports Linux via integration
AuthenticationLDAP bind (or Kerberos via MIT/Heimdal)Kerberos by default, fully controlled
Policy/Group PolicyManual (POSIX + LDAP access control)Full GPO, automatic to Windows machines
LicenseOpen source, freePaid license
ComplexityMedium (manual setup, own TLS)High (needs DNS + domain controllers)
Best forPure Linux environments, labs, cost-efficientWindows-centric organizations with lots of policy

Note

For environments that only have Linux servers, OpenLDAP or FreeIPA (which wraps LDAP + Kerberos + DNS + certificate automation into one package) is a very reasonable choice. Active Directory fits better if the organization is already Windows-centric and needs Group Policy. In the real world, many companies run both at once — AD for primary identities and OpenLDAP/FreeIPA for Linux-based components. The principle is always the same: one single source of truth for identities, many servers depending on it.

Common Pitfalls

Centralized authentication is an area where small mistakes sting a lot. Here are the most common patterns found:

PitfallSymptomSolution
Schema error on ldapaddobjectClass violates schemaMake sure all objectClasses needed by the attributes exist, e.g. add posixAccount for Linux accounts
Base DN mismatchid arman empty; search doesn't find the userMatch ldap_search_base with the actual root DN
Bind vs search auth confusedAuthentication fails even though the bind DN is correctDistinguish: bind DN for lookup, user authentication for login
Confusing SSSD cacheA disabled user can still log inRemember the SSSD cache; set cache_credentials = False or wait for TTL
TLS not enabledPasswords travel in plaintextMust enable TLS before production
Forgotten chmod 600 on sssd.confSSSD refuses to start because permissions are too openSet chmod 600 /etc/sssd/sssd.conf
Home directory not createdLogin succeeds but cd ~ failsEnable mkhomedir in PAM

Two of them deserve a deeper look. Bind vs search is the concept that confuses people most: the bind DN is the machine/client identity SSSD uses to read the directory (find users), while authentication is the verification of the user's password at login. If the bind DN is wrong, SSSD can't find anyone; if user authentication fails, it means the password doesn't match the LDAP entry. They're two different failures with two different solutions.

Base DN mismatch happens because LDAP is very sensitive to hierarchy. If your tree was built with dc=example,dc=org (e.g. because you forgot to change the domain during installation) but SSSD uses dc=example,dc=com, the search will always be empty — and the symptom is not an error, but confusing silence. Always verify with ldapsearch before blaming SSSD:

Verify the search from the client
ldapsearch -x -H ldap://ldap.example.com \
  -b "dc=example,dc=com" \
  -D "cn=svc-app,ou=Servers,dc=example,dc=com" \
  -w 'S3cr3tAppBind' \
  "(uid=arman)"
ldapsearch output
# arman, People, example.com
dn: uid=arman,ou=People,dc=example,dc=com
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
uid: arman
uidNumber: 10001
gidNumber: 10001
homeDirectory: /home/arman
loginShell: /bin/bash

Warning

The SSSD cache is a double-edged sword. On one hand it keeps login working when LDAP is down; on the other hand, a user already disabled in the directory can still log in until the cache expires (usually 30–60 minutes). For tight security — for example when terminating an employee — use online authentication (ldap_access_order) or set cache_credentials = False on the domain handling critical users. Speed can be sacrificed; access control cannot.

Conclusion

In this episode we built centralized authentication with LDAP: understanding why a single identity source is needed as servers multiply, mastering the directory tree structure with DN/OU/CN, setting up the OpenLDAP server, integrating clients through SSSD and PAM, comparing OpenLDAP with Active Directory, and recognizing classic mistakes like schema errors, base DN mismatch, and the bind vs search confusion. In essence: user identities are no longer scattered across hundreds of servers — they live in one place and are controlled from one point.

Now you can manage dozens of servers with controlled, centralized identities. But one question remains unanswered: with so many components — servers, containers, backups, LDAP — how do we know they all stay healthy, and how do we keep services alive when one server dies? In the next episode 29, we'll cover High Availability & Monitoring Stack — Keepalived, Prometheus, Grafana, and Alertmanager. See you in episode 29!

Learn Linux - LDAP & Centralized Authentication | Learn Linux