从真实事故说起
有家公司的运维在离职交接文档里留了个 root 密码。三个月后,前同事用这个密码登录了服务器,删了所有 Docker 容器。原因很简单:没人要求定期改密码,也没人管密码过期策略。
如果你的服务器密码从开通至今都没变过,那你的系统安全性可能还没一个微信支付密码强。还好 Linux 提供了 passwd 和 chage 这两个工具来管理密码策略。
passwd:不只是改密码
修改密码(基础用法)
# 普通用户修改自己的密码(需要输入旧密码)
passwd
# root 修改指定用户的密码(不用旧密码)
sudo passwd zhangsan
root 改别人密码不需要知道旧密码,这是高危操作。某种意义上,谁有 sudo 权限谁就能控制所有账户。
锁定和解锁用户
# 锁定用户(让密码失效)
sudo passwd -l zhangsan
# 解锁用户
sudo passwd -u zhangsan
# 查看用户密码状态
sudo passwd -S zhangsan
# 输出类似:zhangsan L 2026-07-27 0 99999 7 -1 (Password locked.)
-l(lock,锁定)在 /etc/shadow 中给密码字段前面加了一个感叹号。-S(status,状态)显示密码的当前状态,输出内容包括登录名、状态(L=锁定,P=可用,NP=无密码)、最后修改日期、最小天数、最大天数、警告天数、宽限天数。
删除密码
# 删除用户密码(变为无密码账户)
sudo passwd -d zhangsan
删掉密码后,用户登录不需要密码。这在测试环境偶尔会用,但生产环境千万别用。
立即过期密码
# 让用户密码立即过期,下次登录必须修改
sudo passwd -e zhangsan
-e(expire,使过期)相当于让 /etc/shadow 中该用户的密码最后修改日期设为 0。用户下次 SSH 登录时系统会强制要求修改密码。这是新人入职时我必做的一步。
chage:密码策略的专业管理工具
chage(change aging,修改密码时效)比 passwd 精细得多。它控制密码的生命周期。
查看密码过期信息
# 查看用户的密码过期信息
chage -l zhangsan
输出示例:
Last password change : Jul 27, 2026
Password expires : Oct 25, 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
每一行都对应 /etc/shadow 的一个字段。看懂这个输出,就等于看懂了 /etc/shadow 的密码策略配置。
设置密码最长有效期
# 密码90天后过期
sudo chage -M 90 zhangsan
# 密码永不过期(不推荐)
sudo chage -M 99999 zhangsan
-M(maximum days,最大天数)是我在公司强制要求的策略。非 root 用户一律设 90 天过期。
设置密码最短有效期
# 密码修改后至少7天内不能再次修改
sudo chage -m 7 zhangsan
-m(minimum days,最小天数)防止用户改了密码后立刻改回原来的。配合记住历史密码的策略一起用更有效。
设置密码过期前警告
# 密码过期前14天开始警告
sudo chage -W 14 zhangsan
-W(warning days,警告天数)。默认一般是 7 天。用户 SSH 登录时会看到类似 "Warning: your password will expire in 5 days" 的消息。我建议设 14 天,给用户足够的缓冲时间。
设置密码过期后的宽限天数
# 密码过期后7天内必须修改,否则账户锁定
sudo chage -I 7 zhangsan
-I(inactive days,不活动天数)是很多人忽略的参数。密码过期不等于账户锁定,用户还可以用旧密码登录修改密码。但过了宽限期,账户就被锁定了,得找管理员解。
设置账户过期时间
# 设置账户在指定日期过期
sudo chage -E 2026-12-31 zhangsan
# 取消账户过期
sudo chage -E -1 zhangsan
-E(expire date,过期日期)适合实习生、短期合作人员。到期自动锁定,不用手动跟踪离职时间。
强制用户下次登录修改密码
# 密码立即过期,强制修改
sudo chage -d 0 zhangsan
-d 0(last day,最后修改日期设为0)是强制改密码最优雅的方式。和 passwd -e 效果一样,但我更常用 chage,因为参数语义更清晰。
密码策略实战:企业级配置
# 为新员工创建账户并设置标准密码策略
sudo useradd -m -s /bin/bash newhire
sudo passwd newhire
# 手动输入一个临时密码
# 强制下次修改密码
sudo chage -d 0 newhire
# 密码最长90天有效
sudo chage -M 90 newhire
# 最短1天后才能再修改(防滥用)
sudo chage -m 1 newhire
# 提前14天发出警告
sudo chage -W 14 newhire
# 过期后7天宽限期
sudo chage -I 7 newhire
# 查看最终配置
sudo chage -l newhire
这套策略我在几十台服务器上用了几年。核心思路:新员工第一次登录必须改密码,之后每 90 天换一次,过期前两周提醒,过期后一周内还有机会改。超过宽限期的就找管理员。
/etc/shadow 文件结构
了解 passwd 和 chage 在改什么,才能排错。
# 查看 /etc/shadow
sudo cat /etc/shadow | grep zhangsan
# 格式:用户名:加密密码:最后修改:最小:最大:警告:宽限:过期:保留
密码字段以 ! 开头表示锁定,以 $ 开头表示加密算法($y$=yescrypt,$6$=SHA-512)。
密码策略系统化配置
# 查看系统全局密码策略(这个文件控制新用户的默认策略)
cat /etc/login.defs | grep -E 'PASS_MAX|PASS_MIN|PASS_WARN'
# 输出示例:
# PASS_MAX_DAYS 99999
# PASS_MIN_DAYS 0
# PASS_WARN_AGE 7
如果你希望所有新用户的默认策略都是一致的,直接改 /etc/login.defs 就行了。然后在 /etc/shadow 中手动调整个例。
安全提醒
密码策略不能代替双因素认证。 就算 7 天换一次密码,被钓鱼了一样泄露。关键系统还是上 SSH 密钥 + TOTP(基于时间的一次性密码)吧。
chage 的参数和 /etc/shadow 字段对应关系不是很好记。 我一开始常搞混 -M 和 -m(一个是大写一个是小写,一个是 max 一个是 min)。建议在脚本里用 chage 时加上注释。
# 这条命令一定要写对的参数:
# -M = MAX_DAYS(最大),-m = MIN_DAYS(最小),别写反了
sudo chage -M 90 -m 1 zhangsan
root 密码策略更重要。 很多公司给普通用户设了严格的密码策略,但 root 密码几年不变。root 密码的过期检查不能忘。
改密码前确认不是脚本依赖的服务账户。 有些服务用密码认证而不是密钥。改了密码后,cron 定时任务、数据库连接、备份脚本全断了。
密码策略不是折腾用户,而是保护所有人的数据安全。花半天配置好密码策略,比出事后花几天处理数据泄露值得多。