The essentials

Quick reference

One focused task per row. Jump to the related section for complete, working examples.

UseSyntaxExamples
List PAM service filesfind /etc/pam.d -maxdepth 1 -type f -print | sortView examples
Read PAM overviewman 8 pamView examples
Read configuration syntaxman 5 pam.dView examples
Find auth rulesgrep -RnsE '^[[:space:]]*auth[[:space:]]' /etc/pam.dView examples
Find account rulesgrep -RnsE '^[[:space:]]*account[[:space:]]' /etc/pam.dView examples
Find password rulesgrep -RnsE '^[[:space:]]*password[[:space:]]' /etc/pam.dView examples
Find session rulesgrep -RnsE '^[[:space:]]*session[[:space:]]' /etc/pam.dView examples
Find included stacksgrep -RnsE \ '^[[:space:]]*(auth|account|password|session)[[:space:]]+(include|substack)' \ /etc/pam.dView examples
List PAM modulesfind /usr/lib /lib -type f -name 'pam_*.so' -print \ 2>/dev/null | sort -uView examples
Show lock recordssudo faillock --user aliceView examples
Reset one lockoutsudo faillock --user alice --resetView examples
Read lockout policygrep -Ev '^[[:space:]]*(#|$)' \ /etc/security/faillock.confView examples
Read access rulesgrep -Ev '^[[:space:]]*(#|$)' /etc/security/access.confView examples
Read resource limitsgrep -RhvE '^[[:space:]]*(#|$)' \ /etc/security/limits.conf /etc/security/limits.dView examples
Read password quality policygrep -RhvE '^[[:space:]]*(#|$)' \ /etc/security/pwquality.conf \ /etc/security/pwquality.conf.dView examples
Test one PAM servicesudo pamtester login alice authenticateView examples
Test account managementsudo pamtester login alice acct_mgmtView examples
Check SSH PAM integrationsshd -T | grep -i '^usepam'View examples
Read authentication logsjournalctl _COMM=sudo --since '-15 minutes' --no-pagerView examples
Identify module packagerpm -qf /usr/lib64/security/pam_unix.soView 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

01

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.

Capture a read-only PAM inventory
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/*
Back to quick reference ↑
02

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.

Trace one service and its dependencies
sed -n '1,240p' /etc/pam.d/login
grep -RnsE '^[[:space:]]*(auth|account|password|session)[[:space:]]' /etc/pam.d
man 5 pam.d
Back to quick reference ↑
03

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.

Review composition and controls
grep -RnsE '^[[:space:]]*(auth|account|password|session)[[:space:]]+(required|requisite|sufficient|optional|include|substack|\[)' /etc/pam.d
man 5 pam.d
Back to quick reference ↑
04

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.

Inspect password stack and quality settings
grep -RnsE '^[[:space:]]*password[[:space:]]' /etc/pam.d
grep -RhvE '^[[:space:]]*(#|$)' /etc/security/pwquality.conf /etc/security/pwquality.conf.d
passwd --status alice
Back to quick reference ↑
05

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.

Inspect one lockout safely
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
Back to quick reference ↑
06

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.

Review ordered access rules
grep -Rns 'pam_access.so' /etc/pam.d
grep -Ev '^[[:space:]]*(#|$)' /etc/security/access.conf
getent passwd alice
id alice
Back to quick reference ↑
07

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.

Inspect session hooks and effective process limits
grep -RnsE '^[[:space:]]*session[[:space:]]' /etc/pam.d
grep -RhvE '^[[:space:]]*(#|$)' /etc/security/limits.conf /etc/security/limits.d
prlimit --pid $$
Back to quick reference ↑
08

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.

Map applications to service files
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
Back to quick reference ↑
09

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.

Review a controlled test plan
# 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.
Back to quick reference ↑
10

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.

Review bounded logs
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
Back to quick reference ↑

Sources and further reading

References

Authoritative documentation used to verify and expand this cheat sheet.

  1. Linux-PAM ProjectPAM(8) Overviewman7.org
  2. Linux-PAM Projectpam.conf and pam.d(5)man7.org
  3. Linux-PAM ProjectLinux-PAM System Administrators' Guidelinux-pam.org
  4. Linux-PAM Projectpam_faillock(8)man7.org
  5. Linux-PAM Projectpam_access(8)man7.org
  6. Linux-PAM Projectpam_limits(8)man7.org

Help us improve

Found a typo or missing example?

Tell us what would make this cheat sheet clearer, more complete, or more useful.

Share feedback