The essentials
Quick reference
One focused task per row. Jump to the related section for complete, working examples.
| Use | Syntax | Examples |
|---|---|---|
| List PAM service files | find /etc/pam.d -maxdepth 1 -type f -print | sort | View examples |
| Read PAM overview | man 8 pam | View examples |
| Read configuration syntax | man 5 pam.d | View examples |
| Find auth rules | grep -RnsE '^[[:space:]]*auth[[:space:]]' /etc/pam.d | View examples |
| Find account rules | grep -RnsE '^[[:space:]]*account[[:space:]]' /etc/pam.d | View examples |
| Find password rules | grep -RnsE '^[[:space:]]*password[[:space:]]' /etc/pam.d | View examples |
| Find session rules | grep -RnsE '^[[:space:]]*session[[:space:]]' /etc/pam.d | View examples |
| Find included stacks | grep -RnsE \
'^[[:space:]]*(auth|account|password|session)[[:space:]]+(include|substack)' \
/etc/pam.d | View examples |
| List PAM modules | find /usr/lib /lib -type f -name 'pam_*.so' -print \
2>/dev/null |
sort -u | View examples |
| Show lock records | sudo faillock --user alice | View examples |
| Reset one lockout | sudo faillock --user alice --reset | View examples |
| Read lockout policy | grep -Ev '^[[:space:]]*(#|$)' \
/etc/security/faillock.conf | View examples |
| Read access rules | grep -Ev '^[[:space:]]*(#|$)' /etc/security/access.conf | View examples |
| Read resource limits | grep -RhvE '^[[:space:]]*(#|$)' \
/etc/security/limits.conf /etc/security/limits.d | View examples |
| Read password quality policy | grep -RhvE '^[[:space:]]*(#|$)' \
/etc/security/pwquality.conf \
/etc/security/pwquality.conf.d | View examples |
| Test one PAM service | sudo pamtester login alice authenticate | View examples |
| Test account management | sudo pamtester login alice acct_mgmt | View examples |
| Check SSH PAM integration | sshd -T | grep -i '^usepam' | View examples |
| Read authentication logs | journalctl _COMM=sudo --since '-15 minutes' --no-pager | View examples |
| Identify module package | rpm -qf /usr/lib64/security/pam_unix.so | View examples |
PAM is policy code executed by privileged login, sudo, SSH, screen-lock, and password-changing applications. A syntactically valid but logically wrong stack can lock out every administrator or accidentally permit access. Never edit an authentication stack without a root session that remains open, tested console or rescue access, exact backups, and a test against the specific PAM service being changed.
Step by step
Detailed examples
Audit the exact PAM implementation and generated ownership
Module paths, vendor stacks, and management tooling vary by distribution. authselect, pam-auth-update, or package upgrades may regenerate files, so direct edits can be overwritten. Record file checksums, packages, symlinks, and local overrides without copying password databases or confidential module arguments.
find /etc/pam.d -maxdepth 1 -type f -printf '%m %u:%g %f
' | sort
find /usr/lib /lib -type f -name 'pam_*.so' -print 2>/dev/null | sort -u
sha256sum /etc/pam.d/* Evaluate every management group independently
auth verifies credentials, account decides whether an authenticated identity may use the service, password changes credentials, and session runs setup and teardown. An application may call only some groups. Order matters, modules can retain state, and success in auth does not bypass account denial.
sed -n '1,240p' /etc/pam.d/login
grep -RnsE '^[[:space:]]*(auth|account|password|session)[[:space:]]' /etc/pam.d
man 5 pam.d Treat control flow like security-sensitive program logic
required records failure but continues; requisite can fail immediately; sufficient can short-circuit only when no earlier required failure exists; optional usually matters only when alone. Bracketed value=action syntax can jump or reset state. include and substack differ in how actions interact with the parent stack, so copy-paste changes are unsafe.
grep -RnsE '^[[:space:]]*(auth|account|password|session)[[:space:]]+(required|requisite|sufficient|optional|include|substack|\[)' /etc/pam.d
man 5 pam.d Apply password policy to the password-changing path
Quality checks normally run when a password is set, not at every login. Ensure the module receives the new token through the intended options, understand root enforcement settings, and pair quality with secure hashing and breach-response policy. Misordered password modules can update one backend and fail another, leaving credentials inconsistent.
grep -RnsE '^[[:space:]]*password[[:space:]]' /etc/pam.d
grep -RhvE '^[[:space:]]*(#|$)' /etc/security/pwquality.conf /etc/security/pwquality.conf.d
passwd --status alice Tune lockouts without creating denial-of-service
pam_faillock placement and options determine which failures count and whether unknown users are disclosed. Aggressive thresholds let attackers lock out administrators. Preserve an emergency local path, monitor centralized attempts, reset only a verified account, and understand whether counters survive reboot and where they are stored.
grep -Rns 'pam_faillock.so' /etc/pam.d
grep -Ev '^[[:space:]]*(#|$)' /etc/security/faillock.conf
sudo faillock --user alice
# Reset only after confirming identity and incident context:
# sudo faillock --user alice --reset Keep authentication separate from authorization
pam_access can allow or deny by user, group, origin, or service context, with first-match behavior and distribution-specific file inclusion. A permissive fallback or misunderstood group token can invert intent. Test local console, SSH, sudo, automation, and break-glass identities from separate sessions.
grep -Rns 'pam_access.so' /etc/pam.d
grep -Ev '^[[:space:]]*(#|$)' /etc/security/access.conf
getent passwd alice
id alice Treat session modules as privileged lifecycle hooks
Session modules can create homes, set limits, record logins, mount storage, label contexts, and update audit data. A slow or failing network-backed hook can block login. limits.conf applies only when pam_limits runs, and not necessarily to system services; systemd unit limits are a separate control plane.
grep -RnsE '^[[:space:]]*session[[:space:]]' /etc/pam.d
grep -RhvE '^[[:space:]]*(#|$)' /etc/security/limits.conf /etc/security/limits.d
prlimit --pid $$ Verify the application actually uses the expected PAM service
Each application chooses a PAM service name and which management calls to make. sshd can combine PAM with public-key authentication and its own authorization directives; sudo, login, su, display managers, and screensavers use different files. Testing login does not validate sshd or sudo.
sshd -T | grep -i '^usepam'
sed -n '1,200p' /etc/pam.d/sshd
sed -n '1,200p' /etc/pam.d/sudo
sed -n '1,200p' /etc/pam.d/login Test with rescue access and bounded failure counts
pamtester is useful but may not reproduce an application's conversation, environment, remote host, or privilege behavior, and failed tests can trigger lockout. Keep an authenticated root shell open, confirm console recovery, change one stack at a time, and test positive and negative cases before ending the session.
# Keep a separate verified root or console session open.
# sudo pamtester login testuser authenticate
# sudo pamtester login testuser acct_mgmt
# sudo faillock --user testuser
# Test the actual target application before closing recovery access. Collect authentication evidence without collecting credentials
PAM errors usually reach the system journal or authentication log through the calling application. Correlate timestamp, service, user, origin, module, and management group. Debug module options may reveal sensitive metadata and should be time-bounded; never record passwords, tokens, shadow data, or full secret-bearing configuration.
journalctl _COMM=sshd --since '-15 minutes' --no-pager
journalctl _COMM=sudo --since '-15 minutes' --no-pager
journalctl _SYSTEMD_UNIT=systemd-logind.service --since '-15 minutes' --no-pager Sources and further reading
References
Authoritative documentation used to verify and expand this cheat sheet.
Help us improve
Found a typo or missing example?
Tell us what would make this cheat sheet clearer, more complete, or more useful.



