chage -m 90 username 是设置密码90天过期的唯一可靠方式,/etc/login.defs中pass_max_days仅影响新用户;pam密码策略需配合pam_pwquality.so参数(如ucredit=-1)与历史记录、首次强制改密等措施协同生效。

chage -M 设置密码最长有效期必须对每个用户单独执行
直接结论:chage -M 90 username 是让密码 90 天后过期的唯一可靠方式,/etc/login.defs 中的 PASS_MAX_DAYS 只影响新用户,已有用户完全不受影响。很多人改完 /etc/login.defs 就以为全局生效,结果发现老用户还是“从不”过期。
常见错误现象:
-
chage -l username显示 “密码过期时间 : 从不”,即使PASS_MAX_DAYS已设为 90 - 误用
-E(账户截止日)代替-M(密码过期),导致用户无法登录而非强制改密 - 给服务账户(如
nginx、mysql)也设-M,引发定时任务或服务异常中断
实操建议:
- 对普通用户逐个执行:
sudo chage -M 90 -W 7 -m 1 username -
-W 7表示提前 7 天开始提示,-m 1防止刚改完立刻再改 - 批量处理可用:
for u in $(awk -F: '$3>=1000 && $1!="nobody" {print $1}' /etc/passwd); do sudo chage -M 90 -W 7 "$u"; done
pam_pwquality.so 的 minlen 参数不是最终长度控制点
minlen=10 看似设了最小长度,但实际生效还取决于其他 credit 参数是否满足。比如只设 minlen=10 而没配 ucredit=-1,用户仍可设 10 位纯小写密码——这不符合等保要求。
关键差异:
-
minlen是总长度下限,但各字符类型要求由ucredit、lcredit、dcredit、ocredit共同约束 - 负值才表示“至少含 N 个”,例如
ucredit=-1表示至少 1 个大写字母;正值(如ucredit=1)是“最多允许 1 个”,几乎不用 - Debian/Ubuntu 编辑
/etc/pam.d/common-password,RHEL/CentOS 改/etc/pam.d/system-auth或password-auth
推荐配置行(放在其他 password 行之前):
password requisite pam_pwquality.so retry=3 minlen=10 difok=3 ucredit=-1 lcredit=-1 dcredit=-1 ocredit=-1 maxrepeat=3
注意:difok=3 和 maxrepeat=3 容易被忽略,但能防 Pa$$w0rd123 → Pa$$w0rd456 这类弱变更。
密码长度和过期策略必须配合历史记录与首次登录强制改密
只设长度和过期时间,用户可能反复用同一组强密码循环替换,或者新建账号后一直不改初始密码。这两点会让前面所有配置形同虚设。
必须补全的环节:
- 启用密码历史:在 PAM 配置中加
password [default=ok] pam_pwhistory.so remember=5 use_authtok enforce_for_root,确保/etc/security/opasswd可写 - 强制首次登录改密:
sudo chage -d 0 username,它把 shadow 中的 “最后修改日期” 设为 0(即 1970-01-01),触发登录时强制重设 - 避免空密码:确认
pam_unix.so行不含nullok,或显式加deny=nullok
验证是否生效:sudo chage -l username 中 “密码最后一次修改时间” 若显示为 “1月 01, 1970”,说明 -d 0 已起作用。
/etc/login.defs 的 PASS_MIN_LEN 不控制实际最小长度
/etc/login.defs 里的 PASS_MIN_LEN 10 是个误导项——它仅被旧版 pam_cracklib 或某些发行版的 useradd 工具读取,现代系统(Ubuntu 20.04+、RHEL 8+)完全由 pam_pwquality.so 的 minlen 控制。留着它没用,删掉或注释掉更清晰。
真正需要改 /etc/login.defs 的只有三处:
-
PASS_MAX_DAYS 90(仅对新用户) -
PASS_MIN_DAYS 1(新用户最短修改间隔) -
PASS_WARN_AGE 7(新用户警告天数)
改完后新建用户会自动继承这些值,但不会覆盖已有用户的 /etc/shadow 字段。这点最容易被当成“配置失败”来回折腾。
复杂点在于:密码策略是 PAM 模块、shadow 字段、login.defs 三者叠加生效,且优先级不同。漏掉任意一层,都可能让安全策略出现可预测的缺口——比如只配了 minlen 却没禁重复字符,用户就能用 AAAAAaaaa1! 过检。











