应改用 pam_pwquality.so 替代 pam_cracklib.so,因其是官方继任者,支持 unicode 和自定义字典;需更新 pam 配置行并注意参数兼容性、minlen/minclass 实际校验逻辑、conf 文件仅作默认值、debug 调试及 enforce_for_root 显式启用等关键细节。

如何用 pam_pwquality.so 替代过时的 pam_cracklib.so
新版 linux(如 RHEL 8+/centos 8+、ubuntu 20.04+)默认已弃用 pam_cracklib.so,继续在 /etc/pam.d/common-password 或 /etc/pam.d/system-auth 里写它会导致策略不生效,甚至密码修改失败。
必须改用 pam_pwquality.so —— 它是 pam_cracklib 的继任者,配置项更细、校验更严格,且支持 Unicode 和自定义字典。
- 检查是否已安装:
dpkg -l libpam-pwquality(debian/Ubuntu)或rpm -q libpwquality(RHEL/CentOS) - 替换原配置行:
password requisite pam_cracklib.so ...→ 改为password requisite pam_pwquality.so ... - 注意:旧参数名大多失效,比如
minlen要换成minlen=12,但retry仍可用,ucredit/lcredit等保持兼容
minlen 和 minclass 的真实约束力
minlen 不是“最少字符数”,而是“满足复杂度要求后的最低长度”;minclass 控制至少要包含几类字符(大写、小写、数字、符号),但它只对“非空格可打印字符”计数,空格、制表符、控制字符全被忽略。
- 设
minlen=10 minclass=3,密码Abc123!(末尾三个空格)实际只按 7 个有效字符校验,会失败 - 若用户输入含 Unicode 字符(如中文、emoji),
pam_pwquality默认不识别为“字母类”,可能意外降低 class 计数 —— 需显式加dictcheck=0关闭字典检查,或用enforce_for_root避免干扰 root - 想让空格也被纳入长度计算?不行。模块本身跳过空白符,这是硬编码行为,无法绕过
为什么改了 /etc/security/pwquality.conf 却没生效
这个文件只是全局默认值,真正起作用的是 PAM 配置中 pam_pwquality.so 行的参数 —— 后者会覆盖前者。常见误区是只调 pwquality.conf,却忘了检查 PAM 文件里有没有重复或冲突的参数。
- PAM 行中显式写的参数(如
minlen=14)优先级 >/etc/security/pwquality.conf中的同名项 -
pwquality.conf里设置maxrepeat=2,但 PAM 行没写,那该限制就无效 —— 模块不会自动读取 conf 文件,除非你加config=/etc/security/pwquality.conf - 调试方法:临时加
debug参数到 PAM 行,然后tail -f /var/log/auth.log看拒绝原因,比如出现too short还是not enough classes
root 用户密码不受限?小心 enforce_for_root 的默认值
默认情况下,pam_pwquality.so 对 root 用户完全不执行任何检查 —— 即便你配了 minlen=20,root 仍能设 123。这不是 bug,是设计如此,为避免系统锁死。
- 必须显式添加
enforce_for_root才启用 root 密码策略 - 但加了之后,root 自己改密、或通过
sudo passwd root改密都会受控;而首次安装或 recovery 模式下用passwd直接改,仍可能绕过(取决于 initramfs 是否加载 PAM) - 生产环境建议启用,但务必提前测试:用普通用户
sudo passwd root验证策略是否真生效,别只信文档
最易被忽略的点:PAM 配置分散在多个文件(common-password、system-auth、甚至 passwd),改错一个就全白搭;还有 SELinux 可能拦截 pam_pwquality 读取字典路径,报错信息里藏的是 Permission denied,不是策略问题。