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