PAM, Password Policies & User Security
Chapter 22: PAM, Password Policies & User Security
Section titled “Chapter 22: PAM, Password Policies & User Security”Learning Objectives
Section titled “Learning Objectives”- Understand the PAM architecture and module types
- Configure strong password policies using PAM
- Understand account lockout and session management
- Configure MFA via PAM
What is this? (Beginner On-Ramp)
Section titled “What is this? (Beginner On-Ramp)”Password policies enforce strong security rules for user accounts. They dictate how long a password must be, how complex it should be, and how the system should react (like temporarily locking the account) if someone types the wrong password too many times.
22.1 PAM Architecture
Section titled “22.1 PAM Architecture”PAM (Pluggable Authentication Modules) provides a flexible, modular authentication framework.
PAM Architecture ─────────────────
Application (sshd, sudo, login, su) │ calls pam_authenticate() ▼ ┌─────────────────────────────────────────────────────┐ │ PAM Library (libpam.so) │ │ │ │ Reads /etc/pam.d/<service> │ │ Processes module stack in order │ └──────────────────────┬──────────────────────────────┘ │ ┌──────────────────────▼──────────────────────────────┐ │ PAM Module Stack │ │ │ │ pam_unix.so ← Traditional Unix auth │ │ pam_google_authenticator.so ← TOTP │ │ pam_faillock.so ← Account lockout │ │ pam_pwquality.so ← Password complexity │ │ pam_limits.so ← Resource limits │ │ pam_lastlog.so ← Last login info │ └─────────────────────────────────────────────────────┘PAM Module Types
Section titled “PAM Module Types” PAM Management Groups: ──────────────────────── auth: Verify identity (password, key, biometric) account: Account validity (expired? locked? time restrictions?) password: Update authentication credentials session: Setup/teardown session (mount home dir, set env, log)
Control Flags: ──────────────── required: Must succeed; failure noted but stack continues requisite: Must succeed; failure halts stack immediately sufficient: Success ends stack; failure noted but stack continues optional: Used for side effects; success/failure mostly ignored [success=n]: Jump n modules ahead on success (modern syntax)22.2 PAM Configuration
Section titled “22.2 PAM Configuration”# PAM service files locationls /etc/pam.d/
# Important files:# sshd — SSH daemon auth# sudo — sudo authentication# su — su command auth# login — Console login# common-auth — Included by others (Ubuntu/Debian)# system-auth — Included by others (RHEL)
# View a service's PAM configcat /etc/pam.d/sshdCommon-auth Stack (Ubuntu/Debian)
Section titled “Common-auth Stack (Ubuntu/Debian)”auth [success=2 default=ignore] pam_unix.so nullok_secureauth [success=1 default=ignore] pam_winbind.so krb5_auth krb5_ccache_type=FILE cached_login try_first_passauth requisite pam_deny.soauth required pam_permit.soauth optional pam_cap.so22.3 Password Policy with pam_pwquality
Section titled “22.3 Password Policy with pam_pwquality”# Installapt-get install libpam-pwquality # Debian/Ubuntuyum install pam_pwquality # RHEL
# /etc/security/pwquality.conf — Password requirements# Minimum password lengthminlen = 14
# Minimum character class requirements (negative = minimum count)dcredit = -1 # At least 1 digitucredit = -1 # At least 1 uppercaselcredit = -1 # At least 1 lowercaseocredit = -1 # At least 1 special character
# Maximum consecutive same charactersmaxrepeat = 3 # No more than 3 of the same char in a row
# Maximum consecutive same class charactersmaxclassrepeat = 4 # No 4+ consecutive chars from same class
# Reject palindromespalindrome = 1
# Check if password is based on username/GECOSusercheck = 1
# Reject passwords from dictionarydictcheck = 1
# Minimum number of characters that must be different from old passworddifok = 8
# Number of passwords to remember (prevents reuse)# Requires pam_pwhistory.so# Apply pam_pwquality to password changespassword requisite pam_pwquality.so retry=3password [success=1 default=ignore] pam_unix.so obscure sha512 shadow \ use_authtok remember=12 # Remember last 12 passwords22.4 Account Lockout with pam_faillock
Section titled “22.4 Account Lockout with pam_faillock”# pam_faillock — Lock accounts after repeated failures# Replaces older pam_tally2
# Number of failed attempts before lockoutdeny = 5
# Time window for counting failures (seconds)fail_interval = 900 # 15 minutes
# Lockout duration (seconds)unlock_time = 900 # 15 minutes
# Admin accounts need stricter policy# [users] section applies to all users
# Don't lock root (prevents lockout attack; root should use key auth anyway)# even_deny_root# root_unlock_time = 60
# Audit failed attemptsaudit# /etc/pam.d/common-auth — Add faillock supportauth required pam_faillock.so preauthauth [success=1 default=ignore] pam_unix.so nullok_secureauth [default=die] pam_faillock.so authfailauth sufficient pam_faillock.so authsuccauth requisite pam_deny.so
# View lockout statusfaillock --user alice# alice:# When Type Source Valid# 2024-01-15 10:00:00 RHOST 192.168.1.100 V
# Unlock a locked accountfaillock --user alice --reset22.5 Password Aging
Section titled “22.5 Password Aging”# Set password aging policies
# Per-user agingchage -l alice # View aging infochage alice # Interactive
# Set specific valueschage -M 90 alice # Max password age: 90 dayschage -m 7 alice # Min password age: 7 days (prevent rapid cycling)chage -W 14 alice # Warn 14 days before expirychage -I 30 alice # Lock account 30 days after expirychage -E 2025-12-31 alice # Account expiry date
# System-wide defaults for new accounts# /etc/login.defsPASS_MAX_DAYS 90 # Maximum password agePASS_MIN_DAYS 7 # Minimum password agePASS_WARN_AGE 14 # Days before warning
# Apply aging to all existing accounts (except system accounts)for user in $(awk -F: '$3 >= 1000 {print $1}' /etc/passwd); do chage -M 90 -m 7 -W 14 "$user"done22.6 Resource Limits with PAM
Section titled “22.6 Resource Limits with PAM”# /etc/security/limits.conf — PAM-enforced resource limits# Format: <domain> <type> <item> <value>
# Limit for all users* soft nofile 65536 # Open file descriptors* hard nofile 131072* soft nproc 4096 # Number of processes* hard nproc 8192* soft stack 8192 # Stack size (KB)* hard stack unlimited
# Specific useralice soft cpu 240 # CPU time limit (minutes)alice hard memlock unlimited # No memory locking limit
# Group-based@developers soft nofile 32768
# /etc/pam.d/common-session — Enable limitssession required pam_limits.so
# Verify limits for a usersu - alice -c 'ulimit -a'22.7 User Security Audit
Section titled “22.7 User Security Audit”# ── Security Audit Commands ───────────────────────────────# Find users with empty passwordsawk -F: '$2 == "" {print "NO PASSWORD:", $1}' /etc/shadow
# Find system accounts that can login (security issue)awk -F: '$7 != "/sbin/nologin" && $7 != "/bin/false" && $3 < 1000 { print "SYSTEM ACCOUNT WITH SHELL:", $1, "UID:", $3, "SHELL:", $7}' /etc/passwd
# Find accounts with UID 0 (should be only root)awk -F: '$3 == 0 {print "UID 0 ACCOUNT:", $1}' /etc/passwd
# Find duplicate UIDsawk -F: '{print $3}' /etc/passwd | sort | uniq -d | while read uid; do echo "DUPLICATE UID $uid:" awk -F: -v u="$uid" '$3 == u {print " ", $1}' /etc/passwddone
# Check password expiry for all usersawk -F: '$3 >= 1000 && $3 < 65534 {print $1}' /etc/passwd | while read user; do EXPIRY=$(chage -l "$user" 2>/dev/null | grep "Password expires" | cut -d: -f2) echo "$user: expires$EXPIRY"done
# Find users who haven't logged in for 90+ dayslastlog | awk '$4 != "Never" && $4 != "Latest" { # Parse date and check age - manual implementation needed print}' | head -2022.8 Interview Questions
Section titled “22.8 Interview Questions”Q1: What is PAM and how does the module stack work?
Answer: PAM (Pluggable Authentication Modules) is a framework that decouples authentication from applications. Instead of each application implementing its own authentication logic, they call PAM APIs, which consult a configuration file (
/etc/pam.d/<service>) that defines a stack of modules to run. The stack has 4 management groups:auth(verify identity),account(check account validity),password(update credentials),session(setup/teardown). Each module has a control flag:required(must succeed, failure noted but continues),requisite(failure immediately halts),sufficient(success ends the group),optional(mostly ignored). This allows mixing Unix passwords, LDAP, OTP, and biometrics by adding modules to the stack.
Q2: How would you configure a system to lock accounts after 5 failed login attempts?
Answer: Using
pam_faillock: (1) Install/configure/etc/security/faillock.confwithdeny = 5,fail_interval = 900,unlock_time = 1800. (2) Add to/etc/pam.d/common-auth:auth required pam_faillock.so preauthbefore the main auth module andauth [default=die] pam_faillock.so authfailafter. (3) Verify: attempt 5 wrong passwords, thenfaillock --user <user>confirms the lock. Unlock manually withfaillock --user <user> --reset. Also configureeven_deny_rootcarefully — if root gets locked, ensure you have out-of-band access (console, AWS SSM).
22.9 Summary
Section titled “22.9 Summary”| Component | Purpose |
|---|---|
| PAM | Pluggable authentication framework |
| pam_unix | Traditional Unix password auth |
| pam_pwquality | Password complexity enforcement |
| pam_faillock | Account lockout after failures |
| pam_limits | Resource limits (ulimits) |
| pam_google_authenticator | TOTP/2FA |
| /etc/login.defs | System-wide account defaults |
| chage | Password aging configuration |
Next Chapter: Chapter 23: Network Security: iptables, nftables & fail2ban
Section titled “Next Chapter: Chapter 23: Network Security: iptables, nftables & fail2ban”Prerequisites
Section titled “Prerequisites”Chapter 18 (PAM).
Advantages & Disadvantages
Section titled “Advantages & Disadvantages”Advantages: Prevents trivial account takeovers, enforces compliance. Disadvantages: Overly strict policies encourage users to write passwords on sticky notes.
Common Mistakes
Section titled “Common Mistakes”- Setting password expiry too frequently — users will just append numbers to the same password.
- Locking out the root account via PAM faillock without an alternative emergency access method.
Troubleshooting
Section titled “Troubleshooting”| Symptom | Cause | Diagnosis | Fix |
|---|---|---|---|
| User cannot change password | Password doesn’t meet complexity rules | Check /var/log/secure or auth.log | Inform user of the specific policy (length, class) |
| Account locked due to failed logins | faillock triggered | faillock --user username | Unlock with: faillock —user username —reset |
Hands-on Lab
Section titled “Hands-on Lab”Objective: Configure and test password policies.
# 1. Check current password aging ruleschage -l username
# 2. Configure password complexity (e.g., via pam_pwquality)# vi /etc/security/pwquality.conf# minlen = 14# minclass = 3
# 3. Check faillock statusfaillockExercises
Section titled “Exercises”- Configure PAM to enforce a 14-character minimum password length and prevent using the last 5 passwords.
- Use
chageto force a user to change their password on their next login.
Revision Notes
Section titled “Revision Notes”pam_pwqualityenforces password complexity.pam_faillockprotects against brute-force attacks by locking accounts.chagemanages password expiration and aging policies.- NIST now recommends long passphrases and removing arbitrary rotation requirements.
Further Reading
Section titled “Further Reading”- NIST SP 800-63B (Digital Identity Guidelines)
man chage,man pam_pwquality
Related Chapters
Section titled “Related Chapters”- Chapter 18 — PAM fundamentals
Last Updated: July 2026