CrackOps
Interview PrepTracksLinuxAWS LabSoonInterview RoomSoon
Sign inStart free
CrackOps

Interview prep for the people who keep production up.

[email protected]
ProductInterview PrepTracksDashboardInterview Room
RolesDevOpsSREPlatformCloud
CompanyAboutContactPrivacyTerms
© CrackOps
Linux / Users & Groups / chage

chage

Manage password aging and account expiry

Intermediateuserssecuritycompliance

chage reads and sets the aging fields in /etc/shadow: when a password must be changed, how much warning the user gets, how long after expiry the account stays usable, and the date the whole account expires. It's how you enforce rotation policies and time-boxed contractor access.

Syntaxchage [-l] [-M MAX] [-m MIN] [-W WARN] [-I INACTIVE] [-E DATE] [-d LASTDAY] LOGIN

Watch it run

An auditor asks whether passwords on devops-lab ever expire.

devops@devops-lab: ~ — zsh — 96×28
➜ ~
Step 1 of 3
sudo chage -l priya

Ubuntu's defaults: 99999 days maximum means the password never expires, and the account never expires either.

Anatomy of a command

$
prefixsudo

Changing aging fields writes /etc/shadow, so it needs root. chage -l on yourself doesn't.

How it works

Every /etc/shadow line carries aging fields after the hash: last change (days since 1970-01-01), minimum days between changes, maximum days, warning days, inactive days and account expiry (also days since 1970). chage just rewrites those numbers; -l translates them into dates. Nothing runs on a timer: the checks happen at login, in PAM's account phase (pam_unix). If today is past last-change + max, the user is told to change the password before getting a shell; if it's also past the inactive period, or past the account expiry date, the login is refused for every method, SSH keys included. -d 0 sets last change to day 0, which forces a change at next login. Ubuntu's defaults (max 99999, i.e. never) come from PASS_MAX_DAYS and friends in /etc/login.defs and only apply to newly created users.

Options you'll actually use

-lList the aging information in readable form
-M DAYSMaximum days a password is valid (-1 removes the limit)
-m DAYSMinimum days between changes (stops instant reuse)
-W DAYSDays of warning before the password expires
-I DAYSDays after password expiry before the account is disabled
-E DATEAccount expiry date (YYYY-MM-DD); -E -1 removes it
-d 0Set last change to 1970: force a change at next login
(no option)Interactive mode: prompts for each value

Common mistakes

Editing PASS_MAX_DAYS in /etc/login.defs and assuming existing users now expire

login.defs is only read when an account is created. Existing shadow entries keep their values.

sudo chage -M 90 USER for each existing user (loop over getent passwd with UID >= 1000)
Using password expiry (-M) to cut off a contractor on a date

An expired password just forces a change; the user picks a new one and carries on.

sudo chage -E 2026-12-31 USER (account expiry blocks every login)
Forcing -M 90 on a service account used by automation

When it expires, cron jobs and deploys that use the account can fail at night.

Service accounts: no password (locked), key or token auth, chage -M -1

Interview questions

Practice

Try these on a Linux machine of your own. Each task has a hint and a solution.

  1. 1

    Show the aging information for devops.

  2. 2

    Create user temp5 and require a password change every 60 days with 10 days' warning.

  3. 3

    Make temp5's account expire on 2026-12-31, then remove the expiry again.

  4. 4

    Force temp5 to change its password at next login and show the raw shadow fields.

Related commands

passwdSet or change a user's passwordusermodChange an existing user accountuseraddCreate a user account
PreviousgroupsNextsu
Linux / Users & Groups / chage

chage

Manage password aging and account expiry

Intermediateuserssecuritycompliance

chage reads and sets the aging fields in /etc/shadow: when a password must be changed, how much warning the user gets, how long after expiry the account stays usable, and the date the whole account expires. It's how you enforce rotation policies and time-boxed contractor access.

Syntaxchage [-l] [-M MAX] [-m MIN] [-W WARN] [-I INACTIVE] [-E DATE] [-d LASTDAY] LOGIN

Watch it run

An auditor asks whether passwords on devops-lab ever expire.

devops@devops-lab: ~ — zsh — 96×28
➜ ~
Step 1 of 3
sudo chage -l priya

Ubuntu's defaults: 99999 days maximum means the password never expires, and the account never expires either.

Anatomy of a command

$
prefixsudo

Changing aging fields writes /etc/shadow, so it needs root. chage -l on yourself doesn't.

How it works

Every /etc/shadow line carries aging fields after the hash: last change (days since 1970-01-01), minimum days between changes, maximum days, warning days, inactive days and account expiry (also days since 1970). chage just rewrites those numbers; -l translates them into dates. Nothing runs on a timer: the checks happen at login, in PAM's account phase (pam_unix). If today is past last-change + max, the user is told to change the password before getting a shell; if it's also past the inactive period, or past the account expiry date, the login is refused for every method, SSH keys included. -d 0 sets last change to day 0, which forces a change at next login. Ubuntu's defaults (max 99999, i.e. never) come from PASS_MAX_DAYS and friends in /etc/login.defs and only apply to newly created users.

Options you'll actually use

-lList the aging information in readable form
-M DAYSMaximum days a password is valid (-1 removes the limit)
-m DAYSMinimum days between changes (stops instant reuse)
-W DAYSDays of warning before the password expires
-I DAYSDays after password expiry before the account is disabled
-E DATEAccount expiry date (YYYY-MM-DD); -E -1 removes it
-d 0Set last change to 1970: force a change at next login
(no option)Interactive mode: prompts for each value

Common mistakes

Editing PASS_MAX_DAYS in /etc/login.defs and assuming existing users now expire

login.defs is only read when an account is created. Existing shadow entries keep their values.

sudo chage -M 90 USER for each existing user (loop over getent passwd with UID >= 1000)
Using password expiry (-M) to cut off a contractor on a date

An expired password just forces a change; the user picks a new one and carries on.

sudo chage -E 2026-12-31 USER (account expiry blocks every login)
Forcing -M 90 on a service account used by automation

When it expires, cron jobs and deploys that use the account can fail at night.

Service accounts: no password (locked), key or token auth, chage -M -1

Interview questions

Practice

Try these on a Linux machine of your own. Each task has a hint and a solution.

  1. 1

    Show the aging information for devops.

  2. 2

    Create user temp5 and require a password change every 60 days with 10 days' warning.

  3. 3

    Make temp5's account expire on 2026-12-31, then remove the expiry again.

  4. 4

    Force temp5 to change its password at next login and show the raw shadow fields.

Related commands

passwdSet or change a user's passwordusermodChange an existing user accountuseraddCreate a user account
PreviousgroupsNextsu