需配置PAM模块pam_pwquality.so(新系统)或pam_cracklib.so(旧系统)到/etc/pam.d/common-password(Debian/Ubuntu)或/system-auth(RHEL/CentOS),并确保使用requisite控制标志,仅passwd命令触发该策略,修改后无需重启但需新开终端测试。

怎么让 passwd 命令强制检查密码长度和字符类型
Linux 默认的 passwd 不校验复杂度,得靠 PAM 模块干预。核心是启用 pam_pwquality.so(新版系统)或 pam_cracklib.so(老系统),并配置到 /etc/pam.d/common-password(Debian/Ubuntu)或 /etc/pam.d/system-auth(RHEL/CentOS)。
常见错误是只改了文件但没加 required 控制标记,或者写错模块路径导致策略完全不生效。另外,passwd 只走 password 类型的 PAM 栈,改 auth 或 account 配置无效。
- Debian/Ubuntu:在
/etc/pam.d/common-password中找含pam_pwquality.so的行,没有就加一行:password requisite pam_pwquality.so retry=3 minlen=10 difok=3 reject_username authtok_type=
- RHEL 8+:用
pam_pwquality.so;RHEL 7 及更早默认是pam_cracklib.so,参数名略有不同(如minlen→minlen相同,但difok在 cracklib 中叫difok,行为一致) - 修改后立刻生效,无需重启服务,但已有会话中运行的
passwd进程可能缓存旧配置,建议新开终端测试
pam_pwquality.so 关键参数实际效果和坑点
参数不是设了就“一定生效”,很多受底层库限制或与其他模块冲突。比如 minlen=10 看似简单,但若系统启用了 enforce_for_root 却没配,root 改密时会被跳过;又比如 retry=3 是允许输错三次,但若前面有 required 模块失败,整个栈可能提前终止,根本轮不到它重试。
-
minlen:最小长度,但实际生效值受maxrepeat、maxclassrepeat等隐式约束影响——例如设了minlen=10但要求至少 2 个数字 + 2 个小写字母 + 2 个大写字母 + 2 个符号,那真实下限其实是 8,minlen只管总长 -
ocredit/lcredit/ucredit/dcredit:分别控制大小写字母、数字、符号的“信用分”,负值表示至少需要几个(如dcredit=-1表示至少 1 个数字);注意不是所有发行版默认启用这些,得显式写 -
reject_username:禁止密码包含用户名(含反转),但对 root 用户默认不触发,需加enforce_for_root才管用 - 配置写错参数名(如把
ocredit写成ocredit)不会报错,而是静默忽略——建议用pam_pwquality自带的pwscore工具验证:pwscore < /dev/stdin
输入密码看返回分值
为什么改了 PAM 配置,chage 或 SSH 密码登录还是没拦住弱密码
chage 只管密码过期策略,不碰复杂度;SSH 登录走的是 auth 栈,而密码复杂度必须在 password 栈里做。也就是说,PAM 密码策略只在用户主动调用 passwd 修改密码时触发,跟登录认证无关。
- 想让 SSH 登录也校验(比如用
sshpass批量设密),不行——那是认证环节,PAM 复杂度模块不参与 - 某些自动化工具(如 Ansible 的
user模块)直接写/etc/shadow,绕过 PAM,自然也不触发校验 - LDAP 或 SSSD 环境下,本地 PAM 配置对远程用户无效,得在服务端统一配
pam_pwquality或用 LDAP 密码策略对象(PPolicy) - 容器内应用(如 httpd 使用
htpasswd)完全不走系统 PAM,得单独处理
如何快速验证当前策略是否真起作用
别只看配置文件有没有那行,得实测。最可靠的方式是用普通用户执行 passwd,故意输弱密码,看提示是否匹配你配的规则。注意 root 用户默认被豁免,除非显式加了 enforce_for_root。
- 测试命令组合:
echo -e "123456\n123456" | passwd testuser 2>&1 | grep -i "weak\|short\|similar"
—— 观察是否出现预期拒绝信息 - 查实时日志:
journalctl -t PAM --since "1 hour ago" | grep -i pwquality,能看见模块加载和拒绝原因(如password not changed: insufficient credit for digits) - 误配常见现象:输弱密码后直接成功(说明模块没加载或被
sufficient模块短路);或报错 “Authentication token manipulation error”(多半是模块路径错或参数语法非法) - 如果系统用的是 SELinux,还可能因上下文限制导致
pam_pwquality.so读不到字典文件(/usr/share/cracklib/pw_dict),需检查ls -Z /usr/share/cracklib/和ausearch -m avc -ts recent
真正麻烦的不是配哪几行,而是搞清「谁在什么时候调用哪个 PAM 栈」。同一台机器上,passwd、sudo、su、图形登录、SSH 密码登录,背后走的 PAM 配置文件完全不同,改错一个地方,其他地方照常放行弱密码。










