chage Command

Change user password expiry information and manage password aging policies for enhanced system security.

Syntax

chage [OPTIONS] USERNAME chage -l USERNAME chage -E EXPIRE_DATE USERNAME

The chage command modifies user account password expiration and aging information stored in /etc/shadow.

Common Options

Option Description
-l List password aging information
-E DATE Set account expiration date (YYYY-MM-DD)
-M DAYS Set maximum password age in days
-m DAYS Set minimum password age in days
-W DAYS Set password warning period in days
-I DAYS Set password inactive period in days
-d DATE Set last password change date
--help Display help information

Basic Usage

View password aging information

# List password aging info for user sudo chage -l john sudo chage -l alice # View current user's info (if allowed) chage -l $USER # Check multiple users for user in john alice bob; do echo "=== $user ===" sudo chage -l $user echo done

Display password aging information for users

Set account expiration

# Set account to expire on specific date sudo chage -E 2024-12-31 john sudo chage -E 2025-06-30 alice # Remove account expiration (set to never expire) sudo chage -E -1 john # Set account to expire immediately sudo chage -E 0 tempuser # Set expiration to 90 days from now sudo chage -E $(date -d "+90 days" +%Y-%m-%d) john

Set account expiration dates

Set password aging policies

# Set maximum password age (90 days) sudo chage -M 90 john # Set minimum password age (1 day) sudo chage -m 1 john # Set warning period (7 days before expiration) sudo chage -W 7 john # Set inactive period (30 days after expiration) sudo chage -I 30 john # Combine multiple settings sudo chage -M 90 -m 1 -W 7 -I 30 john

Configure password aging policies

Advanced Usage

Force password change

# Force user to change password on next login sudo chage -d 0 john # Set last password change to specific date sudo chage -d 2024-01-01 john # Set last change to yesterday (forces change) sudo chage -d $(date -d "yesterday" +%Y-%m-%d) john # Remove password aging (set to never changed) sudo chage -d -1 john

Force password changes and set change dates

Interactive mode

# Run chage interactively sudo chage john # This will prompt for: # - Minimum password age # - Maximum password age # - Last password change # - Password expiration warning # - Password inactive # - Account expiration date

Use interactive mode to set all parameters

Bulk user management

#!/bin/bash # Set standard password policy for all users set_password_policy() { local username=$1 sudo chage -M 90 -m 1 -W 7 -I 30 "$username" echo "Password policy set for $username" } # Apply to multiple users users=("john" "alice" "bob" "charlie") for user in "${users[@]}"; do if id "$user" &>/dev/null; then set_password_policy "$user" else echo "User $user does not exist" fi done # Set expiration for temporary accounts temp_users=("temp1" "temp2" "guest") expire_date=$(date -d "+30 days" +%Y-%m-%d) for user in "${temp_users[@]}"; do if id "$user" &>/dev/null; then sudo chage -E "$expire_date" "$user" echo "Set $user to expire on $expire_date" fi done

Manage multiple users with scripts

Practical Examples

Security compliance

# Corporate security policy implementation # Standard employee account sudo chage -M 90 -m 1 -W 14 -I 7 employee1 # Contractor account (expires in 6 months) sudo chage -E $(date -d "+6 months" +%Y-%m-%d) contractor1 sudo chage -M 30 -m 1 -W 7 -I 3 contractor1 # Service account (no expiration, long password age) sudo chage -E -1 -M 365 -m 0 -W 30 serviceaccount # Temporary account (expires in 1 week) sudo chage -E $(date -d "+1 week" +%Y-%m-%d) tempuser sudo chage -M 7 -m 0 -W 1 -I 1 tempuser

Implement security compliance policies

User onboarding script

#!/bin/bash onboard_user() { local username=$1 local user_type=$2 local duration=${3:-"permanent"} case $user_type in employee) # Standard employee policy sudo chage -M 90 -m 1 -W 14 -I 7 "$username" sudo chage -E -1 "$username" # No expiration echo "Employee $username configured with standard policy" ;; contractor) # Contractor policy sudo chage -M 60 -m 1 -W 7 -I 3 "$username" if [ "$duration" != "permanent" ]; then expire_date=$(date -d "+$duration" +%Y-%m-%d) sudo chage -E "$expire_date" "$username" echo "Contractor $username expires on $expire_date" fi ;; temp) # Temporary user policy sudo chage -M 30 -m 0 -W 3 -I 1 "$username" expire_date=$(date -d "+30 days" +%Y-%m-%d) sudo chage -E "$expire_date" "$username" echo "Temporary user $username expires on $expire_date" ;; *) echo "Unknown user type: $user_type" return 1 ;; esac # Force password change on first login sudo chage -d 0 "$username" } # Usage examples onboard_user "john.doe" "employee" onboard_user "jane.contractor" "contractor" "6 months" onboard_user "guest123" "temp"

Automated user onboarding with different policies

Password audit script

#!/bin/bash audit_passwords() { echo "=== Password Aging Audit ===" echo "Date: $(date)" echo # Get all regular users (UID >= 1000) while IFS=: read -r username _ uid _ _ _ _; do if [ "$uid" -ge 1000 ] && [ "$uid" -lt 65534 ]; then echo "User: $username" # Get password aging info aging_info=$(sudo chage -l "$username" 2>/dev/null) if [ $? -eq 0 ]; then echo "$aging_info" | while read -r line; do echo " $line" done # Check for issues last_change=$(echo "$aging_info" | grep "Last password change" | cut -d: -f2 | xargs) account_expires=$(echo "$aging_info" | grep "Account expires" | cut -d: -f2 | xargs) if [ "$last_change" = "never" ]; then echo " WARNING: Password never changed" fi if [ "$account_expires" != "never" ]; then expire_date=$(date -d "$account_expires" +%s 2>/dev/null) current_date=$(date +%s) if [ "$expire_date" -lt "$current_date" ]; then echo " WARNING: Account expired" fi fi else echo " ERROR: Cannot read password aging info" fi echo fi done < /etc/passwd } audit_passwords

Audit password aging for all users

Best Practices

chage Usage Best Practices
  • Implement consistent password aging policies across the organization
  • Set appropriate warning periods to give users time to change passwords
  • Use account expiration for temporary and contractor accounts
  • Force password changes for new accounts and after security incidents
  • Regular audit of password aging settings
  • Document password policies and communicate them to users
  • Consider service accounts separately from user accounts
Security Considerations
  • Root access required - chage requires sudo/root privileges
  • Service accounts - Be careful with automated service accounts
  • User notification - Inform users about password policy changes
  • Backup access - Ensure admin access isn't accidentally locked
  • Compliance - Align policies with organizational requirements

See also