How To

Configure Password Aging and Expiry Policy in Linux

Every Linux system with user accounts needs a password policy. Without one, users keep the same password forever, increasing the risk of compromised credentials going undetected. Password aging forces regular password changes and locks inactive accounts automatically – a basic but important part of Linux server security.

Original content from computingforgeeks.com - post 46585

This guide covers how to configure password aging, expiry, and complexity policies on Ubuntu 24.04, Debian 13, RHEL 10, and Rocky Linux 10. We use chage for per-user settings, /etc/login.defs for system-wide defaults, and PAM pwquality for password complexity enforcement.

Prerequisites

  • A server running Ubuntu 24.04, Debian 13, RHEL 10, or Rocky Linux 10
  • Root access or a user with sudo privileges
  • At least one non-root user account for testing

Step 1: Check Current Password Aging Information

Before making changes, check the current password aging settings for a user with the chage command. This shows all password and account expiry details at once.

sudo chage -l username

The output shows the current password aging policy applied to that user account:

Last password change                                    : Mar 22, 2026
Password expires                                        : never
Password inactive                                       : never
Account expires                                         : never
Minimum number of days between password change          : 0
Maximum number of days between password change          : 99999
Number of days of warning before password expires       : 7

A Maximum number of days value of 99999 means the password never expires. The Minimum number of days at 0 means the user can change their password at any time. These are the defaults on most Linux distributions and are not suitable for production systems.

Step 2: Set Password Expiry with chage

The chage command controls all password aging parameters for individual user accounts. Here are the most common settings you will need.

Set Maximum Password Age

Force a user to change their password every 90 days:

sudo chage -M 90 username

Set Minimum Password Age

Prevent a user from changing their password more than once every 7 days. This stops users from cycling through passwords to get back to an old one:

sudo chage -m 7 username

Set Password Expiry Warning

Give the user a 14-day warning before their password expires:

sudo chage -W 14 username

Set Password Inactive Period

Disable the account 30 days after the password expires if the user has not changed it. This is the grace period between password expiry and account lock:

sudo chage -I 30 username

Apply All Settings at Once

Set all password aging parameters in a single command – 90-day max age, 7-day minimum, 14-day warning, and 30-day inactive period:

sudo chage -M 90 -m 7 -W 14 -I 30 username

Verify the changes took effect:

sudo chage -l username

The output now reflects the new password policy for this user:

Last password change                                    : Mar 22, 2026
Password expires                                        : Jun 20, 2026
Password inactive                                       : Jul 20, 2026
Account expires                                         : never
Minimum number of days between password change          : 7
Maximum number of days between password change          : 90
Number of days of warning before password expires       : 14

Step 3: Set Default Password Policy in login.defs

The chage command sets policy per user. To define defaults that apply to all newly created users, edit /etc/login.defs. Existing users are not affected by changes to this file – you still need chage for those.

Open the file for editing:

sudo vi /etc/login.defs

Find and update the following password aging parameters:

# Maximum number of days a password may be used
PASS_MAX_DAYS   90

# Minimum number of days allowed between password changes
PASS_MIN_DAYS   7

# Number of days warning given before a password expires
PASS_WARN_AGE   14

# Minimum acceptable password length
PASS_MIN_LEN    12

Save the file and exit. Any user account created after this change will inherit these defaults. To apply the same policy to existing users, use the chage command from Step 2 on each account.

Step 4: Configure Password Complexity with PAM pwquality

Password aging alone is not enough – you also need to enforce password complexity so users cannot set weak passwords. The pam_pwquality module handles this on modern Linux distributions.

Install libpam-pwquality

On Ubuntu and Debian, install the pwquality PAM module:

sudo apt install libpam-pwquality -y

On RHEL 10 and Rocky Linux 10, the package is already installed by default. If not, install it with:

sudo dnf install libpwquality -y

Configure Password Complexity Rules

Edit the pwquality configuration file:

sudo vi /etc/security/pwquality.conf

Add or update these settings to enforce strong passwords. If you want to learn more, check our guide on how to set strong password policy on Ubuntu and Debian Linux:

# Minimum password length
minlen = 12

# Require at least 1 digit
dcredit = -1

# Require at least 1 uppercase letter
ucredit = -1

# Require at least 1 lowercase letter
lcredit = -1

# Require at least 1 special character
ocredit = -1

# Reject passwords containing the username
usercheck = 1

# Number of retries before returning error
retry = 3

# Reject passwords that match dictionary words
dictcheck = 1

Save the file. The settings take effect immediately for the next password change. The dcredit, ucredit, lcredit, and ocredit values use negative numbers – a value of -1 means “require at least 1 character of this type.”

Verify PAM Configuration

Confirm that the pwquality module is included in the PAM password stack. On Ubuntu/Debian:

grep pwquality /etc/pam.d/common-password

You should see a line similar to this, confirming pwquality is active:

password    requisite    pam_pwquality.so retry=3

On RHEL 10 and Rocky Linux 10, check the system-auth file instead:

grep pwquality /etc/pam.d/system-auth

Step 5: Force User to Change Password at Next Login

After creating a new user account or resetting a password, force the user to set a new password on their next login. This is standard practice when provisioning accounts.

sudo chage -d 0 username

This sets the last password change date to epoch 0 (January 1, 1970), which makes the password immediately expired. When the user logs in via SSH or console, they will be prompted to change their password before they can proceed.

Verify the forced change is set:

sudo chage -l username

The output shows the password must be changed:

Last password change                                    : password must be changed
Password expires                                        : password must be changed
Password inactive                                       : password must be changed
Account expires                                         : never
Minimum number of days between password change          : 7
Maximum number of days between password change          : 90
Number of days of warning before password expires       : 14

You can also use the passwd command to expire a password immediately:

sudo passwd -e username

Step 6: Lock and Unlock User Accounts

Locking an account disables password authentication for that user without deleting the account. This is useful for temporary suspensions or when an employee leaves.

Lock a User Account

Lock the account using passwd:

sudo passwd -l username

Alternatively, use usermod:

sudo usermod -L username

Both commands add a ! prefix to the password hash in /etc/shadow, which prevents authentication. Verify the account is locked:

sudo passwd -S username

The second field shows L for locked:

username L 2026-03-22 7 90 14 30

Unlock a User Account

Unlock the account to restore access:

sudo passwd -u username

Or with usermod:

sudo usermod -U username

Important: Locking an account only blocks password-based login. If the user has SSH key authentication configured, they can still log in. To fully block access, also set the shell to /sbin/nologin or disable the account with chage -E 0 username.

Step 7: Set Account Expiration Date

Account expiration is different from password expiration. When an account expires, the user cannot log in at all – regardless of their password status. This is useful for contractor accounts or temporary access.

Set an account to expire on a specific date:

sudo chage -E 2026-12-31 username

Verify the expiration date:

sudo chage -l username

The account expiration now shows the set date:

Account expires                                         : Dec 31, 2026

To remove the expiration date and make the account permanent again:

sudo chage -E -1 username

You can also use usermod to set account expiration:

sudo usermod -e 2026-12-31 username

chage Command Options Reference

The following table summarizes the most useful chage options for managing password aging policy in Linux:

OptionDescriptionExample
-lList password aging informationchage -l username
-MSet maximum days between password changeschage -M 90 username
-mSet minimum days between password changeschage -m 7 username
-WSet days of warning before password expireschage -W 14 username
-ISet inactive days after password expireschage -I 30 username
-ESet account expiration date (YYYY-MM-DD)chage -E 2026-12-31 username
-dSet last password change date (0 forces change)chage -d 0 username

login.defs Password Parameters Reference

These parameters in /etc/login.defs control the default password aging policy for newly created user accounts:

ParameterDescriptionRecommended Value
PASS_MAX_DAYSMaximum number of days a password is valid90
PASS_MIN_DAYSMinimum days before a password can be changed7
PASS_WARN_AGEDays of warning before password expiry14
PASS_MIN_LENMinimum password length12
LOGIN_RETRIESMax login attempts before failure3
LOGIN_TIMEOUTMax seconds for login before timeout60
ENCRYPT_METHODPassword hashing algorithmYESCRYPT

Conclusion

You now have a working password aging and expiry policy on your Linux server. The combination of chage for per-user controls, /etc/login.defs for system-wide defaults, and pam_pwquality for complexity enforcement covers the essentials of password security on Ubuntu 24.04, Debian 13, RHEL 10, and Rocky Linux 10.

For production servers, pair these settings with SSH two-factor authentication, key-based SSH login instead of password auth, and account monitoring with tools like fail2ban. Audit your password policies periodically and adjust the aging values based on your organization’s security requirements.

Related Articles

Security How to Analyze Linux Malware and Phishing Threats Safely Security Install and Use Metasploit Framework on Kali Linux CentOS Boot CentOS / RHEL / Fedora into Emergency Recovery Security Install Nessus vulnerability Scanner on Kali Linux

Leave a Comment

Press ESC to close