SSSD and the Linux Auth Flow

What SSSD is, how Linux authentication works end-to-end, and how to troubleshoot login failures.

The Linux auth flow overview

When a user logs in to a Linux system, the following happens in order:

  1. PAM (Pluggable Authentication Modules) intercepts the login attempt
  2. PAM calls the configured authentication modules — including the SSSD module if present
  3. SSSD queries the identity provider (FreeIPA, Active Directory, LDAP) to verify credentials
  4. If credentials are valid, SSSD fetches the user's group memberships
  5. PAM checks access control rules (HBAC in FreeIPA, or PAM access.conf)
  6. NSS resolves the user's UID, GID, and home directory
  7. Login succeeds; the user's session starts

SSSD is the glue that connects Linux's local auth mechanisms (PAM + NSS) to a centralised identity provider.

What SSSD is and does

SSSD (System Security Services Daemon) is a background service that:

# Is SSSD running?
systemctl status sssd

# Check it is enrolled and working
id username@domain.example.com

# List groups for a user
groups username

PAM — pluggable authentication modules

PAM is the authentication framework. It is configured per service via files in /etc/pam.d/. Each file has four management groups:

# Example /etc/pam.d/system-auth (simplified, RHEL)
auth     required   pam_env.so
auth     sufficient pam_unix.so nullok
auth     sufficient pam_sss.so  forward_pass   ← SSSD auth
auth     required   pam_deny.so

account  required   pam_unix.so
account  sufficient pam_localuser.so
account  sufficient pam_sss.so               ← SSSD account check
account  required   pam_permit.so

PAM stacks are evaluated top to bottom. sufficient means: if this module succeeds and nothing before it failed, stop checking and allow. required means: this must succeed, but keep checking the rest. Do not edit PAM files manually — use authconfig or authselect.

NSS — name service switch

NSS determines where the system looks up user/group information. Configured in /etc/nsswitch.conf:

# /etc/nsswitch.conf
passwd:     files sss         # check /etc/passwd first, then SSSD
group:      files sss         # check /etc/group first, then SSSD
shadow:     files sss
hosts:      files dns         # /etc/hosts first, then DNS
netgroup:   nisplus sss

This means when you run id someuser, the system checks /etc/passwd first, then asks SSSD. If SSSD knows the user (via FreeIPA), it returns their UID, GID, and home directory.

sssd.conf

# /etc/sssd/sssd.conf
[sssd]
services = nss, pam
domains = example.com

[domain/example.com]
id_provider = ipa
auth_provider = ipa
access_provider = ipa
chpass_provider = ipa
cache_credentials = true

ipa_domain = example.com
ipa_hostname = client.example.com
ipa_server = _srv_, ipa01.example.com

krb5_store_password_if_offline = true
default_shell = /bin/bash
fallback_homedir = /home/%u@%d

This file is typically created by ipa-client-install and should not need manual editing. If you must edit it, restart SSSD after: systemctl restart sssd

SSSD with FreeIPA

When a host is enrolled in FreeIPA (ipa-client-install), it:

  1. Creates a Kerberos keytab at /etc/krb5.keytab
  2. Configures SSSD with the IPA domain settings
  3. Updates /etc/nsswitch.conf to include sss
  4. Updates PAM to include the SSSD modules
  5. Registers the host as a managed host in FreeIPA

After enrollment, any FreeIPA user who is granted access to the host can log in without a local account.

# Enroll a host in FreeIPA
ipa-client-install --domain=example.com \
  --server=ipa01.example.com \
  --mkhomedir \
  --enable-dns-updates

# Verify enrollment
ipa host-show $(hostname)

Useful commands

# Look up a user through SSSD
id username
id username@example.com

# Get detailed user info from SSSD
getent passwd username

# Get group info
getent group groupname

# Check SSSD cache for a user
sss_cache -u username     # invalidate (force fresh lookup)

# Invalidate all cache
sss_cache -E

# Show SSSD config status
sssctl config-check

# Show domain status
sssctl domain-status example.com

SSSD cache — offline login

SSSD caches credentials and user information. This means:

# If a user's group memberships changed in IPA but haven't updated on the host:
sss_cache -u username     # force cache invalidation for this user

# If you changed a group in IPA:
sss_cache -g groupname

# Nuclear option — clear everything (causes re-fetch on next access)
systemctl stop sssd
sss_cache -E
systemctl start sssd

Troubleshooting login failures

User cannot log in — "Permission denied"

# Check if SSSD can resolve the user
id username@example.com

# If this fails — SSSD cannot reach IPA or user does not exist
systemctl status sssd
journalctl -u sssd -n 50

User exists in IPA but gets "Access denied"

This is usually an HBAC rule issue — the user is not in an HBAC rule that grants them access to this host. Check the FreeIPA HBAC rules (see the FreeIPA HBAC page).

# Test HBAC rules with ipa hbactest (most reliable method)
ipa hbactest --user=username --host=web01.example.com --service=sshd

# List HBAC rules the user matches
ipa hbacrule-find --user=username

Authentication failed (password correct but login fails)

# Check Kerberos ticket is obtainable
kinit username@EXAMPLE.COM
klist

# Check the KDC is reachable
ping ipa01.example.com

# Check time sync — Kerberos requires clocks within 5 minutes
chronyc tracking

Reading SSSD logs

# SSSD logs go to /var/log/sssd/
ls /var/log/sssd/

# Main daemon log
tail -f /var/log/sssd/sssd.log

# Domain-specific log
tail -f /var/log/sssd/sssd_example.com.log

# PAM auth log
tail -f /var/log/sssd/sssd_pam.log

# Increase log verbosity (for debugging — revert after)
# In /etc/sssd/sssd.conf, under [domain/example.com]:
debug_level = 9
systemctl restart sssd

SSSD debug levels go from 0 (minimal) to 9 (trace). Level 5-6 is usually enough for auth debugging. Always revert to a low level after debugging — level 9 produces enormous log files quickly.

Active Directory enrollment

SSSD also works with Microsoft Active Directory — the process is similar to FreeIPA but uses realmd to join the domain.

Prerequisites (same checks as IPA)

# DNS must resolve the AD domain
dig SRV _kerberos._tcp.EXAMPLE.COM

# Clock must be in sync with the AD DC (<5 min skew)
chronyc tracking

# Required packages
dnf install realmd sssd adcli oddjob oddjob-mkhomedir samba-common-tools

Discover and join the domain

# Discover — shows what realm is available and the join method
realm discover EXAMPLE.COM

# Join the domain (prompts for Administrator password)
realm join EXAMPLE.COM

# Join with a specific user
realm join -U Administrator EXAMPLE.COM

# Verify enrollment
realm list

Minimal sssd.conf for Active Directory

[sssd]
domains = EXAMPLE.COM
config_file_version = 2
services = nss, pam

[domain/EXAMPLE.COM]
id_provider = ad
auth_provider = ad
access_provider = ad

# Use short usernames (alice) instead of alice@EXAMPLE.COM
use_fully_qualified_names = False

# Create home dirs automatically on first login
fallback_homedir = /home/%u
default_shell = /bin/bash

# Cache credentials for offline login
cache_credentials = True

# Limit which AD groups can log in (optional)
# ad_access_filter = memberOf=CN=Linux-Users,OU=Groups,DC=example,DC=com
# Restart SSSD after config changes
systemctl restart sssd

# Test user lookup
id alice@EXAMPLE.COM
# or (if use_fully_qualified_names = False)
id alice
Firewall: AD enrollment requires DNS (53), Kerberos (88), LDAP (389), SMB (445), and Global Catalog (3268) ports open to the domain controllers. realm join will fail silently if these are blocked.

sssctl user-checks and live log

sssctl — SSSD control tool

# Check a user's access status and group membership (live — bypasses cache)
sssctl user-checks alice

# Check against a specific service (ssh, sudo, etc.)
sssctl user-checks alice -s ssh

# Show the user's cached information
sssctl user-show alice

# Check domain status
sssctl domain-status EXAMPLE.COM

# List all cached users
sssctl user-list

sssctl user-checks is the fastest first step when a user reports "I can't log in." It shows PAM rules, group memberships, HBAC decisions, and whether the account is locked — all in one command.

Live log monitoring

# Follow SSSD logs in real time
journalctl -u sssd -f

# Follow logs for a specific SSSD subdomain service
journalctl -u sssd-be@EXAMPLE.COM -f

# Increase log verbosity temporarily for debugging
# Edit /etc/sssd/sssd.conf → [domain/...] → debug_level = 6
systemctl restart sssd
journalctl -u sssd -f    # watch the live log while attempting login
# Invalidate cache and force re-fetch from directory
sssctl cache-expire -E     # expire all cache entries
systemctl restart sssd