4. 密码策略与认证强化

在 RHEL 安全基线中,密码策略是身份认证的第一道闸门。它并不由单一文件控制,而是由多个组件分工协作:/etc/login.defs 负责账号与密码的全局默认值,/etc/security/pwquality.conf 负责密码复杂度校验,PAM 的 system-auth 与 password-auth 栈负责把复杂度、历史记录和过期策略真正挂接到认证流程中。理解这三者的分工,是避免“改了配置却不生效”的关键。

一、三个组件的职责边界

/etc/login.defs 是 useradd、usermod、passwd 等工具读取的全局策略文件,主要控制密码有效期与长度下限。典型参数包括:PASS_MAX_DAYS(密码最长可用天数)、PASS_MIN_DAYS(两次修改密码的最小间隔)、PASS_WARN_AGE(过期前多少天开始警告)、PASS_MIN_LEN(密码最小长度,但该值对普通用户改密并不总是强制生效,真正强制长度的是 pwquality)。

/etc/security/pwquality.conf 由 pam_pwquality 模块读取,负责密码的“质量”判断,包括最小长度、字符类别数量、连续重复字符、回文、用户名包含等。它才是真正决定“这个密码能不能被接受”的规则来源。

PAM 栈则是执行者。在 /etc/pam.d/system-auth 和 /etc/pam.d/password-auth 中,password requisite pam_pwquality.so 负责复杂度校验,password requisite pam_pwhistory.so 负责历史密码比对,password sufficient pam_unix.so 负责最终写入。三者顺序不能随意调换,否则历史记录可能在校验前就被写入。

密码策略三组件协作与认证校验链 用户执行 passwd 输入新密码 PAM password 栈 /etc/pam.d/system-auth pam_pwquality.so 复杂度校验(长度/类别/重复) pam_pwhistory.so 历史密码比对(remember) pam_unix.so 写入 shadow(sha512) pwquality.conf minlen / dcredit ucredit / ocredit / lcredit login.defs PASS_MAX_DAYS PASS_MIN_DAYS / WARN_AGE 拒绝:复杂度不足 提示 BAD PASSWORD 拒绝:历史重复 提示 password reused 通过:写入 shadow 更新 /etc/shadow 第3字段 过期策略 PASS_MAX_DAYS=90 PASS_MIN_DAYS=7 PASS_WARN_AGE=14 chage -l 查看 chage -M 90 user chage -d 0 user 强制改密 校验顺序要点: 1. pam_pwquality 先判断密码质量,不通过直接拒绝,不进入后续模块。 2. pam_pwhistory 再比对 /etc/security/opasswd 中的历史哈希,命中则拒绝。 3. pam_unix 最后写入 shadow;login.defs 的过期参数由 chage/passwd 在写入时同步应用。

二、pwquality.conf 的复杂度参数

打开 /etc/security/pwquality.conf,常见配置如下(示例值,可按基线调整):

minlen = 12
dcredit = -1
ucredit = -1
lcredit = -1
ocredit = -1
minclass = 3
maxrepeat = 3
maxclassrepeat = 2
gecoscheck = 1
dictcheck = 1
usercheck = 1
enforcing = 1
retry = 3

这里有几个容易混淆的点。minlen 是密码最小长度,但它与 credit 参数存在叠加关系:当 dcredit=-1 时,表示“至少包含 1 个数字”,同时会为密码长度贡献 +1 的信用值。也就是说,如果 minlen=12 且四个 credit 都为 -1,实际最短密码长度可能被要求为 12,但满足各类别后信用值会抵扣部分长度要求。若希望长度严格为 12,可把 credit 设为 0 或使用 minclass 控制类别数。

maxrepeat=3 限制同一字符最多连续出现 3 次,maxclassrepeat=2 限制同一字符类别最多连续出现 2 次,usercheck=1 禁止密码中包含用户名,gecoscheck=1 禁止包含 GECOS 字段信息,dictcheck=1 会调用字典检查弱口令。enforcing=1 表示违规时直接拒绝,若设为 0 则只警告不阻止,生产环境应保持 1。

三、历史记录与过期策略

历史记录由 pam_pwhistory.so 控制,在 PAM 文件中通常写成:

password    requisite     pam_pwhistory.so use_authtok remember=5 retry=3

remember=5 表示记住最近 5 个密码哈希,禁止重复使用。历史哈希存放在 /etc/security/opasswd,该文件权限应为 600,属主 root。注意:remember 只对通过 PAM 修改密码的路径生效,直接用 usermod -p 或编辑 shadow 不会触发历史检查。

过期策略在 /etc/login.defs 中设置默认值,对新建用户生效;对已存在用户需用 chage 单独调整。例如:

PASS_MAX_DAYS   90
PASS_MIN_DAYS   7
PASS_WARN_AGE   14

验证时可用 chage -l alice 查看某用户的密码有效期、最小间隔、警告天数、上次修改时间和账号过期时间。若要把某用户强制下次登录改密,执行 chage -d 0 alice,其 shadow 第三字段会变为 0,登录时即被要求修改密码。

四、配置生效与验证方法

修改 PAM 相关文件后无需重启,下一次认证即生效。验证复杂度是否生效,可用一个普通用户执行 passwd,依次输入弱密码(如 123456、alice2024、aaaaaa),观察是否被拒绝并给出对应提示。验证历史记录,可连续修改密码并尝试复用旧密码,应看到 “password reused” 类提示。验证过期策略,用 chage -l 核对字段,或用 chage -d 0 后重新登录确认强制改密。

注意:不要同时依赖 PASS_MIN_LEN 和 minlen 做长度控制,前者对普通用户改密路径并不总是强制;应以 pwquality 的 minlen 为准。修改 PAM 文件前建议备份,避免语法错误导致所有用户无法登录。

五、基线检查清单(示例)

检查项期望值验证命令
密码最长有效期≤ 90 天grep PASS_MAX_DAYS /etc/login.defs
密码最小间隔≥ 7 天grep PASS_MIN_DAYS /etc/login.defs
过期警告天数≥ 14 天grep PASS_WARN_AGE /etc/login.defs
最小长度≥ 12grep minlen /etc/security/pwquality.conf
字符类别数≥ 3grep minclass /etc/security/pwquality.conf
历史密码数≥ 5grep remember /etc/pam.d/system-auth
opasswd 权限600 root:rootls -l /etc/security/opasswd

把上述参数落到基线中,密码策略才算真正闭环:login.defs 管生命周期,pwquality.conf 管质量门槛,PAM 管执行顺序,chage 管个体差异,最后用实际改密和 chage -l 做验证。任何一环缺失,都会让“看起来配了”的策略在实际认证中失效。