TechEarl

Linux Password Expiry: Force a Change and Manage chage Aging

Force a password change, inspect and undo aging settings, and distinguish password expiry from account expiry, including SSH/PAM caveats.

Ishan Karunaratne⏱️ 5 min readUpdated
Share thisCopied
Set password maximum age, warning period, and account expiry date on Linux with chage, and read current aging with chage -l.
bash
sudo chage -l deploy
sudo chage -d 0 deploy

The first command shows the account's aging fields. The second requires a password change at the next login that enforces local password aging. For a temporary password, set it with sudo passwd deploy first, then expire it with chage -d 0 or passwd -e.

chage changes local shadow-password aging information. It does not administer an LDAP or other external identity provider. SSH and service behavior also depends on their authentication and account-check configuration.

Inspect password and account age

bash
sudo chage -l deploy

A user can inspect their own account with chage -l "$USER"; changing another user's settings needs root. Record the existing values before editing them, particularly the last-change date and account-expiry date.

Terminal showing chage aging fields and an example maximum-age and account-expiry configuration.
Read every field after a change; password expiry and account expiry are separate controls.

Require a password change at next login

bash
sudo passwd deploy       # set a temporary password interactively, if needed
sudo chage -d 0 deploy   # require it to be changed
sudo chage -l deploy

An alternative for the expiry step is:

bash
sudo passwd -e deploy

Both mark the password as expired. A supported interactive login usually asks the user to change it before starting the session. An unattended process or file-transfer client may fail instead because it cannot complete the password-change conversation. Test that the user's actual login path can handle the reset before handing over a temporary credential.

This does not revoke access in the way an offboarding process does. A successful password change normally lets the user continue.

Undo an accidental expiry

Restore the original last-change date you recorded. If you deliberately want the policy to treat today as the last change, use:

bash
sudo chage -d "$(date +%F)" deploy
sudo chage -l deploy

This changes the aging record; it does not change the password. Setting it to today extends the life of the existing password, so it is not a remedy for a compromised credential. In that case, replace the password itself.

Set aging and account expiry

OptionMeaning
-M DAYSMaximum age measured from the last password change
-m DAYSMinimum days between password changes
-W DAYSWarning period before password expiry
-I DAYSDays after password expiry before inactivity disables access
-E YYYY-MM-DDAccount-expiry date, independent of password age

For an environment whose documented policy requires aging, an example is:

bash
sudo chage -M 90 -m 1 -W 7 -I 14 deploy
sudo chage -E 2026-12-31 deploy
sudo chage -l deploy

These numbers demonstrate the options; they are not a universal password recommendation. NIST's current guidance rejects routine forced rotation and calls for a change when there is evidence of compromise. Apply the policy appropriate to the system, rather than adopting 90 days because an example uses it.

Changing -M can expire an existing password immediately if its last-change date is already too old. -m can also prevent a user from changing a recently set password, so check the complete combination rather than adjusting one field in isolation.

To remove individual limits deliberately:

bash
sudo chage -M -1 deploy   # no maximum password age
sudo chage -I -1 deploy   # no post-expiry inactivity limit
sudo chage -E -1 deploy   # no account-expiry date

Removing a limit does not undo every other setting; inspect the result with chage -l.

Password expiry vs account expiry

Password expiry is a request to replace the credential. Account expiry is a date-based denial enforced by services that check the account's aging information.

bash
sudo chage -E 1970-01-02 deploy

This puts the account-expiry date unambiguously in the past. Avoid an account-expiry value of 0: the shadow-file manual warns that consumers can interpret it as either no expiration or 1970-01-01. It is useful for blocking new logins through services that honor local account expiry, but it does not terminate existing sessions, revoke API tokens, remove scheduled jobs or guarantee every external service checks /etc/shadow. For offboarding, revoke the relevant keys/tokens and sessions as well. See locking and unlocking Linux accounts.

passwd -l or usermod -L locks the password. Do not describe that alone as disabling every possible authentication method.

SSH keys and PAM account checks

A key login skips password authentication, but it does not necessarily skip password-age checks. OpenSSH with UsePAM yes applies PAM account and session processing to all authentication types, including public keys. Depending on the PAM stack and client, an expired password can trigger a reset requirement or prevent the session from opening.

An administrator can inspect the daemon's effective setting without changing it:

bash
sudo sshd -T | grep -i '^usepam '

Conditional Match rules may need sshd -T -C with the relevant connection parameters for an accurate effective configuration. Keep an existing administrator session open while testing a separate login. Do not turn PAM off merely to make an expiry prompt disappear.

Set the policy for new users

chage changes an existing account. For accounts created with shadow-utils useradd, the PASS_MAX_DAYS, PASS_MIN_DAYS and PASS_WARN_AGE values in /etc/login.defs provide defaults. Existing users are unaffected.

Distribution wrappers, configuration-management tools and external identity providers can apply their own policy. Verify an actual test account created through the same provisioning path instead of assuming one file controls every new user.

FAQ

Both expire the local password so a login that enforces aging requires a change. Neither is a complete account-revocation command.

Not necessarily. With UsePAM enabled, OpenSSH still runs account checks for public-key authentication. The PAM configuration and client determine whether the session requires a password change or fails.

Yes. The maximum is measured from its recorded last-change date. If that date is already older than the new maximum, the password can expire immediately.

See also

Sources

Authoritative references this article was fact-checked against.

TagsLinuxchagePasswordAccount AgingSecurity

Found this useful? Pass it on.

Copied

Ishan Karunaratne

Systems and Network Architect · Chief Technology Officer

Systems and network architect and Chief Technology Officer with more than two decades designing, building, and running production software, cloud and network architecture, Linux systems, and the bare metal underneath them, and lately working AI into the stack. A US Army veteran who served in Operation Iraqi Freedom. What I write here is drawn from the full arc of that work, across architecture, engineering, and operations, not any single job.

Keep reading

Related posts