Protego field desk
Users, Permissions and Access Control · Access control

L8. PAM: How Linux Handles Authentication

Course outlineLesson 8 of 20

Pluggable Authentication Modules (PAM) is the framework that controls how Linux verifies user identity, enforces password policies, and locks accounts after failed attempts. This lesson covers how PAM works, its configuration structure, and the modules most relevant to security administration.

What Is PAM?

PAM (Pluggable Authentication Modules) is a framework that separates authentication logic from the applications that need it. Instead of every program (login, SSH, sudo, su) implementing its own password checking, account lockout, and session setup, they all delegate to PAM. PAM then decides which authentication checks to perform based on its configuration files.

This design has two major security benefits:

  1. Centralized policy: You configure password strength rules, account lockout, and session limits in one place. PAM-aware services can share policy through included stacks; each service still has its own configuration.
  2. Modular design: You can add, remove, or reorder authentication steps (password checks, two-factor authentication, biometrics) without modifying any application code.

How PAM Works

When a user tries to log in via SSH, the sshd process does not check the password itself. Instead, it calls PAM with the username and credentials. PAM then processes a stack of modules defined in the relevant configuration file. Each module performs one check and returns a result (success, failure, or other). PAM combines these results according to its rules and tells sshd whether to allow or deny the login.

The Four PAM Module Types

PAM organizes its modules into four management groups. Applications invoke the groups they need; password changes are not a step in every login:

TypePurposeExample
authVerify the user's identity (password, token, key)Check password against /etc/shadow
accountCheck if the account is allowed to log inVerify account is not expired or locked
passwordHandle password changesEnforce strength requirements when changing a password
sessionSet up and tear down the user's sessionCreate login records, set resource limits
Each type can have multiple modules stacked together. For example, the auth stack might first check a password, then check a two-factor token.

PAM Configuration Files

PAM configuration lives in the /etc/pam.d/ directory. Each file corresponds to a service (an application that uses PAM):

ls /etc/pam.d/

Typical files:

FileControls Authentication For
/etc/pam.d/sshdSSH logins
/etc/pam.d/loginConsole logins
/etc/pam.d/sudosudo commands
/etc/pam.d/suSwitching users with su
/etc/pam.d/common-authShared auth config included by other files (Debian/Ubuntu)
/etc/pam.d/system-authShared auth config (RHEL/CentOS)
/etc/pam.d/common-passwordShared password policy (Debian/Ubuntu)
/etc/pam.d/password-authShared password policy (RHEL/CentOS)

Configuration Line Format

Each line in a PAM file follows this structure:

type    control    module    [arguments]

Illustrative authentication line (not a complete stack):

auth    required    pam_unix.so

Control Values

The control field determines how PAM handles the module's result:

ControlBehavior
requiredMust succeed for overall success. If it fails, continue checking remaining modules but ultimately deny.
requisiteMust succeed. If it fails, immediately deny (do not continue the stack).
sufficientIf this succeeds and no prior required module failed, immediately allow.
optionalResult is only significant if it is the only module in the stack.
Security note: The difference between required and requisite matters. required continues processing even after failure (which can reduce differences in failure timing). requisite fails immediately (which can leak information but is faster).

Essential PAM Modules

pam_unix: Standard Password Authentication

This is the most fundamental module. It checks passwords against /etc/shadow.

auth    required    pam_unix.so

pam_pwquality: Password Strength Enforcement

pam_pwquality enforces password complexity rules when users set or change passwords:
# Install on Ubuntu if not present
sudo apt install libpam-pwquality

Configuration in /etc/pam.d/common-password (Ubuntu):

password    requisite    pam_pwquality.so retry=3 minlen=12 difok=3 ucredit=-1 lcredit=-1 dcredit=-1 ocredit=-1
ParameterMeaning
minlen=12Minimum password length of 12 characters
difok=3At least 3 characters must differ from the old password
ucredit=-1At least 1 uppercase letter required
lcredit=-1At least 1 lowercase letter required
dcredit=-1At least 1 digit required
ocredit=-1At least 1 special character required
retry=3Allow 3 attempts before failing
You can also configure these settings in /etc/security/pwquality.conf:
sudo cat /etc/security/pwquality.conf

pam_faillock: Account Lockout After Failed Attempts

pam_faillock (which replaced the older pam_tally2) locks accounts after a configurable number of failed login attempts:

Use your distribution's supported PAM management tooling rather than pasting a generic stack into a live host. Configure policy in /etc/security/faillock.conf, for example:

deny = 5
fail_interval = 900
unlock_time = 900
silent

The auth stack must route failed authentication to pam_faillock.so authfail. Use authsucc to clear prior failures after success, or the documented account-module arrangement with a preauth check. A preauth check can reject an already locked account. Calling authfail unconditionally records successes as failures; omitting the success reset can count nonconsecutive failures. See the complete pam_faillock(8) examples and your distribution guidance before changing the stack.

ParameterMeaning
deny=5Lock the account after 5 failed attempts
unlock_time=900Automatically unlock after 900 seconds (15 minutes)
auditLog failed attempts to the system log
silentDo not reveal to the user that the account is locked (prevents enumeration)
Managing locked accounts:
# View failed login attempts for a user
faillock --user idan

# Unlock a locked account sudo faillock --user idan --reset

pam_limits: Resource Limits

pam_limits enforces resource limits defined in /etc/security/limits.conf:
# /etc/security/limits.conf
# Limit the number of simultaneous logins
*    hard    maxlogins    3

# Limit maximum number of open files * soft nofile 1024 * hard nofile 65536

# Limit process count (prevents fork bombs) * hard nproc 256

The nproc limit is a defense against fork bomb attacks (:(){ :|:& };:), which spawn processes recursively until the system runs out of resources.

Password Aging and Expiration

PAM works in conjunction with password aging settings stored in /etc/shadow and managed with the chage command:

# View password aging information for a user
sudo chage -l idan

# Set password to expire after 90 days sudo chage -M 90 idan

# Set minimum days between password changes (prevents rapid cycling) sudo chage -m 7 idan

# Set warning period (days before expiry to warn user) sudo chage -W 14 idan

# Force password change on next login sudo chage -d 0 idan

Example Legacy Password Policy Settings

SettingExample ValuePurpose
Maximum age90 daysForce periodic password rotation
Minimum age7 daysPrevent users from immediately reverting to old password
Warning period14 daysGive users time to plan a change
Minimum length12+ charactersResist brute-force attacks
ComplexityMixed case, digits, special charsIncrease keyspace
HistoryRemember last 12 passwordsPrevent password reuse
Note: Modern guidance from NIST (SP 800-63B) recommends longer passwords over complex ones and discourages mandatory periodic rotation unless there is evidence of compromise. Your organization's compliance requirements may differ.

Putting It Together: A Hardened PAM Configuration

Here is what a security-focused PAM auth stack looks like conceptually:

  1. pam_faillock (preauth): Check if the account is already locked
  2. pam_unix: Verify the password against /etc/shadow
  3. pam_faillock: Route failures to authfail and successes to authsucc to reset the tally
  4. pam_pwquality: Enforce password strength on changes
  5. pam_limits: Apply resource limits for the session

This layered approach ensures that every login attempt is checked against lockout policy, authenticated against the password store, and constrained by resource limits. Each module does one thing, and the stack combines them into a comprehensive authentication flow.

Common Mistakes to Avoid

  1. Editing PAM files without a backup: A misconfigured PAM stack can lock everyone out. Always keep a root shell open while testing changes.
  2. Assuming control flags hide all failure details: required continues after a failure; requisite stops immediately. Messages and timing also depend on the application and modules.
  3. Setting unlock_time=0: This means locked accounts never automatically unlock, which can cause denial-of-service if an attacker deliberately triggers lockouts.
  4. Forgetting the root account: Ensure root is either excluded from lockout policies or has an alternative recovery method (physical console access).

References

Exam Focus Points
  • ✓PAM separates authentication logic from applications: PAM-aware services use service-specific stacks that can include shared policy.
  • ✓The four PAM module types are auth (identity verification), account (access checks), password (credential changes), and session (setup/teardown).
  • ✓The "required" control continues processing after failure (continuing the stack), while "requisite" fails immediately (faster but leaks information).
  • ✓pam_faillock replaces pam_tally2 for account lockout: configure deny count, unlock_time, and use the "silent" flag to prevent account enumeration.
  • ✓pam_pwquality enforces password strength rules (length, complexity, similarity to old password) during password changes.
Knowledge Check

1. What is the primary advantage of PAM's centralized authentication design?

2. What is the difference between the "required" and "requisite" PAM control values?

3. Why should the pam_faillock "silent" parameter be enabled?