chage command is used to change user password expiry information. It allows system administrators to manage password aging policies, enforce password changes, and control account expiration dates.
Display all password aging information for a user account:
sudo chage -l username
Sample Output:
Last password change : Jan 15, 2026 Password expires : Apr 15, 2026 Password inactive : never Account expires : never Minimum number of days between password change : 0 Maximum number of days between password change : 90 Number of days of warning before password expires: 7
What it does: Lists all password aging parameters including last change date, expiration dates, and policy settings. This is essential for auditing user accounts and ensuring compliance with security policies.
Force a password to expire on a specific date:
sudo chage -E 2026-12-31 username
What it does: Sets the account expiration date to December 31, 2026. After this date, the user will be unable to login until the administrator reactivates the account. Use format YYYY-MM-DD.
chage -E -1 username to remove the account expiration date and make the account permanent.
Require user to change password at next login:
sudo chage -d 0 username
What it does: Sets the date of last password change to zero (January 1, 1970), which forces the system to require a password change at the next login. This is commonly used for:
Configure how long a password remains valid:
sudo chage -M 90 username
What it does: Sets the maximum number of days a password is valid to 90 days. After 90 days, the user must change their password. Common settings:
Prevent users from changing passwords too frequently:
sudo chage -m 7 username
What it does: Sets the minimum number of days between password changes to 7. Users must wait at least 7 days before changing their password again. This prevents users from:
Configure advance warning before password expires:
sudo chage -W 14 username
What it does: Users will receive warnings 14 days before their password expires. They'll see a message at login like:
Warning: your password will expire in 10 days
This gives users adequate time to plan for password changes without being surprised by sudden expiration.
Lock account after password expires and remains unchanged:
sudo chage -I 30 username
What it does: After the password expires, the account will be locked if the user doesn't change it within 30 days. This provides a grace period where:
Configure all password aging settings interactively:
sudo chage username
Interactive prompts:
Changing the aging information for username
Enter the new value, or press ENTER for the default
Minimum Password Age [0]: 7
Maximum Password Age [99999]: 90
Last Password Change (YYYY-MM-DD) [2026-01-15]:
Password Expiration Warning [7]: 14
Password Inactive [-1]: 30
Account Expiration Date (YYYY-MM-DD) [-1]: 2027-12-31
What it does: Provides an interactive menu to set all password aging parameters at once. Press ENTER to keep current value or type new value to change it.
Apply consistent password policies to multiple users:
#!/bin/bash
# apply-password-policy.sh - Enforce standard password aging
POLICY_MAX_DAYS=90
POLICY_MIN_DAYS=7
POLICY_WARN_DAYS=14
POLICY_INACTIVE=30
# Read usernames from file or argument
USERS_FILE=${1:-/tmp/users.txt}
while IFS= read -r username; do
echo "Applying policy to: $username"
# Set maximum password age
sudo chage -M $POLICY_MAX_DAYS "$username"
# Set minimum password age
sudo chage -m $POLICY_MIN_DAYS "$username"
# Set warning period
sudo chage -W $POLICY_WARN_DAYS "$username"
# Set inactivity period
sudo chage -I $POLICY_INACTIVE "$username"
echo "Policy applied to $username"
echo "---"
done &li; "$USERS_FILE"
echo "Password policy enforcement complete!"
Usage:
echo -e "john\nmary\nbob" > /tmp/users.txt bash apply-password-policy.sh /tmp/users.txt
This script ensures consistent password aging across all user accounts.
Generate comprehensive password aging report for all users:
#!/bin/bash
# password-audit-report.sh - Generate password aging compliance report
OUTPUT_FILE="password_audit_$(date +%Y%m%d).txt"
echo "Password Aging Compliance Report" > $OUTPUT_FILE
echo "Generated: $(date)" >> $OUTPUT_FILE
echo "========================================" >> $OUTPUT_FILE
echo "" >> $OUTPUT_FILE
# Get all regular users (UID >= 1000)
getent passwd | awk -F: '$3 >= 1000 && $3 < 65534 {print $1}' | while read username; do
echo "User: $username" >> $OUTPUT_FILE
# Get password aging info
sudo chage -l "$username" >> $OUTPUT_FILE
# Check for compliance issues
MAX_DAYS=$(sudo chage -l "$username" | grep "Maximum" | awk '{print $NF}')
WARN_DAYS=$(sudo chage -l "$username" | grep "warning" | awk '{print $NF}')
if [ "$MAX_DAYS" -gt 90 ] || [ "$MAX_DAYS" == "99999" ]; then
echo "⚠️ WARNING: Password max age exceeds policy (90 days)" >> $OUTPUT_FILE
fi
if [ "$WARN_DAYS" -lt 7 ]; then
echo "⚠️ WARNING: Warning period below recommended (7 days)" >> $OUTPUT_FILE
fi
echo "----------------------------------------" >> $OUTPUT_FILE
echo "" >> $OUTPUT_FILE
done
echo "Report generated: $OUTPUT_FILE"
cat $OUTPUT_FILE
What it produces: A comprehensive audit report showing all users' password aging settings and highlighting any policy violations. Essential for compliance audits and security reviews.
| Option | Description | Example |
|---|---|---|
-l |
List password aging information | chage -l john |
-d DAYS |
Set days since last password change (0 forces change) | chage -d 0 john |
-E DATE |
Set account expiration date (YYYY-MM-DD, -1 = never) | chage -E 2027-12-31 john |
-I DAYS |
Set password inactive period after expiration | chage -I 30 john |
-m DAYS |
Set minimum days between password changes | chage -m 7 john |
-M DAYS |
Set maximum days password is valid | chage -M 90 john |
-W DAYS |
Set warning days before password expiration | chage -W 14 john |
-h |
Display help message | chage -h |
sudo chage -M 90 -m 7 -W 14 -I 30 username
sudo chage -M 60 -m 1 -W 7 -I 7 username
sudo chage -M 99999 -m 0 -W 0 -I -1 -E -1 serviceaccount
System-wide default password aging policies:
PASS_MAX_DAYS 90 # Maximum password age PASS_MIN_DAYS 7 # Minimum password age PASS_MIN_LEN 8 # Minimum password length PASS_WARN_AGE 14 # Warning days before expiration
/etc/login.defs only apply to newly created users. Use chage to modify existing users.
Where password aging information is stored:
username:$6$encrypted_password:18993:7:90:14:30:19724:
Fields (colon-separated):
chage -d 0)-E to set automatic expiration for contractor accounts# Check if account is locked sudo chage -l username # If inactive period exceeded, unlock account sudo passwd -u username # Allow user to change password sudo chage -d 0 username
# Set last change date to today sudo chage -d $(date +%Y-%m-%d) username
sudo chage -M 99999 -m 0 -W 0 -I -1 -E -1 username
| Task | Command |
|---|---|
| View aging info | sudo chage -l username |
| Force password change | sudo chage -d 0 username |
| Set 90-day expiration | sudo chage -M 90 username |
| Set account expiry date | sudo chage -E 2027-12-31 username |
| Disable password expiry | sudo chage -M 99999 username |
| Set all parameters interactively | sudo chage username |