修改密码复杂度需配置pam模块而非/etc/login.defs;先确认系统使用pam_pwquality或pam_cracklib,二者不可共存;在common-password(debian/ubuntu)或system-auth(rhel/centos)中password requisite行插入对应模块参数,位置须在pam_unix.so之前;minlen与字符类别要求叠加生效,可用minclass=4简化配置;测试用passwd命令实时验证。

直接改 /etc/login.defs 里的 PASS_MIN_LEN 没用,密码必须含大小写字母、数字和特殊符号,靠的是 PAM 模块的字符类别校验,不是系统级长度参数。
确认当前系统用的是 pam_pwquality 还是 pam_cracklib
两者参数名相似但不兼容,混用会导致策略静默失效:
- Debian/Ubuntu:运行
grep -v '^#' /etc/pam.d/common-password | grep -E '(pwquality|cracklib)' - RHEL/CentOS:运行
grep -v '^#' /etc/pam.d/system-auth | grep -E '(pwquality|cracklib)' - 如果看到两行都存在(比如同时有
pam_pwquality.so和pam_cracklib.so),删掉其中一个——PAM 不允许多个密码强度模块共存于同一 password 链路 - 不确定时查手册:
man pam_pwquality或man pam_cracklib,确认你写的参数是否被当前模块支持
在 PAM 配置文件中添加或修改 password requisite 行
这行必须放在 pam_unix.so 之前,否则会被跳过;类型必须是 requisite,不是 sufficient 或 required:
- Debian/Ubuntu:编辑
/etc/pam.d/common-password,在password [success=1 default=ignore] pam_unix.so行之前插入 - RHEL/CentOS:编辑
/etc/pam.d/system-auth,同样插在pam_unix.so行之前,并检查是否被include覆盖(常见坑) - 典型配置(
pam_pwquality):password requisite pam_pwquality.so retry=3 minlen=12 ucredit=-1 lcredit=-1 dcredit=-1 ocredit=-1 - 旧系统(
pam_cracklib):password requisite pam_cracklib.so retry=3 minlen=12 ucredit=-1 lcredit=-1 dcredit=-1 ocredit=-1
为什么设了 minlen=12 还被拒绝短密码?
minlen 不是绝对下限,它和字符类别要求是叠加计算的:
- 如果你设了
ucredit=-1 lcredit=-1 dcredit=-1 ocredit=-1(即四类各至少一个),但用户只输大小写字母,pam_pwquality会自动把“缺数字、缺特殊字符”的代价折算进长度要求,实际最低可能要到 14–16 位才能满足 - 想降低门槛又保安全,可用
minclass=4替代四个*credit参数(pam_pwquality支持,pam_cracklib不支持) - 测试时用普通用户执行
passwd即可实时验证,无需重启服务或登出 - 注意
enforce_for_root参数:默认 root 不受限制,加这个才对 root 生效
最常被忽略的一点:ocredit=-1 要求的“特殊字符”范围由 /usr/share/cracklib/pw_dict 或系统 locale 决定,某些符号如空格、中文、emoji 可能不被识别为有效特殊字符,建议优先用 !@#$%^&* 类标准符号测试。











