PAM Configuration¶
Pluggable Authentication Modules (PAM) provide a flexible framework for authentication on Linux systems. Proper PAM configuration enforces password policies, account lockout, and access controls.
PAM Fundamentals¶
What PAM Does¶
PAM sits between applications and authentication methods:
┌─────────────────────────────────────────────────────────────┐
│ Applications (sshd, sudo, login) │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ PAM Library │
│ (libpam.so) │
└─────────────────────────────────────────────────────────────┘
│
┌─────────────────┼─────────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│pam_unix │ │pam_ldap │ │pam_google │
│(local) │ │(LDAP) │ │(2FA) │
└──────────┘ └──────────┘ └──────────┘
PAM Module Types¶
| Type | Purpose | Example |
|---|---|---|
| auth | Verify identity | Password check, 2FA |
| account | Access authorization | Account expiry, time restrictions |
| password | Password changes | Complexity requirements |
| session | Session setup/teardown | Mount home, set limits |
Control Flags¶
| Flag | Behavior |
|---|---|
required | Must succeed, but continue checking other modules |
requisite | Must succeed, fail immediately if not |
sufficient | If succeeds, stop checking (unless required failed) |
optional | Only matters if it's the only module |
include | Include another PAM configuration |
Configuration Files¶
File Locations¶
/etc/pam.d/
├── common-auth # Authentication
├── common-account # Account management
├── common-password # Password changes
├── common-session # Session management
├── common-session-noninteractive
├── login # Console login
├── sshd # SSH daemon
├── sudo # sudo command
└── su # su command
Configuration Format¶
Password Policies¶
Install Password Quality Module¶
Configure Password Complexity¶
Edit /etc/security/pwquality.conf:
# Minimum password length
minlen = 14
# Require at least one digit
dcredit = -1
# Require at least one uppercase
ucredit = -1
# Require at least one lowercase
lcredit = -1
# Require at least one special character
ocredit = -1
# Maximum consecutive same characters
maxrepeat = 3
# Maximum consecutive characters from same class
maxclassrepeat = 4
# Check for words from GECOS field
gecoscheck = 1
# Disallow usernames in passwords
usercheck = 1
# Dictionary check (requires cracklib-runtime)
dictcheck = 1
# Minimum difference from old password
difok = 5
# Number of recent passwords to remember
remember = 12
# Reject passwords containing dictionary words
enforcing = 1
Enable in PAM¶
Verify /etc/pam.d/common-password includes:
password requisite pam_pwquality.so retry=3
password [success=1 default=ignore] pam_unix.so obscure use_authtok try_first_pass yescrypt remember=12
Password Aging¶
Configure in /etc/login.defs:
# Maximum days before password must be changed
PASS_MAX_DAYS 90
# Minimum days between password changes
PASS_MIN_DAYS 7
# Days before expiry to warn user
PASS_WARN_AGE 14
Apply to existing users:
# Set for specific user
sudo chage -M 90 -m 7 -W 14 username
# View current settings
sudo chage -l username
Account Lockout¶
Install Faillock Module¶
Ubuntu 24.04 uses pam_faillock (replaced pam_tally2):
Configure Lockout Policy¶
Create /etc/security/faillock.conf:
# Number of failed attempts before lockout
deny = 5
# Lockout duration in seconds (600 = 10 minutes)
unlock_time = 600
# Time window for counting failures (seconds)
fail_interval = 900
# Also lock root account
even_deny_root = true
# Lockout duration for root
root_unlock_time = 60
# Audit failed attempts
audit
# Silent mode (don't reveal account existence)
silent
# Directory for failure records
dir = /var/run/faillock
Enable Faillock in PAM¶
Edit /etc/pam.d/common-auth:
# Add before pam_unix
auth required pam_faillock.so preauth
auth [success=1 default=ignore] pam_unix.so nullok
# Add after pam_unix
auth [default=die] pam_faillock.so authfail
auth sufficient pam_faillock.so authsucc
Edit /etc/pam.d/common-account:
Manage Locked Accounts¶
# View failed login attempts
sudo faillock --user username
# Reset failed count (unlock)
sudo faillock --user username --reset
# View all users with failed attempts
sudo faillock
Access Time Restrictions¶
Configure Time-Based Access¶
Edit /etc/security/time.conf:
# Format: services;ttys;users;times
# Allow login only during business hours
login;*;!admin;Al0800-1800
# Restrict specific user
sshd;*;contractor;Wk0900-1700
# Allow admin anytime
*;*;admin;Al0000-2400
Enable Time Module¶
Add to /etc/pam.d/common-auth:
Time Format¶
| Code | Meaning |
|---|---|
| Su | Sunday |
| Mo | Monday |
| Tu | Tuesday |
| We | Wednesday |
| Th | Thursday |
| Fr | Friday |
| Sa | Saturday |
| Wk | Weekdays |
| Wd | Weekend |
| Al | All days |
Resource Limits¶
Configure Limits¶
Edit /etc/security/limits.conf:
# Limit maximum processes
* soft nproc 1024
* hard nproc 2048
# Limit open files
* soft nofile 4096
* hard nofile 65535
# Limit memory (KB)
* soft as 4194304
* hard as 8388608
# Core dumps
* soft core 0
* hard core 0
# Specific user limits
developer soft nproc 4096
developer hard nproc 8192
# Group limits (prefix @)
@developers soft nofile 8192
Enable Limits in PAM¶
Usually already enabled in /etc/pam.d/common-session:
Common Limit Types¶
| Type | Description |
|---|---|
| nproc | Max user processes |
| nofile | Max open files |
| memlock | Max locked memory |
| as | Max address space |
| core | Core dump size (0 disables) |
| cpu | CPU time limit |
| fsize | Max file size |
Session Security¶
Configure Session Options¶
Edit /etc/pam.d/common-session:
# Log session open/close
session required pam_unix.so
# Set resource limits
session required pam_limits.so
# Set environment
session required pam_env.so
# Create home directory if missing
session optional pam_mkhomedir.so skel=/etc/skel umask=077
# Last login notification
session optional pam_lastlog.so showfailed
# Notify on new mail
session optional pam_mail.so standard
umask for New Sessions¶
Set default umask in /etc/pam.d/common-session:
Or in /etc/login.defs:
Two-Factor Authentication¶
Google Authenticator¶
Install the module:
Configure for each user:
Answer prompts: - Time-based tokens: yes - Update .google_authenticator: yes - Disallow multiple uses: yes - Increase time skew: no - Rate limiting: yes
Enable in PAM (e.g., /etc/pam.d/sshd):
Update SSH configuration /etc/ssh/sshd_config:
U2F/FIDO2¶
Install the module:
Register key:
# Create config directory
mkdir -p ~/.config/Yubico
# Register U2F key
pamu2fcfg > ~/.config/Yubico/u2f_keys
# Touch the key when prompted
Enable in PAM:
Debugging PAM¶
Enable Debug Logging¶
Temporarily add debug to module arguments:
View PAM Logs¶
# Authentication logs
sudo tail -f /var/log/auth.log
# System messages
sudo journalctl -f | grep pam
Test PAM Configuration¶
# Test SSH PAM config
sudo pamtester sshd username authenticate
# Test sudo PAM config
sudo pamtester sudo username authenticate acct_mgmt
Common Issues¶
"Authentication failure" despite correct password:
# Check PAM configuration syntax
# Look for typos in /etc/pam.d/ files
grep -r "required" /etc/pam.d/ | head
# Check module exists
ls -la /lib/x86_64-linux-gnu/security/pam_unix.so
"Module is unknown":
# Module not installed
sudo apt install libpam-<module>
# Check available modules
ls /lib/x86_64-linux-gnu/security/
Security Recommendations¶
PAM Best Practices¶
| Practice | Implementation |
|---|---|
| Strong passwords | pam_pwquality with strict requirements |
| Account lockout | pam_faillock with reasonable thresholds |
| Audit logging | pam_tty_audit for command logging |
| Resource limits | pam_limits to prevent DoS |
| 2FA for sensitive access | pam_google_authenticator or pam_u2f |
Avoid Common Mistakes¶
| Mistake | Risk |
|---|---|
| nullok without reason | Allows blank passwords |
| sufficient before required | May skip required checks |
| Missing modules | Silent authentication bypass |
| Overly strict lockout | Self-DoS vulnerability |
Test Changes Carefully¶
Before deploying PAM changes:
- Keep an active root session open
- Test in a secondary terminal
- Have recovery plan (boot media)
- Document changes
Quick Reference¶
Common Modules¶
| Module | Purpose |
|---|---|
| pam_unix | Traditional Unix authentication |
| pam_pwquality | Password complexity |
| pam_faillock | Account lockout |
| pam_limits | Resource limits |
| pam_time | Time-based access |
| pam_env | Environment variables |
| pam_mkhomedir | Create home directories |
| pam_google_authenticator | TOTP 2FA |
| pam_u2f | U2F/FIDO2 authentication |
Key Files¶
| File | Purpose |
|---|---|
| /etc/pam.d/* | Service-specific PAM config |
| /etc/security/pwquality.conf | Password complexity |
| /etc/security/faillock.conf | Lockout policy |
| /etc/security/limits.conf | Resource limits |
| /etc/security/time.conf | Access time restrictions |
| /etc/login.defs | Login defaults |
Next Steps¶
Continue to systemd to learn about service management and hardening.