在 Debian 服务器运维中,弱密码是最大的安全漏洞之一。无论防火墙规则多么完善,只要有一个用户使用了“123456”或“password”这样的弱口令,整个系统就形同虚设。解决这个问题的核心在于两个层面:一是强制密码复杂度策略,确保密码本身足够健壮;二是实施密码老化机制,强制用户定期更换。Debian 系统通过 PAM(可插拔认证模块)和 login.defs 配置文件提供了精细的控制能力,下面直接进入具体配置方法。

安装并配置 PAM 密码强度模块

Debian 默认使用 pam_unix 模块进行密码认证,但它只检查最基本的规则。要实现强密码策略,需要引入 libpam-pwquality 模块。这个模块可以强制密码长度、字符种类组合,甚至能检测密码是否包含字典单词或用户名。

首先安装该模块:

apt update
apt install libpam-pwquality

安装完成后,核心配置文件位于 /etc/pam.d/common-password。这个文件控制着所有修改密码操作的行为,无论是 root 还是普通用户,只要使用 passwd 命令或通过 SSH 修改密码,都会经过这里的规则检查。打开文件,找到包含 pam_pwquality.so 的那一行,如果没有则手动添加。一个典型的强密码配置如下:

password requisite pam_pwquality.so retry=3 minlen=12 difok=4 dcredit=-1 ucredit=-1 lcredit=-1 ocredit=-1 enforce_for_root

这里每个参数都有明确含义。retry=3 表示用户有 3 次机会输入符合规则的新密码。minlen=12 设置最小密码长度为 12 个字符,注意这不是简单的字符数,而是经过加权计算后的得分长度。difok=4 要求新密码与旧密码至少有 4 个字符不同,防止用户只改一个数字敷衍了事。dcredit=-1 表示密码必须包含至少 1 个数字,ucredit=-1 要求至少 1 个大写字母,lcredit=-1 要求至少 1 个小写字母,ocredit=-1 要求至少 1 个特殊字符。最后的 enforce_for_root 很关键,它让这些规则对 root 用户同样生效,避免特权账户成为突破口。

如果想更严格,可以增加负数值,比如 dcredit=-2 要求至少 2 个数字。还可以使用 reject_username 参数禁止密码包含用户名,以及 maxrepeat=3 限制同一字符连续出现次数。配置完成后,立即生效,无需重启任何服务。

验证密码策略是否生效

配置完成后,用一个普通用户账户测试。登录后执行 passwd 命令尝试修改密码,先输入一个简单密码如“abc123”,系统应该会拒绝并给出提示,比如“密码太短”或“必须包含大写字母”。只有输入符合所有规则的新密码,系统才会接受。如果发现规则没有生效,检查 /etc/pam.d/common-password 文件中 pam_pwquality.so 行的位置是否正确,它应该在 pam_unix.so 之前,并且使用 requisite 控制标志,这样一旦检查失败就立即拒绝,不会继续执行后续模块。

通过 login.defs 设置密码过期策略

强密码只是第一步,长期不换的密码即使再复杂也有泄露风险。Debian 使用 /etc/login.defs 文件控制用户账户的全局默认设置,其中就包括密码老化参数。打开该文件,找到以下关键配置项并进行修改:

PASS_MAX_DAYS 90
PASS_MIN_DAYS 7
PASS_WARN_AGE 14

PASS_MAX_DAYS 90 表示密码最长使用 90 天后必须更换。这个数值需要根据实际安全需求调整,对于高安全环境可以设为 60 甚至 30,但过于频繁的更换可能导致用户产生抵触情绪,反而把密码写在便签上。PASS_MIN_DAYS 7 设置两次密码修改之间的最小间隔天数,防止用户当天连续修改多次来绕过“不能重复使用旧密码”的限制。PASS_WARN_AGE 14 表示在密码过期前 14 天开始,每次登录时系统会显示警告信息,提醒用户尽快更换密码。

需要注意的是,login.defs 中的设置只对新建用户生效,现有用户需要手动应用这些策略。使用 chage 命令可以修改已有用户的密码过期信息:

chage -M 90 -m 7 -W 14 username

查看某个用户的密码老化状态,执行 chage -l username,会列出上次修改时间、过期时间、账户失效时间等详细信息。对于系统上的所有普通用户,建议写一个简单脚本批量设置,确保没有遗漏。

强制用户在下次登录时修改密码

在某些场景下,比如新用户创建后或怀疑密码泄露时,需要强制用户立即修改密码。使用 chage -d 0 username 命令可以将上次密码修改日期设置为 0,也就是 1970 年 1 月 1 日。这样系统会认为密码已经过期,用户下次登录时会被强制要求设置新密码。结合 SSH 的 ChallengeResponseAuthentication 设置,可以确保远程登录用户也无法绕过这个流程。

限制密码重用历史

用户最常用的取巧方式是在新旧密码之间来回切换。PAM 提供了 remember 参数来记住历史密码,防止重复使用。在 /etc/pam.d/common-password 文件中,pam_unix.so 行添加 remember 选项:

password sufficient pam_unix.so obscure sha512 remember=10

remember=10 表示系统会记住最近 10 次使用的密码,用户设置新密码时不能与这 10 个历史密码相同。密码历史记录存储在 /etc/security/opasswd 文件中,该文件权限应设为 600 且属主为 root,防止普通用户读取后分析密码规律。

处理特殊账户和服务账户

系统上可能存在一些自动化服务使用的账户,比如运行 Web 应用或数据库的专用用户。这些账户通常不需要交互式登录,但它们的密码策略同样重要。对于这类账户,可以设置更长的密码有效期,或者使用 chage -M -1 username 将密码设为永不过期,但前提是必须使用足够复杂的随机密码,并配合其他安全措施如 SSH 密钥认证或服务间的内部通信加密。务必定期审计这些账户,确保没有弱密码残留。

结合 SSH 配置增强安全性

密码策略配合 SSH 配置可以形成纵深防御。在 /etc/ssh/sshd_config 中,确保以下参数设置正确:

PermitRootLogin prohibit-password
PasswordAuthentication yes
ChallengeResponseAuthentication yes
UsePAM yes

PermitRootLogin prohibit-password 强制 root 只能通过密钥登录,即使 root 密码符合强密码策略,也不允许直接密码登录,这大大降低了暴力破解风险。PasswordAuthentication yes 允许普通用户使用密码登录,因为我们配置的强密码策略需要这个通道。UsePAM yes 确保 SSH 服务调用 PAM 模块进行认证,这样前面配置的密码复杂度检查和过期提醒才能通过 SSH 生效。

修改 SSH 配置后,执行 systemctl restart sshd 重启服务。注意不要断开当前连接,先另开一个终端测试能否正常登录,确认无误后再关闭原会话。

监控和审计密码合规性

策略部署后,持续监控同样重要。定期使用以下命令审计用户密码状态:

for user in $(awk -F: '$3>=1000 {print $1}' /etc/passwd); do
    echo "User: $user"
    chage -l $user | grep -E "Last|Expires|Warning"
    echo "---"
done

这个脚本遍历所有 UID 大于等于 1000 的普通用户,输出他们的密码最后修改时间和过期信息。可以将它加入 cron 定时任务,每周生成报告发送给管理员。如果发现某个账户的密码即将过期但用户长期未登录,应主动联系或考虑临时锁定账户。

另一个有用的工具是 cracklib-check,它来自 libpam-pwquality 的依赖包,可以离线检测密码强度:

echo "mypassword" | cracklib-check

如果输出“OK”,说明密码通过了基本字典检查,但这不代表绝对安全,仍需结合长度和字符种类综合判断。

应对用户抵触和培训

强制强密码和定期更换策略往往会遇到用户抱怨。技术手段之外,需要让用户理解为什么这些措施必要。可以编写简明的密码安全指南,说明如何构造既复杂又好记的密码,比如使用短语首字母缩写加数字和符号,或者推荐使用开源的密码管理器生成和存储随机密码。当用户掌握了方法,抵触情绪会大幅降低。

总结配置清单

完成以上所有步骤后,你的 Debian 系统已经具备了一套完整的强密码强制和定期更换机制。回顾关键配置点:/etc/pam.d/common-password 中 pam_pwquality.so 控制密码复杂度,pam_unix.so 的 remember 参数控制历史密码重用,/etc/login.defs 控制密码过期时间,chage 命令用于精细调整单个用户,SSH 配置确保远程登录同样受约束。这套组合拳能有效抵御绝大多数基于弱密码的攻击向量,为服务器安全打下坚实基础。