密码复杂度不由 /etc/login.defs 控制,改 PASS_MIN_LEN 无效;真正生效的是 pam_pwquality.so(新系统)或 pam_cracklib.so(旧系统),须在 /etc/pam.d/common-password(Debian/Ubuntu)或 /etc/pam.d/system-auth(RHEL/CentOS)中以 password requisite 方式正确配置参数并置于 pam_unix.so 之前。

直接说结论:密码复杂度不由 /etc/login.defs 控制,改 PASS_MIN_LEN 没用;真正起效的是 pam_pwquality.so 模块,必须在对应 PAM 配置文件里加对参数、放对位置。
确认当前系统用的是 pam_pwquality 还是 pam_cracklib
旧系统(CentOS 7、Ubuntu 16.04)可能还在用 pam_cracklib.so,新系统(RHEL 8+/Ubuntu 20.04+)默认用 pam_pwquality.so。两者参数名相似但不完全兼容,混用会导致策略静默失效。
- 执行
grep -v '^#' /etc/pam.d/common-password | grep -E '(pwquality|cracklib)'(Debian/Ubuntu)或grep -v '^#' /etc/pam.d/system-auth | grep -E '(pwquality|cracklib)'(RHEL/CentOS)看实际加载哪个模块 - 不确定时,查手册:
man pam_pwquality或man pam_cracklib,确认你写的参数是否被当前模块支持 - 如果看到两行都存在(比如既有
pam_pwquality.so又有pam_cracklib.so),删掉其中一个——PAM 不允许多个密码强度模块共存于同一链路
在 PAM 文件里正确添加 password requisite 行
requisite 类型的模块一旦失败就终止整个密码修改流程,所以它必须放在其他 password 模块之前(尤其是不能在 pam_unix.so 后面),否则会被跳过。
- Debian/Ubuntu:编辑
/etc/pam.d/common-password,在开头附近找password [success=1 default=ignore] pam_unix.so这类行,在它前面插入:
password requisite pam_pwquality.so retry=3 minlen=12 difok=5 dcredit=-1 ucredit=-1 lcredit=-1 ocredit=-1 maxrepeat=3 reject_username enforce_for_root
- RHEL/CentOS:编辑
/etc/pam.d/system-auth,同样插在pam_unix.so行之前,且确保不是被include覆盖的副本(检查是否有重复 include 导致策略被覆盖) - 注意:不要把这行写成
sufficient或required——requisite才能保证校验失败立即退出 - 首次启用后,普通用户运行
passwd就会实时生效,无需重启任何服务
为什么设了 minlen=12 还被拒绝短密码?
minlen 不是绝对下限。它和字符类别要求是叠加计算的:若你设了 ucredit=-1 lcredit=-1 dcredit=-1 ocredit=-1(即四类字符各至少一个),但用户只输大小写字母,pam_pwquality 会自动把最低长度抬高到 12 + 2 = 14(缺数字、缺特殊符,两类未达标)。
- 更可控的做法是加
minclass=4:表示“至少满足 4 类字符”,这样系统会按实际缺失类别动态补足长度,逻辑更透明 -
difok=5是指新旧密码至少 5 个字符不同——如果旧密码是Abc123!(8位),新密码想设Abc123@(只改最后一位),会被拒绝 -
maxrepeat=3拒绝aaaa,但允许aaabbb;如需更严,加maxclassrepeat=2(同一类字符最多连续出现 2 次)
root 用户为啥不受限?
默认情况下,pam_pwquality.so 对 root 不生效,这是历史遗留行为。即使你在普通用户上测试通过,root 仍可能设出 123 这样的密码。
- 必须显式加上
enforce_for_root参数,否则 root 绕过所有规则 - 历史密码限制同理:
pam_pwhistory.so remember=24也得带enforce_for_root,否则 root 的旧密码不会被记录 - 首次启用
pam_pwhistory前,手动创建空文件:sudo touch /etc/security/opasswd && sudo chmod 600 /etc/security/opasswd,否则改密时报错“unable to open /etc/security/opasswd”
最易被忽略的点:PAM 是按行顺序执行的,requisite 失败就停,但如果你改的是 /etc/pam.d/sshd 而不是 common-password 或 system-auth,那 passwd 命令根本不会走那条链——得看具体哪个服务触发了密码修改流程。


















