应禁用服务账号密码认证而非仅设密码永不过期:先用usermod -s /usr/sbin/nologin禁用登录,再用passwd -l锁定密码,使/etc/shadow中密码字段为!;chage -M 99999仅作策略补全,不可替代密码锁定。

为系统内置服务账号(如 mysql、nginx)设置密码永不过期,核心原则是:**这些账号通常不用于交互式登录,应禁用密码认证能力,而非单纯延长密码有效期**。直接设 -M 99999 不仅冗余,还可能引入安全风险或管理混淆。
为什么不能只用 chage -M 99999?
服务账号(如 mysql、nginx、redis、postfix 等)一般满足以下特征:
- Shell 设为
/usr/sbin/nologin或/bin/false,本身就不允许登录 - 密码字段在
/etc/shadow中常为*或!,表示密码被锁定或不可用 - 它们通过文件权限、socket、密钥或配置文件认证,不依赖 PAM 密码校验
- 设
-M 99999对实际运行无意义,反而让chage -l输出产生误导(显示“Password expires: never”,但其实该账号根本不用密码)
推荐做法:确保密码字段不可用 + 显式禁用登录
这才是符合 Linux 安全规范和服务账户最佳实践的操作:
Linux 安全审计工具,检查 SSH 配置、开放/监听端口、防火墙规则(ufw/iptables/nftables)、失败登录尝试、sudoers 权限...
- 确认账号 shell 已设为非登录 shell:
sudo usermod -s /usr/sbin/nologin mysql - 锁定密码(清空密码并标记为不可用):
sudo passwd -l mysql
执行后,/etc/shadow中该行第二字段变为!(如mysql:!:19200:0:99999:7:::),表示密码被禁用 - 验证结果:
sudo chage -l mysql会显示Password expires : never(这是-l的副作用,但本质是密码被锁,不是“永有效”)
更关键的是检查:getent shadow mysql | cut -d: -f2应输出!或!!
若因审计要求必须显式设置 MaxDays(极少数场景)
例如等保测评中要求“所有账号需明确定义密码策略”,可补充执行(但须与 passwd -l 配合):
sudo chage -m 0 -M 99999 -I -1 -E -1 mysql- 注意:此命令本身不解除密码锁定,
passwd -l优先级更高;-M 99999仅是对已锁定账号的策略补全,不影响行为 - 同理适用于 nginx:
sudo usermod -s /usr/sbin/nologin nginx && sudo passwd -l nginx && sudo chage -m 0 -M 99999 -I -1 -E -1 nginx
务必避免的操作
以下做法存在隐患,不建议采用:
- 用
passwd为服务账号设置真实密码(如sudo passwd mysql)——会激活密码字段,增加攻击面 - 仅执行
chage -M 99999而不锁定密码——账号仍处于“有密码但永不过期”状态,违背服务账户设计本意 - 修改
/etc/login.defs影响新建服务账号——该文件只对useradd创建的新用户生效,且服务账号通常由包管理器(如 apt/dnf)预建,不受其控制










