Linux chage命令详解

chage(change age)命令用于修改用户密码的过期信息,可以设置密码的最后修改日期、过期日期、过期前的警告天数等,是Linux系统账户安全管理的重要工具。

一、命令简介

chage 命令用于管理用户密码的时效性,可以查看和修改用户的密码过期信息。通过合理配置密码过期策略,可以提高系统安全性,防止长期使用同一密码带来的安全风险。

特点: 增强账户安全、强制密码定期更换、提供密码过期警告、防止密码被长期使用。

二、安装chage

chage 命令是 shadow-utils 或 passwd 包的一部分,在大多数 Linux 发行版中默认已安装:

Ubuntu/Debian

# 通常已安装,如需安装可使用
sudo apt-get install passwd

CentOS/RHEL

# 通常已安装
# 如果未安装,可能是shadow-utils包的一部分
sudo yum install shadow-utils

验证安装

chage --version

三、基本语法

chage [选项] [用户名]

四、常用选项

选项 说明
-d, --lastday LAST_DAY 设置密码最后修改日期(自1970年1月1日以来的天数)
-E, --expiredate EXPIRE_DATE 设置账户过期日期(YYYY-MM-DD或自1970年1月1日以来的天数)
-h, --help 显示帮助信息
-I, --inactive INACTIVE 密码过期后账户被禁用的天数
-l, --list 显示账户时效信息
-m, --mindays MIN_DAYS 设置密码修改的最小间隔天数
-M, --maxdays MAX_DAYS 设置密码保持有效的最大天数
-W, --warndays WARN_DAYS 设置密码过期前的警告天数
--root CHROOT_DIR 在chroot目录中应用更改

五、密码时效参数详解

chage管理的密码时效参数
  • 密码最后修改日期(Last password change):用户最后一次修改密码的日期
  • 密码过期日期(Password expires):密码过期的具体日期
  • 密码失效日期(Password inactive):密码过期后账户被锁定的日期
  • 账户过期日期(Account expires):账户本身过期的日期
  • 最小间隔天数(Minimum number of days):两次密码修改之间的最小间隔天数
  • 最大有效天数(Maximum number of days):密码保持有效的最大天数
  • 警告天数(Number of days of warning):密码过期前开始警告的天数

六、使用示例

示例1:查看用户密码时效信息

# 查看当前用户的密码时效信息
chage -l $(whoami)

# 查看指定用户的密码时效信息
chage -l username

# 查看root用户的密码时效信息
sudo chage -l root

输出示例:

Last password change                                    : Jan 01, 2024
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

示例2:设置密码过期策略

# 设置密码最大有效期为90天
sudo chage -M 90 username

# 设置密码最小修改间隔为7天
sudo chage -m 7 username

# 设置密码过期前7天开始警告
sudo chage -W 7 username

# 组合设置多个参数
sudo chage -M 90 -m 7 -W 7 username

示例3:设置账户过期日期

# 设置账户在2024年12月31日过期
sudo chage -E 2024-12-31 username

# 使用天数设置账户过期(自1970年1月1日以来的天数)
sudo chage -E 20000 username

# 清除账户过期日期(设置为永不过期)
sudo chage -E -1 username

# 立即禁用账户(设置为昨天过期)
sudo chage -E $(date -d "yesterday" +%Y-%m-%d) username

示例4:设置密码最后修改日期

# 设置密码最后修改日期为今天
sudo chage -d $(date +%Y-%m-%d) username

# 强制用户下次登录时修改密码(将最后修改日期设置为1970年1月1日)
sudo chage -d 0 username

# 使用天数设置(自1970年1月1日以来的天数)
sudo chage -d 20000 username

示例5:设置密码过期后账户禁用时间

# 设置密码过期后30天禁用账户
sudo chage -I 30 username

# 禁用密码过期后账户禁用功能
sudo chage -I -1 username

# 立即锁定过期账户(设置为0)
sudo chage -I 0 username

示例6:交互式设置密码时效

# 交互式设置用户密码时效信息
sudo chage username

# 系统会提示输入各个参数的值
# 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) [2024-01-01]:
#     Password Expiration Warning [7]:
#     Password Inactive [-1]: 30
#     Account Expiration Date (YYYY-MM-DD) [1969-12-31]: 2024-12-31

示例7:批量设置用户密码策略

#!/bin/bash
# 批量设置多个用户的密码策略
USERS=("user1" "user2" "user3" "user4")

for USER in "${USERS[@]}"; do
    echo "设置用户 $USER 的密码策略..."
    sudo chage -M 90 -m 7 -W 7 "$USER"
    sudo chage -l "$USER" | grep -E "Maximum|Minimum|Warning"
    echo "---"
done

示例8:安全审计 - 检查密码过期账户

#!/bin/bash
# 检查所有用户的密码状态
echo "=== 密码过期检查 ==="
echo "检查时间: $(date)"
echo ""

# 获取所有普通用户(UID >= 1000)
getent passwd | awk -F: '$3 >= 1000 {print $1}' | while read USER; do
    echo "用户: $USER"
    sudo chage -l "$USER" 2>/dev/null | grep -E "expires|expired|Password inactive"
    echo ""
done

七、实用技巧

1. 强制用户下次登录时修改密码

# 方法1:使用chage命令
sudo chage -d 0 username

# 方法2:使用passwd命令
sudo passwd -e username

# 验证设置
sudo chage -l username | grep "Last password change"

2. 自动化密码策略管理

#!/bin/bash
# 自动化密码策略管理脚本
CONFIG_FILE="/etc/password_policy.conf"

# 读取配置文件(示例格式:用户名:最大天数:最小天数:警告天数)
# user1:90:7:7
# user2:60:5:5

while IFS=: read -r USER MAX_DAYS MIN_DAYS WARN_DAYS; do
    # 跳过注释行和空行
    [[ "$USER" =~ ^# ]] && continue
    [[ -z "$USER" ]] && continue

    echo "配置用户 $USER 的密码策略..."
    sudo chage -M "$MAX_DAYS" -m "$MIN_DAYS" -W "$WARN_DAYS" "$USER"

    # 记录日志
    echo "$(date): 已配置用户 $USER 的密码策略 (M:$MAX_DAYS, m:$MIN_DAYS, W:$WARN_DAYS)" >> /var/log/password_policy.log
done < "$CONFIG_FILE"

3. 密码过期预警系统

#!/bin/bash
# 密码过期预警脚本
WARNING_DAYS=7
ADMIN_EMAIL="admin@example.com"

# 检查所有用户
getent passwd | awk -F: '$3 >= 1000 {print $1}' | while read USER; do
    # 获取密码过期信息
    EXPIRY_INFO=$(sudo chage -l "$USER" 2>/dev/null)

    # 提取密码过期日期
    EXPIRY_DATE=$(echo "$EXPIRY_INFO" | grep "Password expires" | awk -F: '{print $2}' | xargs)

    if [ "$EXPIRY_DATE" != "never" ]; then
        # 计算剩余天数
        TODAY_EPOCH=$(date +%s)
        EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s)
        DAYS_LEFT=$(( (EXPIRY_EPOCH - TODAY_EPOCH) / 86400 ))

        if [ $DAYS_LEFT -le $WARNING_DAYS ] && [ $DAYS_LEFT -ge 0 ]; then
            # 发送警告
            echo "警告: 用户 $USER 的密码将在 $DAYS_LEFT 天后过期 ($EXPIRY_DATE)" | \
            mail -s "密码过期警告: $USER" "$ADMIN_EMAIL"

            # 也可以发送给用户自己
            USER_EMAIL="${USER}@example.com"
            echo "您的密码将在 $DAYS_LEFT 天后过期,请及时修改。" | \
            mail -s "密码即将过期通知" "$USER_EMAIL"
        fi
    fi
done

4. 账户生命周期管理

#!/bin/bash
# 临时账户管理脚本(例如:实习生账户)
INTERN_USERS=("intern1" "intern2" "intern3")
INTERN_END_DATE="2024-06-30"

# 设置实习生账户过期日期
for USER in "${INTERN_USERS[@]}"; do
    echo "设置实习生账户 $USER 的过期日期为 $INTERN_END_DATE"
    sudo chage -E "$INTERN_END_DATE" "$USER"

    # 设置密码策略(相对宽松)
    sudo chage -M 120 -m 1 -W 14 "$USER"
done

# 检查实习生账户状态
echo ""
echo "=== 实习生账户状态 ==="
for USER in "${INTERN_USERS[@]}"; do
    echo "用户: $USER"
    sudo chage -l "$USER" | grep -E "Account expires|Password expires"
done

5. 密码策略合规性检查

#!/bin/bash
# 密码策略合规性检查脚本
COMPLIANCE_LOG="/var/log/password_compliance.log"

# 定义合规性标准
MIN_MAX_DAYS=90     # 密码最大有效期不超过90天
MIN_MIN_DAYS=7      # 密码最小修改间隔不少于7天
MIN_WARN_DAYS=7     # 过期前警告不少于7天

echo "=== 密码策略合规性检查 ===" > "$COMPLIANCE_LOG"
echo "检查时间: $(date)" >> "$COMPLIANCE_LOG"
echo "" >> "$COMPLIANCE_LOG"

# 检查所有用户
getent passwd | awk -F: '$3 >= 1000 && $3 < 60000 {print $1}' | while read USER; do
    # 获取密码策略
    MAX_DAYS=$(sudo chage -l "$USER" 2>/dev/null | grep "Maximum" | awk -F: '{print $2}' | xargs)
    MIN_DAYS=$(sudo chage -l "$USER" 2>/dev/null | grep "Minimum" | awk -F: '{print $2}' | xargs)
    WARN_DAYS=$(sudo chage -l "$USER" 2>/dev/null | grep "Warning" | awk -F: '{print $2}' | xargs)

    # 检查合规性
    VIOLATIONS=()

    if [ "$MAX_DAYS" != "never" ] && [ "$MAX_DAYS" -gt "$MIN_MAX_DAYS" ]; then
        VIOLATIONS+=("密码有效期($MAX_DAYS天)超过$MIN_MAX_DAYS天")
    fi

    if [ "$MIN_DAYS" -lt "$MIN_MIN_DAYS" ]; then
        VIOLATIONS+=("密码修改间隔($MIN_DAYS天)少于$MIN_MIN_DAYS天")
    fi

    if [ "$WARN_DAYS" -lt "$MIN_WARN_DAYS" ]; then
        VIOLATIONS+=("过期警告($WARN_DAYS天)少于$MIN_WARN_DAYS天")
    fi

    # 记录违规
    if [ ${#VIOLATIONS[@]} -gt 0 ]; then
        echo "用户: $USER" >> "$COMPLIANCE_LOG"
        for VIOLATION in "${VIOLATIONS[@]}"; do
            echo "  ✗ $VIOLATION" >> "$COMPLIANCE_LOG"
        done
        echo "" >> "$COMPLIANCE_LOG"
    fi
done

echo "检查完成,结果已保存到 $COMPLIANCE_LOG"

6. 备份和恢复密码时效配置

#!/bin/bash
# 备份所有用户的密码时效配置
BACKUP_DIR="/backup/chage_config"
BACKUP_FILE="$BACKUP_DIR/chage_backup_$(date +%Y%m%d).txt"

# 创建备份目录
mkdir -p "$BACKUP_DIR"

echo "=== 密码时效配置备份 ===" > "$BACKUP_FILE"
echo "备份时间: $(date)" >> "$BACKUP_FILE"
echo "" >> "$BACKUP_FILE"

# 备份所有用户的配置
getent passwd | awk -F: '$3 >= 1000 {print $1}' | while read USER; do
    echo "[用户: $USER]" >> "$BACKUP_FILE"
    sudo chage -l "$USER" 2>/dev/null >> "$BACKUP_FILE"
    echo "" >> "$BACKUP_FILE"
done

echo "备份已完成: $BACKUP_FILE"

# 恢复配置示例(手动操作):
# 1. 查看备份文件
# 2. 使用chage命令重新设置每个用户的配置
# 例如:sudo chage -M 90 -m 7 -W 7 username

八、与其他密码管理工具对比

工具 主要功能 与chage的关系 使用场景
chage 管理密码时效/过期策略 核心工具 设置密码过期、账户过期、警告天数等
passwd 修改用户密码 配合使用(passwd -e 等价于 chage -d 0) 修改密码、锁定账户、设置密码策略
usermod 修改用户账户属性 功能部分重叠(账户过期) 修改用户主目录、shell、过期日期等
shadow 影子密码文件 chage操作的对象文件 直接编辑/etc/shadow文件(不推荐)
pam_cracklib/pam_pwquality 密码质量检查 补充chage的功能 强制密码复杂度要求

九、常见问题

Q: chage命令需要什么权限?

A: chage命令需要root权限来修改其他用户的密码时效信息:

# 查看自己的密码信息(不需要sudo)
chage -l $(whoami)

# 修改其他用户的密码信息(需要sudo)
sudo chage -M 90 username
Q: 如何取消密码过期限制?

A: 可以使用以下方法:

# 方法1:设置密码永不过期
sudo chage -M 99999 username

# 方法2:清除所有过期限制
sudo chage -M -1 -m 0 -I -1 -E -1 username

# 方法3:交互式设置
sudo chage username
# 在交互模式中将Maximum Password Age设置为-1
Q: 密码过期和账户过期有什么区别?

A: 重要区别:

  • 密码过期:用户密码失效,用户无法使用旧密码登录,但可以设置新密码
  • 账户过期:整个账户被锁定,用户无法登录,即使有正确的密码
  • 密码失效:密码过期后,账户还可以登录一段时间(由-I参数指定)
# 示例:
sudo chage -E 2024-12-31 username  # 账户在2024年底过期
sudo chage -M 90 username          # 密码90天后过期
sudo chage -I 7 username           # 密码过期后7天账户被锁定
Q: chage设置后立即生效吗?

A: 是的,chage的设置立即生效,但用户可能需要重新登录才能看到变化。某些设置(如密码过期)会在用户下次登录时生效。

Q: 如何批量重置所有用户的密码过期时间?

A: 可以使用脚本批量操作:

#!/bin/bash
# 批量重置所有用户的密码最后修改日期
getent passwd | awk -F: '$3 >= 1000 {print $1}' | while read USER; do
    sudo chage -d $(date +%Y-%m-%d) "$USER"
    echo "已重置用户 $USER 的密码修改日期"
done
安全注意事项:
  • 过于频繁的密码更换可能导致用户选择弱密码
  • 密码策略应考虑业务需求和用户体验
  • 定期审计密码策略的合规性
  • 在生产环境中修改密码策略前应充分测试
  • 确保有备用管理员账户,防止所有账户同时过期
最佳实践:
  • 普通用户:密码90天过期,过期前7天警告
  • 管理员用户:密码60天过期,过期前14天警告
  • 服务账户:使用SSH密钥认证,或设置密码永不过期
  • 临时账户:设置明确的账户过期日期
  • 定期审查和更新密码策略