Skip to content

Pam_authentication

PAM (Pluggable Authentication Modules) is a flexible framework for authentication in Linux systems. Instead of embedding authentication logic directly into applications, PAM allows system administrators to configure authentication methods without modifying applications. This chapter covers PAM architecture, configuration, module types, common modules, and practical examples for system authentication.


┌─────────────────────────────────────────────────────────────────────────┐
│ PAM ARCHITECTURE │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ APPLICATION LAYER │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │ login │ │ sshd │ │ su │ │ sudo │ │ │
│ │ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ │ │
│ │ │ │ │ │ │ │
│ └────────┼─────────────┼─────────────┼─────────────┼───────────────────┘ │
│ │ │ │ │ │
│ ▼ ▼ ▼ ▼ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ PAM LIBRARY (libpam) │ │
│ │ │ │
│ │ pam_start() - Initialize PAM session │ │
│ │ pam_authenticate() - Verify user identity │ │
│ │ pam_acct_mgmt() - Check account validity │ │
│ │ pam_open_session() - Start session │ │
│ │ pam_close_session() - End session │ │
│ │ pam_get_item() - Get PAM data │ │
│ │ pam_set_item() - Set PAM data │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ CONFIGURATION LAYER │ │
│ │ /etc/pam.d/ or /etc/pam.conf │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ MODULE LAYER │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ pam_unix │ │ pam_ldap │ │ pam_krb5 │ │ pam_sss │ │ │
│ │ │ pam_secure │ │ pam_tally│ │ pam_cifs │ │ pam_google│ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────┐
│ PAM MODULE TYPES │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ auth - Authentication │ │
│ │ ┌─────────────────────────────────────────────────────────┐ │ │
│ │ │ • Verify user identity (password, token, biometric) │ │ │
│ │ │ • Establish user credentials │ │ │
│ │ │ • pam_unix, pam_ldap, pam_krb5, pam_google_authenticator│ │ │
│ │ └─────────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ account - Account Verification │ │
│ │ ┌─────────────────────────────────────────────────────────┐ │ │
│ │ │ • Check if account is valid (not expired, allowed) │ │ │
│ │ │ • Check time restrictions, group membership │ │ │
│ │ │ • Check password expiration │ │ │
│ │ └─────────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ password - Password Management │ │
│ │ ┌─────────────────────────────────────────────────────────┐ │ │
│ │ │ • Update authentication tokens (password change) │ │ │
│ │ │ • Enforce password policies │ │ │
│ │ │ • Check password complexity │ │ │
│ │ └─────────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ │ session - Session Management │ │
│ │ ┌─────────────────────────────────────────────────────────┐ │ │
│ │ │ • Setup user environment (environment, limits) │ │ │
│ │ │ • Log session start/end │ │ │
│ │ │ • Mount directories, start services │ │ │
│ │ └─────────────────────────────────────────────────────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
│ Control Flags: │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ required - Must succeed, failure = final failure │ │
│ │ requisite - Must succeed, failure = immediate failure │ │
│ │ sufficient - Success = sufficient for auth │ │
│ │ optional - Result is ignored (informational) │ │
│ │ binding - Like required, but can be overridden │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘

Terminal window
# ============================================================
# PAM CONFIGURATION FILES
# ============================================================
# Global configuration (deprecated, rarely used)
/etc/pam.conf
# Service-specific configuration (recommended)
/etc/pam.d/
├── login # Terminal login
├── sshd # SSH daemon
├── sudo # sudo command
├── su # su command
├── passwd # password command
├── system-auth # Common auth settings (Red Hat)
├── common-auth # Common auth settings (Debian)
├── common-account # Common account settings
├── common-session # Common session settings
└── common-password # Common password settings
# Configuration file format:
# type control module-path module-arguments
# Example:
auth required pam_unix.so nullok
Terminal window
# ============================================================
# COMMON PAM MODULES
# ============================================================
# pam_unix.so - Traditional UNIX authentication
auth required pam_unix.so nullok
account required pam_unix.so
password required pam_unix.so obscure sha512
# pam_permit.so - Always permits (dangerous!)
auth required pam_permit.so
# pam_deny.so - Always denies
auth required pam_deny.so
# pam_securetty.so - Restricts root to secure tty
auth required pam_securetty.so
# pam_nologin.so - Blocks login when /etc/nologin exists
account required pam_nologin.so
# pam_limits.so - Apply resource limits
session required pam_limits.so
# pam_systemd.so - systemd session management
session required pam_systemd.so
# pam_umask.so - Set default file permissions
session optional pam_umask.so umask=0022
# pam_env.so - Set environment variables
session optional pam_env.so
# pam_faillock.so - Lock after failed attempts
auth required pam_faillock.so deny=3 unlock_time=600
# pam_selinux.so - SELinux integration
session required pam_selinux.so close
session required pam_selinux.so open

Terminal window
# ============================================================
# /etc/pam.d/login - Terminal Login
# ============================================================
#auth required pam_securetty.so # Only root on secure ttys
auth required pam_unix.so nullok
auth required pam_nologin.so # Check /etc/nologin
account required pam_unix.so # Account verification
account required pam_nologin.so
password required pam_unix.so obscure sha512 remember=5
session required pam_unix.so
session optional pam_lastlog.so failedlogin
session optional pam_mail.so standard noenv
# Alternative with more security:
# auth required pam_faillock.so preauth deny=3 unlock_time=600
# account required pam_faillock.so
Terminal window
# ============================================================
# /etc/pam.d/sshd - SSH Authentication
# ============================================================
# Authentication
auth required pam_sepermit.so
auth include password-auth
# Account verification
account required pam_nologin.so
account include password-auth
# Password management
password include password-auth
# Session management
session required pam_loginuid.so
session required pam_selinux.so close
session required pam_selinux.so open
session optional pam_keyinit.so force revoke
session required pam_limits.so
session include password-auth
session optional pam_systemd.so
Terminal window
# ============================================================
# /etc/pam.d/common-password - Password Policy
# ============================================================
password required pam_pwquality.so try_first_pass local_users_only retry=3 minlen=12 dcredit=-1 ucredit=-1 lcredit=-1 ocredit=-1 enforce_for_root
# Alternative with pam_unix:
password [success=1 default=ignore] pam_unix.so obscure sha512 remember=5
# Explanation of pam_pwquality options:
# minlen=12 - Minimum 12 characters
# dcredit=-1 - At least 1 digit
# ucredit=-1 - At least 1 uppercase
# lcredit=-1 - At least 1 lowercase
# ocredit=-1 - At least 1 special character
# enforce_for_root - Apply to root user too
# retry=3 - Prompt 3 times on failure
Terminal window
# ============================================================
# /etc/security/limits.conf - Resource Limits
# ============================================================
# Format: <domain> <type> <item> <value>
# Hard limits for all users
* hard core 0
* hard data unlimited
* hard fsize unlimited
* hard memlock unlimited
* hard nofile 65536
* hard cpu unlimited
* hard nproc unlimited
* hard as unlimited
# Soft limits (can be increased by user)
* soft fsize 2097152 # 2GB
* soft cpu 480 # 8 minutes
* soft nofile 4096
# Specific user/group
@developers soft nproc 8192
@developers hard nproc 16384
root - nofile 65536
# Apply limits for PAM sessions
# /etc/pam.d/sshd should have:
session required pam_limits.so

Terminal window
# ============================================================
# TWO-FACTOR AUTHENTICATION
# ============================================================
# Google Authenticator TOTP
# Install: pam_google_authenticator
# /etc/pam.d/sshd - Add to auth section
auth required pam_google_authenticator.so
# /etc/pam.d/login
auth required pam_google_authenticator.so
# Configuration per user:
# Run: google-authenticator
# Scan QR code, save secret key
# Copy ~/.google_authenticator to other machines
# YubiKey
# /etc/pam.d/sudo
auth required pam_yubico.so id=1 debug
auth required pam_unix.so use_first_pass
Terminal window
# ============================================================
# LDAP AUTHENTICATION
# ============================================================
# /etc/pam.d/system-auth (RHEL)
auth required pam_env.so
auth required pam_faildelay.so delay=2000000
auth [default=1 success=ok] pam_localuser.so
auth sufficient pam_unix.so nullok try_first_pass
auth requisite pam_succeed_if.so uid >= 1000 quiet_success
auth required pam_ldap.so use_first_pass
account sufficient pam_localuser.so
account sufficient pam_unix.so
account required pam_ldap.so use_first_pass
password requisite pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type=
password sufficient pam_unix.so sha512 shadow try_first_pass
password required pam_ldap.so use_first_pass
session optional pam_keyinit.so revoke
session required pam_limits.so
session optional pam_unix.so
session optional pam_ldap.so

┌─────────────────────────────────────────────────────────────────────────┐
│ PAM INTERVIEW QUESTIONS │
├─────────────────────────────────────────────────────────────────────────┤
Q1: What is PAM and why is it important? │
A1: │
PAM (Pluggable Authentication Modules): │
- Framework for authentication in Linux │
- Allows flexible authentication without modifying applications │
- Centralized authentication configuration │
- Supports multiple auth methods (password, LDAP, Kerberos, etc.) │
- Enables two-factor authentication │
─────────────────────────────────────────────────────────────────────────┤
Q2: What are the four PAM module types? │
A2: │
1. auth - Verify user identity (password, token, biometric) │
2. account - Check account validity (expiry, restrictions) │
3. password - Update passwords, enforce policies │
4. session - Setup/cleanup user environment │
─────────────────────────────────────────────────────────────────────────┤
Q3: Explain PAM control flags. │
A3: │
- required: Must succeed, failure = overall failure │
- requisite: Must succeed, failure = immediate failure │
- sufficient: Success = auth successful (if nothing else failed) │
- optional: Result ignored, for informational purposes │
- binding: Like required, but can be overridden with success= │
─────────────────────────────────────────────────────────────────────────┤
Q4: How do you configure password complexity requirements? │
A4: │
Use pam_pwquality.so or pam_cracklib: │
password required pam_pwquality.so minlen=12 dcredit=-1 \ ucredit=-1 lcredit=-1 ocredit=-1 │
Options: │
- minlen: Minimum length │
- dcredit: Digits required │
- ucredit: Uppercase required │
- lcredit: Lowercase required │
- ocredit: Special characters required │
─────────────────────────────────────────────────────────────────────────┤
Q5: How do you lock accounts after failed login attempts? │
A5: │
Use pam_faillock.so: │
auth required pam_faillock.so preauth deny=3 unlock_time=600 │
account required pam_faillock.so │
Or pam_tally2: │
auth required pam_tally2.so deny=3 unlock_time=600 │
─────────────────────────────────────────────────────────────────────────┤
Q6: What's the difference between /etc/pam.conf and /etc/pam.d/? │
A6: │
- /etc/pam.conf: Global config, deprecated │
- /etc/pam.d/: Service-specific configs (recommended) │
- /etc/pam.d/ is more flexible and is the modern approach │
- Allows different services to have different auth methods │
─────────────────────────────────────────────────────────────────────────┤
Q7: How do you set resource limits using PAM? │
A7: │
1. Configure /etc/security/limits.conf │
2. Add pam_limits.so to session in PAM config │
3. Example: * soft nofile 4096 │
4. Options: core, data, fsize, memlock, nofile, nproc, cpu, as │
5. Apply immediately with pam_limits.so │
─────────────────────────────────────────────────────────────────────────┤
Q8: How do you configure two-factor authentication? │
A8: │
1. Install pam_google_authenticator │
2. Configure user's secret: google-authenticator │
3. Add to PAM config: auth required pam_google_authenticator.so │
4. For SSH: also modify sshd_config to enable keyboard-interactive │
5. Works with TOTP apps (Google Authenticator, Authy, etc.) │
─────────────────────────────────────────────────────────────────────────┤
Q9: How does authentication differ between login, sshd, and sudo? │
A9: │
- login: Uses /etc/pam.d/login, checks /etc/nologin, secure tty │
- sshd: Uses /etc/pam.d/sshd, supports keyboard-interactive │
- sudo: Uses /etc/pam.d/sudo, may use pam_env for env vars │
- Each can have different auth requirements │
- All use same PAM framework but different configs │
─────────────────────────────────────────────────────────────────────────┤
Q10: How would you troubleshoot PAM authentication failures? │
A10: │
1. Check /var/log/secure (RHEL) or /var/log/auth.log (Debian) │
2. Enable debug in PAM config (debug flag) │
3. Verify PAM config syntax │
4. Test modules individually │
5. Check /etc/nologin and /etc/securetty │
6. Verify user account status (expired, locked) │
7. Use pamtest or manually test auth │
└─────────────────────────────────────────────────────────────────────────┘

Terminal window
# PAM Configuration
/etc/pam.d/ # Service configs
/etc/security/limits.conf # Resource limits
# Control flags
required # Must succeed
requisite # Must succeed, immediate fail
sufficient # Success = done
optional # Ignore result
# Module types
auth # Verify identity
account # Check account
password # Manage passwords
session # Manage sessions
# Common modules
pam_unix.so # Traditional UNIX
pam_ldap.so # LDAP
pam_krb5.so # Kerberos
pam_faillock.so # Lockout
pam_limits.so # Resource limits
pam_pwquality.so # Password policy

  • PAM: Pluggable Authentication Modules framework
  • Types: auth, account, password, session
  • Control: required, requisite, sufficient, optional
  • Config: /etc/pam.d/ service files
  • Modules: pam_unix, pam_ldap, pam_faillock, pam_limits

Chapter 11: File Permissions and Ownership


Last Updated: February 2026