Portal | Level: L2: Operations | Topics: LDAP & Identity Management, Linux Hardening, Least Privilege | Domain: Security
LDAP & Identity Management - Primer¶
Why This Matters¶
Every organization with more than a handful of servers needs centralized identity management. Without it, you are managing local user accounts on every box, which means inconsistent access, orphaned accounts, and audit nightmares. LDAP is the protocol that glues it all together — it backs Active Directory, FreeIPA, OpenLDAP, and virtually every enterprise identity system.
Understanding LDAP is not about becoming a directory admin. It is about knowing how Linux authentication works end-to-end: from a user typing their password to PAM checking SSSD to SSSD querying LDAP (or Kerberos). When login fails at 2 AM, you need to know where in that chain the problem lives.
The LDAP Data Model¶
LDAP is a hierarchical directory — think of it as a tree (technically a DAG) of entries.
Name origin: LDAP stands for Lightweight Directory Access Protocol. The "lightweight" is relative to its predecessor, the X.500 Directory Access Protocol (DAP), which required the full OSI stack. LDAP stripped it down to run over TCP/IP. It was created by Tim Howes, Steve Kille, and Wengyik Yeong at the University of Michigan in 1993 (RFC 1487).
dc=example,dc=com (root / base DN)
/ \
ou=People ou=Groups
/ | \ / \
uid=alice uid=bob uid=carol cn=devops cn=dba
Key Terminology¶
| Term | Meaning | Example |
|---|---|---|
| DN | Distinguished Name (full path to entry) | uid=alice,ou=People,dc=example,dc=com |
| RDN | Relative DN (just this entry's name) | uid=alice |
| Base DN | Root of the search tree | dc=example,dc=com |
| OU | Organizational Unit (container) | ou=People |
| CN | Common Name | cn=devops |
| DC | Domain Component | dc=example |
| objectClass | Schema type of entry | inetOrgPerson, posixAccount |
| Attribute | Key-value property of an entry | mail=alice@example.com |
Entry Structure¶
An LDAP entry is a set of attributes:
dn: uid=alice,ou=People,dc=example,dc=com
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
uid: alice
cn: Alice Smith
sn: Smith
uidNumber: 10001
gidNumber: 10001
homeDirectory: /home/alice
loginShell: /bin/bash
mail: alice@example.com
userPassword: {SSHA}encrypted_hash_here
LDAP Operations¶
BIND authenticate to the directory
SEARCH query entries (the most common operation)
ADD create a new entry
MODIFY change attributes of an entry
DELETE remove an entry
MODRDN rename an entry
COMPARE test if an attribute has a specific value
UNBIND close the connection
LDAP Search Filters¶
Filters are how you query LDAP. The syntax is prefix notation:
# Simple equality
(uid=alice)
# Wildcard
(cn=Alice*)
# AND (all conditions must match)
(&(objectClass=posixAccount)(uidNumber>=1000))
# OR (any condition matches)
(|(uid=alice)(uid=bob))
# NOT
(!(loginShell=/bin/false))
# Combined
(&(objectClass=posixAccount)(|(memberOf=cn=devops,ou=Groups,dc=example,dc=com)(uid=admin)))
Search Scope¶
base search only the base DN itself
one search direct children of base DN
sub search entire subtree (most common)
The Linux Authentication Stack¶
When a user logs in to a Linux machine, the request flows through:
User types password
│
▼
┌──────────────┐
│ PAM │ Pluggable Authentication Modules
│ (pam stack) │ /etc/pam.d/
└──────┬───────┘
│
▼
┌──────────────┐
│ NSS │ Name Service Switch
│ /etc/nsswitch │ maps uid -> username, etc.
└──────┬───────┘
│
▼
┌──────────────┐
│ SSSD │ System Security Services Daemon
│ (cache + │ /etc/sssd/sssd.conf
│ backend) │
└──────┬───────┘
│
▼
┌──────────────┐
│ LDAP / AD / │ Backend identity provider
│ FreeIPA │
└──────────────┘
PAM (Pluggable Authentication Modules)¶
PAM is a framework that lets you stack authentication methods. Each service (sshd, sudo, login) has a PAM config:
# /etc/pam.d/sshd
auth required pam_sepermit.so
auth sufficient pam_sss.so forward_pass
auth required pam_unix.so use_first_pass
auth required pam_deny.so
account required pam_unix.so
account sufficient pam_sss.so
account required pam_permit.so
password sufficient pam_sss.so
password required pam_unix.so
session required pam_mkhomedir.so skel=/etc/skel/ umask=077
session required pam_unix.so
session optional pam_sss.so
PAM Control Flags¶
required must pass; failure is fatal but continues checking
requisite must pass; failure stops immediately
sufficient if passes, skip remaining modules in this stack
optional result only matters if it's the only module
The order matters enormously. A misplaced sufficient can bypass all subsequent checks.
Remember: PAM control flags mnemonic: Requisite Rejects immediately, Required Records failure but continues, Sufficient Stops on success. Think "RR stops, RR continues, S skips."
Gotcha: If you put
pam_sss.soassufficientbeforepam_unix.so, and SSSD is down, local users in/etc/passwdcan still log in. But if you reverse the order and makepam_unix.sosufficient first, LDAP-only users will never be checked when local auth fails.
NSS (Name Service Switch)¶
This says: look up users first in /etc/passwd, then ask SSSD. Same for groups.
SSSD — The Glue Daemon¶
SSSD is the modern way to connect Linux to LDAP/AD/FreeIPA. It handles:
- Authentication (password check)
- Identity (user/group lookup)
- Caching (works offline if cache is warm)
- Kerberos ticket management
Basic SSSD Config for LDAP¶
# /etc/sssd/sssd.conf (must be mode 0600!)
[sssd]
domains = example.com
services = nss, pam
[domain/example.com]
id_provider = ldap
auth_provider = ldap
ldap_uri = ldaps://ldap.example.com
ldap_search_base = dc=example,dc=com
ldap_tls_reqcert = demand
ldap_tls_cacert = /etc/pki/tls/certs/ca-bundle.crt
# User/group mappings
ldap_user_search_base = ou=People,dc=example,dc=com
ldap_group_search_base = ou=Groups,dc=example,dc=com
# Cache settings
cache_credentials = true
entry_cache_timeout = 300
# Enumeration (set false for large directories)
enumerate = false
Debug clue: When SSSD authentication fails, the first place to look is
/var/log/sssd/sssd_<domain>.log. Setdebug_level = 6in the[domain/...]section ofsssd.conffor verbose output. After changing debug level, restart SSSD — it does not pick up debug level changes on SIGHUP.
SSSD for Active Directory¶
[domain/ad.example.com]
id_provider = ad
auth_provider = ad
access_provider = ad
ad_domain = ad.example.com
ad_server = dc1.ad.example.com
krb5_realm = AD.EXAMPLE.COM
# Use POSIX attributes from AD (if configured)
ldap_id_mapping = false
# Or let SSSD auto-map SIDs to UIDs
ldap_id_mapping = true
# Filter allowed groups
ad_access_filter = memberOf=CN=LinuxAdmins,OU=Groups,DC=ad,DC=example,DC=com
Kerberos Basics¶
Kerberos provides single-sign-on (SSO) by issuing time-limited tickets:
Name origin: Kerberos is named after the three-headed dog (Cerberus) from Greek mythology that guards the gates of the underworld. The three "heads" of the protocol are the client, the server, and the Key Distribution Center (KDC). Developed at MIT as part of Project Athena in the 1980s.
1. User authenticates to KDC (Key Distribution Center)
→ Receives TGT (Ticket Granting Ticket)
2. User requests access to service
→ Presents TGT to KDC
→ Receives Service Ticket
3. User presents Service Ticket to service
→ Service validates ticket
→ Access granted (no password sent!)
┌────────┐ ┌──────────┐ ┌──────────┐
│ User │──TGT──▶│ KDC │ │ Service │
│ │◀───────│(AS + TGS)│ │ (SSH/HTTP)│
│ │──Svc──▶│ │ │ │
│ │ Ticket │ │ │ │
│ │────────┼──────────┼────────▶│ │
└────────┘ └──────────┘ └──────────┘
Kerberos on Linux¶
# Obtain a TGT
kinit alice@EXAMPLE.COM
# List tickets
klist
# Destroy tickets
kdestroy
# Kerberos config
cat /etc/krb5.conf
# /etc/krb5.conf
[libdefaults]
default_realm = EXAMPLE.COM
dns_lookup_kdc = true
[realms]
EXAMPLE.COM = {
kdc = kdc.example.com
admin_server = kdc.example.com
}
[domain_realm]
.example.com = EXAMPLE.COM
example.com = EXAMPLE.COM
FreeIPA¶
FreeIPA bundles LDAP (389 Directory Server), Kerberos, DNS, and a web UI into a single identity management platform. It is the open-source answer to Active Directory.
Joining a Client to FreeIPA¶
# Install client packages
yum install ipa-client # RHEL/CentOS
apt install freeipa-client # Debian/Ubuntu
# Join the domain (interactive)
ipa-client-install --domain=example.com --realm=EXAMPLE.COM \
--server=ipa.example.com --mkhomedir
# This configures:
# - SSSD for identity/auth
# - Kerberos (/etc/krb5.conf)
# - PAM and NSS
# - SSH key retrieval from IPA
# - Certificate trust
Common IPA Commands¶
# Find a user
ipa user-find alice
# Show user details
ipa user-show alice --all
# Add user to group
ipa group-add-member devops --users=alice
# List groups
ipa group-find
# Check host enrollment
ipa host-find $(hostname)
# Manage sudo rules
ipa sudorule-find
ipa sudorule-show admin_rule --all
AD Integration Without FreeIPA¶
For joining Linux directly to Active Directory:
# Using realmd (recommended)
realm discover ad.example.com
realm join ad.example.com -U admin
# Verify
realm list
# SSSD is auto-configured. Check status:
systemctl status sssd
id aduser@ad.example.com
Login Format After AD Join¶
# Default format
ssh aduser@ad.example.com@linuxhost
# Configure short names in sssd.conf
[domain/ad.example.com]
use_fully_qualified_names = false
fallback_homedir = /home/%u
Quick Reference: File Locations¶
/etc/sssd/sssd.conf SSSD configuration (0600!)
/etc/pam.d/ PAM configs per service
/etc/nsswitch.conf Name service switch order
/etc/krb5.conf Kerberos configuration
/etc/ldap.conf LDAP client defaults
/var/log/sssd/ SSSD domain and service logs
/var/lib/sss/db/ SSSD cache databases
/etc/openldap/ldap.conf OpenLDAP client config
Understanding the full chain — PAM, NSS, SSSD, LDAP/Kerberos — is what separates "login does not work" panic from "the SSSD cache is stale, let me clear it." Know the chain, debug the chain.
Wiki Navigation¶
Prerequisites¶
- Linux Ops (Topic Pack, L0)
- Security Basics (Ops-Focused) (Topic Pack, L1)
Related Content¶
- Compliance & Audit Automation (Topic Pack, L2) — Linux Hardening
- Deep Dive: Systemd Service Design Debugging and Hardening (deep_dive, L2) — Linux Hardening
- Infrastructure Forensics (Topic Pack, L2) — Linux Hardening
- LDAP Flashcards (CLI) (flashcard_deck, L1) — LDAP & Identity Management
- Linux Security Flashcards (CLI) (flashcard_deck, L1) — Linux Hardening
- Linux Users & Permissions (Topic Pack, L1) — Linux Hardening
- SELinux & AppArmor (Topic Pack, L2) — Linux Hardening
- SELinux & Linux Hardening (Topic Pack, L2) — Linux Hardening
- SSH Deep Dive (Topic Pack, L1) — Linux Hardening