Practice Use drills for recall and labs for real operating judgment.

LAB-USER-05 - Password & Aging Controls

Understand how Linux hashes and stores passwords, and master the chage tool to enforce enterprise password rotation policies.

USR User & Group Management

Password & Aging Controls

Understand how Linux hashes and stores passwords, and master the chage tool to enforce enterprise password rotation policies.

30 min INTERMEDIATE LINUX Curriculum-reviewed
Success criteria
  • Understand how Linux hashes and stores passwords, and master the chage tool to enforce enterprise password rotation policies.
  • Repeat the workflow without copy-paste or step-by-step prompting.
Safety notes
  • Use throwaway accounts or a lab VM when creating, deleting, or modifying users and groups.

Part A: The Field Guide


🎯 What & Why

In corporate environments (Enterprise Linux), you don’t just set a password and forget it. Security compliance (like SOC2 or HIPAA) dictates strict rules:

  • Passwords must be changed every 90 days.
  • Users must be warned 7 days before it expires.
  • If a contractor leaves, their account must automatically expire on exactly November 1st.

Before you can enforce these rules, you must understand exactly where and how passwords live on the system.


🧠 Mental Model: The /etc/shadow File

In the old days, passwords were encrypted and stored right inside /etc/passwd. Because every program needs to read /etc/passwd to translate UIDs to Names, hackers could easily read the encrypted passwords and take them offline to crack them.

Linux fixed this by moving the passwords into a vault: /etc/shadow.

  1. /etc/passwd is world-readable.
  2. /etc/shadow is unreadable by anyone except root. It contains the actual cryptographic hashes and the aging controls.

A line in /etc/shadow looks like this: dave:$6$xyz123HashValueGarbage:19254:0:90:7:14::

If you try to read this manually, your eyes will glaze over. The numbers 19254, 90, 7 represent days since 1970, expiration limits, and warning days. You NEVER edit this file by hand. You use the chage command to manipulate it.


📖 Command Reference

passwd (Change Hash)

Changes the password (the hash) for a user. Normal users can run passwd to change their own. Root can run sudo passwd username to change anyone’s password, bypassing all current-password checks.

Locking an account

$ # Lock an account (adds a ’!’ to the hash in /etc/shadow, making login impossible) $ sudo passwd -l dave

$ # Unlock it $ sudo passwd -u dave

$ # Force Dave to change his password the next time he logs in $ sudo passwd -e dave

chage (Change Aging)

The primary tool for managing password expiration policies.

Viewing age info

$ sudo chage -l dave Last password change : Sep 20, 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

Setting enterprise policies:

  • -M 90 (Max days: Must change password every 90 days)
  • -m 2 (Min days: Cannot change password again for 2 days. Prevents users from changing it 5 times in a row to get back to their old favorite password).
  • -W 14 (Warning: Start nagging the user 14 days before expiration).
  • -E 2026-12-31 (Account perfectly locks out at midnight on New Year’s Eve).

💡 Password Expiration vs Account Expiration

Password Expiration (-M): The user must pick a new password to continue. They are not fired, they just need an update.
Account Expiration (-E): The account goes completely dead on a specific date. The user cannot log in, even if their password is valid. Used for Contractors and Temps.


🌍 Real Scenarios

Scenario 1: The Panic Lockout You detect suspicious activity on Dave’s account. He’s asleep and you can’t ask him. You instantly run: sudo passwd -l dave. This scrambles his hash in /etc/shadow temporarily. His SSH keys might still work (if configured), but any password-based access is dead. When he wakes up, you unlock it: sudo passwd -u dave.

Scenario 2: “Reset my password” A user forgets their password. As root, you cannot extract their old password. Hashes are one-way math functions. You can only overwrite it. sudo passwd alice -> Type new password -> sudo passwd -e alice (forces her to pick her own private password the moment she uses the temporary one you gave her).

Scenario 3: The Summer Intern You hire “Intern Bob”. He starts June 1st, leaves August 31st. You create his account and immediately future-proof it: sudo chage -E "2026-08-31" bob You no longer have to worry about forgetting to delete his access in September. The kernel handles it.


⚠️ Gotchas & Pitfalls

  1. Epoch Time — If you try to read /etc/shadow directly, the dates are integers like 19254. This is “Epoch Time” (the number of days since January 1, 1970). It is unreadable to humans. Always use chage -l username to format these integers into real dates.
  2. Deleting passwords vs locking passwords
    • passwd -l locks the account safely.
    • passwd -d deletes the password entirely. DANGER! This allows the user to log in simply by hitting ENTER when asked for a password. Never use this on a public-facing server.

Part B: The Drill Deck

Terminal Required: Open your Linux terminal for these exercises. You will need sudo.


G
Guided Step by step - type exactly this and compare the result
>

Exercise G1: The Shadow Vault

  1. Try to read the vault as a normal user: cat /etc/shadow.
  2. Observe the “Permission denied” error. Security is working.
  3. Read it as root: sudo cat /etc/shadow
  4. Look through the list. Accounts with an * or ! in the second column are system accounts explicitly locked out of password logins.
  5. Find your personal username. You should see a massive, unrecognizable string of gibberish starting with $y$ or $6$. That is your cryptographically hashed password.

Exercise G2: Reading Policies

  1. Let’s look at your current password policy nicely formatted.
  2. Run: sudo chage -l $USER
  3. Notice that “Maximum number of days” is likely 99999. This means your Linux box is configured for home use — passwords never expire.

Exercise G3: The First-Login Flow

  1. Create a temporary user: sudo useradd -m temp_worker
  2. Set a dummy password: sudo passwd temp_worker (Type password123 twice).
  3. Now force them to change it on their first day: sudo passwd -e temp_worker
  4. Confirm the forced change flag. Run sudo chage -l temp_worker. Look at the top line: “Last password change”. It should say password must be changed.
S
Solo Task described, hints available - figure it out
>

Exercise S1: Enforcing Corporate Constraints

You are tasked with bringing the temp_worker account into strict corporate compliance.

Using chage, modify temp_worker with the following parameters in a single command (or multiple if you prefer):

  • Passwords expire every 60 days.
  • Users cannot change passwords more than once every 3 days.
  • Warn them 10 days before expiration.

Hint: check chage --help or man chage to remember the uppercase vs lowercase flag letters! Verify your work with sudo chage -l temp_worker.

Exercise S2: The Panic Lock

  1. Lock the temp_worker account using the passwd command.
  2. Verify they are locked by grepping /etc/shadow: sudo grep "temp_worker" /etc/shadow
  3. Notice the ! injected right at the front of the hash string. That ! invalidates the math.
  4. Unlock the account.
  5. Check /etc/shadow again and notice the ! is gone.
M
Mission Real scenario - no hints, combine multiple skills
>

Mission M1: The Date Formatter

The -E flag in chage sets an absolute account expiration date. It expects the format YYYY-MM-DD.

Your company has a strict rule: All contractor accounts must expire exactly on December 31st of the current year.

However, you are writing an automated script and you don’t want to hardcode “2026” because the script will break next year.

Combine your knowledge of the date command with command substitution $(...) to formulate a single command that evaluates the current year dynamically, appends “-12-31”, and sets the expiration date for temp_worker.

Hint: date +%Y prints the current year as a 4-digit number.

(After formulating and testing this, clean up by running sudo userdel -r temp_worker).