LearnRHCSA (EX200)Users and Groups

Password Aging with chage

chage - a hands-on Linux lab on a real virtual machine.

Manage a local user password aging rules with chage. Read the full report with chage -l NAME, set the maximum valid days with -M, the minimum days between changes with -m, the warning window with -W, and a hard account-expiry date with -E YYYY-MM-DD, then force a password change at the next login with chage -d 0 NAME. Rules live in /etc/shadow, so chage runs as root. Serves EX200 users-and-groups: manage user password aging.

A contractor account was created eight months ago for a two-week job. The contractor left, but the account is still there, still with a valid password, still able to log in. Nobody set it to expire, because nobody knew how. That single forgotten account is exactly the kind of finding a security audit lives to catch, and it is the kind of thing the exam asks you to prevent.

Every local user carries a set of password aging rules: how long a password stays valid, how often it must change, how much warning the user gets, and when the whole account switches off. These rules are not set when you type passwd. They live in a separate place, and the tool that reads and writes them is chage. This lesson takes you from reading an account's aging report to forcing a password change at the next login, which is the most-tested aging task on the whole exam.

The black boxes below are a practice terminal: a safe sandbox that checks the one command each step teaches. The outputs are from a real RHEL 10 machine (AlmaLinux 10.2) running as root, with a user alice created just before the capture. The dates in the aging report, like the last-change date, depend on when the account was made, so treat those as illustrative. What is stable everywhere is the SHAPE: chage -l prints a seven-line report, the default maximum is 99999, and the default warning is 7.

chage stands for change age. It is the tool that manages the aging rules on a local user's password: the dates and day-counts that decide when a password must change and when an account expires. Think of it as the expiry sticker on a carton of milk. The milk is the password; chage is who writes the sell-by date and decides how many days of warning you get before it turns.

The passwd command sets what the password IS. chage sets the rules around it: how long it lives, how often it must rotate, when the account itself shuts off. These are two different jobs. You cannot set an account expiry date with passwd, and you cannot change a password's text with chage. Knowing which tool owns which job is half the battle.

In real work, aging rules are how you enforce policy without babysitting people. A company policy might say passwords must change every 90 days with a week of warning; you encode that once with chage and the system enforces it forever. A contractor's account should die on a known date; you set that date once and forget it. And when you reset a user's forgotten password, you often want to force them to pick their own at next login rather than keep the temporary one you chose. Every one of those is a chage one-liner.

On the exam, the aging task is almost always phrased as a policy: set a maximum, set a warning, expire an account on a date, or force a reset. You read the numbers off the task and hand them to chage. The reading tool comes first, so start there.

Before you change anything, you read what is already there. The -l flag (for list) prints a full aging report for one user: seven lines covering the last change, the three expiry dates, and the three day-count policies. This is the command you run first on every aging task, and the command you run last to confirm your change took.

Before you run it, know what success looks like: seven labeled lines, not an error. Read alice's aging report:

chage -l alice

prompt: [root@servera ~]# answer: chage -l alice output: Last password change : Jul 05, 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 hint: The list flag is -l, then the username: chage -l alice

Seven lines, and each one is a rule. Last password change is the day the password was last set, the anchor every other date counts from. Password expires, Password inactive, and Account expires all read never here, which is the default for a fresh account. The three day-counts at the bottom are the policy: Minimum 0 means the user can change the password again immediately, Maximum 99999 means the password effectively never has to change (that number is roughly 273 years), and Number of days of warning 7 means the user gets a week of nagging before an expiry. A brand-new user has no real limits; your job is to write them.

The Last password change date reads Jul 05, 2026 here because that is when this account was made on the capture machine. Yours will show whatever day the account you inspect was created or last had its password set. The dates move; the seven labels and their order do not.

Now the writing side. Two flags carry most exam tasks. -M sets the maximum number of days a password stays valid before the user must change it. -W sets the warning window: how many days ahead of that deadline the user starts getting reminded. You can set both in one command by listing both flags before the username.

A common policy is a 90-day maximum with a 7-day warning. Apply it to alice:

chage -M 90 -W 7 alice

prompt: [root@servera ~]# answer: chage -M 90 -W 7 alice output: hint: -M sets the max days, -W sets the warn days, then the user: chage -M 90 -W 7 alice

No output, which is success: chage is silent when a set works. The password now expires 90 days after its last change, and alice will start seeing warnings 7 days before that. To confirm, you would run chage -l alice again and watch Maximum number of days flip from 99999 to 90 and Password expires change from never to a real date 90 days out. There are two more setters worth knowing before the challenge: -m for the minimum days between changes, and -E for a hard account-expiry date.

Two setters finish the toolkit. -m (lowercase) sets the minimum number of days that must pass before a user is allowed to change the password again; it stops someone from cycling through a required change back to their old password in one sitting. -E (uppercase) sets a hard account expiry date: on that day the whole account switches off and can no longer log in, no matter what the password says. That is the contractor kill-switch from the opening scene.

-E takes a date in YYYY-MM-DD form. To expire an account at the end of 2026, you would run chage -E 2026-12-31 alice. To lift an expiry you set it to -1, which means never. The exam loves the account-expiry task because it maps straight to a real security requirement: this account must not work after this date.

Do not confuse -m and -M. Lowercase -m is the minimum days between changes; uppercase -M is the maximum days a password lives. They are opposite ends of the same window and a single case slip sets the wrong one. Read the case out loud before you press Enter: little-m is minimum, big-M is maximum.

chage writes these rules into /etc/shadow, the same protected file passwd writes the hashed password into. That is why every chage command here runs as root: an ordinary user cannot read or write another account's shadow entry. On the exam you are root, so this is never an obstacle, but it explains why the tool needs privilege.

The single most common aging task, and the one to burn in, is forcing a user to change their password the next time they log in. You do it by setting the last change date to day zero of the epoch with -d 0. That instantly marks the password as older than any maximum, so the system demands a new one before it lets the user in.

This is the natural finish to a password reset: you set a temporary password with passwd, then force the user to replace it. Force alice to reset at next login:

chage -d 0 alice

prompt: [root@servera ~]# answer: chage -d 0 alice output: hint: -d sets the last-change date; 0 means the epoch, so it is already expired: chage -d 0 alice

Silent success again. Setting the last-change date to 0 (January 1, 1970) makes the password instantly older than any maximum, so RHEL forces alice to choose a new one at her very next login, before she reaches a shell. Running chage -l alice now shows Last password change as a date in 1970 and, if a maximum is set, Password expires as a date already in the past. This is how you hand someone a temporary password without letting them keep it.

Scaffolding off. No command is printed this time. You have every piece you need.

You have just reset a user's forgotten password to a temporary value with passwd. Policy says the user must not keep that temporary password: they have to choose their own the instant they log in next. You are not setting a maximum, not setting an expiry date, not touching the warning window. You need the account's password to count as already expired right now, so the login itself demands a fresh one. Which single chage command, given the username alice, forces that reset at next login?

prompt: [root@servera ~]# answer: chage -d 0 alice output: hint: You want the last-change date, not the max. The flag is -d and the value that means already-expired is 0: chage -d 0 alice

chage -d 0 alice sets the last-change date to the epoch, which makes the password instantly expired, so alice is forced to set a new one at her next login. Not -M, which sets a future deadline; not -E, which kills the whole account on a date. -d 0 is the precise tool for force a reset now. Pair it with passwd to reset, then -d 0 to force, and you have the complete password-reset handoff the exam expects.

You earned this cheat sheet. Every row is a form you just ran or built:

The one thing to burn in for the exam: chage -d 0 NAME forces a reset at next login, and lowercase -m is minimum while uppercase -M is maximum. Read the report first with -l, make your change, then read it again to confirm.

Every aging rule you set with chage lands in /etc/shadow, so you can read a raw account's aging fields there too, but chage -l is far easier to read and is the answer the exam wants. When a task says confirm the aging is set, run chage -l NAME and read the labeled line, do not go parsing colon-separated shadow fields by hand.

The practice terminal has walked you through the whole loop. chage -l to read an account's aging report, -M and -W to set the maximum and warning, -m and -E for the minimum and the account kill-switch, and -d 0 to force a password change at next login. Every one of those you typed yourself.

Operation Roster, the users-groups capstone, is where you run these against a real RHEL 10 machine. A full VM boots for you, with its own real accounts to age and expire. The mission hands you objectives that use exactly what you practiced here. Read an account's aging with chage -l, apply a maximum and a warning to enforce a policy, set an account-expiry date on a contractor, and force a reset at next login. One difference from this lesson: the mission shows no commands. You read the objective, recall the chage flag you need, and type it. That recall is what makes it stick on exam day.

Finish the other users-groups lessons, then take on Operation Roster and age some real accounts.

Practice Password Aging with chage in a real Linux terminal at The Linux Camp. Progress is verified automatically as you type commands on the machine.