Table of Contents
Why Password Policies Matter
Password policies define how user passwords must be created, stored, and maintained on a system. On Linux servers, they help:
- Reduce the risk of weak or reused passwords
- Limit the time a compromised password is useful (expiration)
- Enforce lockouts or delays to slow brute‑force attacks
- Provide consistent security across all users
This chapter focuses on configuring and inspecting password policies on typical Linux systems. User and group concepts, sudo, and basic account management are covered in other chapters.
Core Elements of a Password Policy
Common policy elements you’ll encounter:
- Minimum length — e.g., at least 12 characters
- Complexity — mix of character types (uppercase, lowercase, digits, symbols)
- Password history — prevent reuse of last N passwords
- Aging — how long a password is valid
- Minimum days before it can be changed again
- Maximum days before it must be changed
- Warning period before expiration
- Account / password lockout — lock account or delay login after repeated failures
Linux implements these using Pluggable Authentication Modules (PAM) plus a few configuration files and tools.
Files and Tools Related to Password Policies
You’ll work mainly with:
/etc/login.defs— default password aging and related settings/etc/pam.d/*— PAM configs where password rules and lockouts are enforced/etc/security/*— extra policy configs (e.g.,pwquality.conf,faillock.conf)/etc/shadow— stores hashed passwords and per‑account aging data
CLI tools:
passwd— change passwords and some account-level password settingschage— view and modify password aging for individual accountsfaillockorpam_tally2(older) — inspect/clear login failure counters
Password Aging: System‑Wide Defaults with `login.defs`
/etc/login.defs sets defaults applied when new users are created (e.g., via useradd). It does not usually retroactively change existing accounts.
Key directives (values differ by distro):
PASS_MAX_DAYS— max days before a password must be changedPASS_MIN_DAYS— min days between password changesPASS_WARN_AGE— days before expiration when user is warned
Example:
PASS_MAX_DAYS 90
PASS_MIN_DAYS 1
PASS_WARN_AGE 7This means:
- A new user’s password will expire after 90 days.
- It can’t be changed more than once per day.
- They’ll start seeing a warning 7 days before expiration.
To apply to existing users, use chage (next section), not just login.defs.
Per‑User Password Aging with `chage`
chage (change age) manages password aging on a per‑account basis. It works with data stored in /etc/shadow.
Viewing a user’s password policy
sudo chage -l usernameExample output:
Last password change : Aug 20, 2025
Password expires : Nov 18, 2025
Password inactive : never
Account expires : never
Minimum number of days between password change : 1
Maximum number of days between password change : 90
Number of days of warning before password expires : 7Setting aging values
Common options:
-M DAYS— set max days before password must be changed-m DAYS— set min days between changes-W DAYS— warning period-E DATE— account expiration date (not just password)-I DAYS— days after password expiration until account is disabled (inactive)
Examples:
Set a 90‑day max, 1‑day min, 7‑day warning:
sudo chage -M 90 -m 1 -W 7 usernameForce a user to change password at next login:
sudo chage -d 0 usernameSet account to expire on a specific date:
sudo chage -E 2025-12-31 usernameThis is useful for temporary accounts or contractors.
Password Complexity and Strength (PAM `pam_pwquality` / `pam_cracklib`)
Password complexity is enforced via PAM password modules. On most modern systems:
- RHEL / CentOS / Rocky / Alma / Fedora — use
pam_pwqualityand/orpam_faillock - Debian / Ubuntu — may use
pam_pwqualityor olderpam_cracklib
Rules are configured in:
/etc/security/pwquality.conf(or/etc/security/pam_pwquality.confon some distros)- And referenced from
/etc/pam.d/system-auth,/etc/pam.d/password-auth, or/etc/pam.d/common-password(Debian/Ubuntu)
Example: `pam_pwquality` configuration
Typical pam_pwquality.conf options:
minlen— minimum lengthdcredit— digit credit (negative values require digits)ucredit— uppercase creditlcredit— lowercase creditocredit— other (symbol) creditretry— number of tries when setting a new password
Example configuration:
# /etc/security/pwquality.conf
minlen = 12
dcredit = -1
ucredit = -1
lcredit = -1
ocredit = -1
retry = 3This means:
- Password must be at least 12 characters.
- Must contain at least one digit, one uppercase, one lowercase, and one symbol.
- User gets 3 tries when changing password.
These rules are enforced because PAM includes something like:
password requisite pam_pwquality.so retry=3
in the appropriate /etc/pam.d/* file (exact file names differ by distro).
Password History (Preventing Reuse)
Password history stops users from cycling back to recent passwords. This is implemented by pam_unix.so with the remember option, or by pam_pwhistory.so on some systems.
Example snippet (RHEL/Fedora style, in /etc/pam.d/system-auth or /etc/pam.d/password-auth):
password sufficient pam_unix.so sha512 shadow remember=5
This remembers the last 5 passwords and prevents reuse. You’ll find similar configuration in Debian‑based systems, sometimes via pam_unix or pam_pwhistory.
Common points:
- Only affects future password changes (history starts from now).
- History is stored in
/etc/security/opasswd(forpam_unixwithremember).
Account Lockout and Failed Login Policies
Lockout policies reduce the risk of brute‑force attacks by:
- Locking an account after a certain number of failed logins
- Or adding delays between attempts
Implementation differs by distro.
`pam_faillock` (RHEL / Fedora / many modern distros)
Configuration files:
/etc/security/faillock.conf— central config- Integrated via
pam_faillock.soin/etc/pam.d/system-authandpassword-auth
Typical options:
deny— allowed number of failed logins before lockoutunlock_time— seconds before automatic unlock (0 = until manually unlocked)fail_interval— time window in seconds to count failures
Example faillock.conf:
# /etc/security/faillock.conf
deny = 5
unlock_time = 600
fail_interval = 900This means:
- 5 failed logins within 15 minutes (
fail_interval = 900) trigger a lock. - Account is locked for 10 minutes (
unlock_time = 600).
Managing faillock state
View failures:
sudo faillockView for a specific user:
sudo faillock --user username
Clear failures (e.g., to unlock before unlock_time):
sudo faillock --user username --resetOlder approaches: `pam_tally2` and `pam_faildelay`
On older systems, pam_tally2 may be used instead of pam_faillock to count failed logins and lock accounts. Another module, pam_faildelay, can introduce a delay after a failed login, slowing brute‑force attempts.
While still seen in older setups, new deployments should favor pam_faillock (or distro‑recommended defaults).
System Password Hashing and Policy Considerations
Although hashing is more of an internal/security topic, it’s directly tied to password policy:
- Hash algorithms are configured in PAM (usually
pam_unix.sooptions). - Common secure hashes:
sha512(standard), sometimesyescryptorargon2on newer distros.
Example PAM line:
password sufficient pam_unix.so sha512 shadowFrom a policy perspective:
- Use a strong hash algorithm (avoid older
md5,descrypt). - Prefer distro defaults unless you have a strong reason to change.
Forcing Password Changes and Locking Passwords
In addition to aging and lockout rules, you’ll sometimes need to:
- Force users to pick a new password
- Temporarily disable password login for an account
Force a user to change password
Two common methods:
- Set password to expire now:
sudo chage -d 0 usernameUser must change password at next login.
- With some tools (e.g.,
passwd):
sudo passwd -e username
(-e = expire password immediately; availability may vary by distro.)
Lock and unlock passwords
Lock password (disables password-based login but doesn’t remove the account):
sudo passwd -l usernameUnlock:
sudo passwd -u usernameThis is useful for temporarily disabling accounts without deleting them, but note:
- SSH keys or other auth methods may still work; this only affects password authentication.
Practical Policy Design Tips
When designing policies for real systems:
- Balance security and usability:
- Very short expiration (e.g., 30 days) can lead to weaker behaviors (users writing passwords down).
- Very complex requirements can cause support overhead.
- Prefer longer, memorable passphrases over short complex strings; adjust
minlenaccordingly. - Use history and lockout to prevent trivial reuse and brute force.
- Avoid disabling all password logins unless you fully rely on SSH keys and understand the implications.
- Document your policy so users know what to expect and administrators configure systems consistently.
Verifying Password Policy on Your System
To understand the current policy on a given system:
- Check defaults:
- View
/etc/login.defsfor aging defaults. - Inspect per‑user settings:
sudo chage -l username- Check complexity rules:
grep -E 'pwquality|cracklib' /etc/pam.d/* /etc/pam.d/common-password 2>/dev/null- View
/etc/security/pwquality.conf - Check history and hashing:
- Look for
pam_unix.solines in/etc/pam.d/*and note options likeremember=,sha512. - Inspect lockout rules:
- Look for
pam_faillock.soorpam_tally2in/etc/pam.d/* - View
/etc/security/faillock.confif present. - Test as a non‑privileged user:
- Try changing to a simple password and see what errors you get; messages often show which rules apply.
Understanding how these pieces fit together lets you implement and audit password policies that match your organization’s security requirements.