在CentOS系统中,pwquality是控制密码复杂度的核心模块,它通过/etc/security/pwquality.conf配置文件来管理密码策略。如果你想自定义密码字典——也就是禁止用户使用某些弱密码(比如"password123"、"admin@2024"这类常见组合),最直接的方法就是利用pwquality的dictpath参数指向一个你自己编写的密码字典文件,同时配合minlen、dcredit、ucredit、lcredit、ocredit等参数做综合控制。下面我把这套配置从头到尾讲透,包括字典文件怎么写、配置文件怎么改、怎么验证生效、以及常见坑点。

一、pwquality到底是什么,为什么要自定义密码字典

pwquality是Linux系统中一个PAM(Pluggable Authentication Modules)模块,CentOS 7和CentOS 8/Stream都默认使用它。它的作用就是在用户设置或修改密码时,强制检查密码是否满足复杂度要求。默认情况下,pwquality自带了一个内置的密码黑名单机制,但这个内置列表非常有限,只能拦截极少数最烂的密码。实际生产环境中,攻击者用的字典远比系统自带的丰富,所以你需要自己维护一份密码字典文件,把企业内部常见的弱密码、泄露过的密码、和业务相关的敏感词都加进去。

二、找到并编辑pwquality配置文件

在CentOS 7上,配置文件路径是/etc/security/pwquality.conf。在CentOS 8/Stream上,路径同样是这个,但部分参数名可能有细微差异。先用编辑器打开:

vim /etc/security/pwquality.conf

打开后你会看到类似这样的内容:

#%PAM-1.0
# This file is autogenerated by authselect
# Please modify the appropriate source file instead.

minlen = 8
dcredit = -1
ucredit = -1
lcredit = -1
ocredit = -1
minclass = 3

注意,CentOS 8使用authselect管理认证配置,直接改这个文件可能被覆盖。建议先用authselect创建自定义profile:

authselect create-profile hardening -b sssd
authselect select custom/hardening

然后再去编辑/etc/security/pwquality.conf,这样改动不会被系统更新覆盖。

三、创建自定义密码字典文件

这是核心步骤。你需要创建一个纯文本文件,每行写一个要禁止的密码或密码片段。文件路径建议放在/etc/security/目录下,比如命名为pwdict.txt。

vim /etc/security/pwdict.txt

文件内容示例:

password
123456
12345678
qwerty
abc123
monkey
letmein
dragon
111111
baseball
iloveyou
trustno1
sunshine
master
welcome
shadow
ashley
football
jesus
michael
ninja
mustang
passw0rd
admin123
root123
toor
centos
redhat
company2024
Company@2024
Welcome1!
Welcome123

这里有几个关键原则:第一,每行一个条目,不要有空行;第二,大小写敏感,你写"Password"和"password"是两条不同的规则,如果想同时禁止大小写变体,需要都写上;第三,不要写太短的通用词比如"a"、"ab",这会误伤正常密码且影响性能;第四,文件权限必须设为600,否则系统会拒绝加载:

chmod 600 /etc/security/pwdict.txt
chown root:root /etc/security/pwdict.txt

四、在pwquality.conf中引用字典文件

回到配置文件,添加或修改dictpath参数:

dictpath = /etc/security/pwdict.txt

如果你希望系统同时检查密码是否包含字典中的词(而不仅仅是完全匹配),还需要设置:

dictcheck = 1

dictcheck=1的意思是:用户密码中只要包含字典里的任何一个词,就判定为不合格。比如字典里有"admin",那么"myadmin123"也会被拒绝。如果你只想禁止完全匹配的情况,设为0即可。生产环境强烈建议设为1。

完整的推荐配置如下:

minlen = 12
dcredit = -1
ucredit = -1
lcredit = -1
ocredit = -1
minclass = 4
dictpath = /etc/security/pwdict.txt
dictcheck = 1
maxrepeat = 3
maxsequence = 3
maxclassrepeat = 4

各参数含义快速说明:minlen是密码最小长度12位;dcredit/ucredit/lcredit/ocredit分别要求至少包含一个数字、大写字母、小写字母、特殊字符;minclass=4表示四类字符都必须出现;maxrepeat=3禁止同一字符连续出现超过3次;maxsequence=3禁止连续3个字母或数字序列如"123"、"abc";maxclassrepeat=4限制同类字符连续不超过4个。

五、如何让字典持续更新和维护

密码字典不是一次性的东西。现实中每天都有新的泄露密码库流出,你需要定期更新。有几个实用做法:第一,从公开的泄露密码库(比如haveibeenpwned的下载包)中提取Top 10万条常见密码,过滤掉太短的和太通用的,追加到你的字典文件末尾;第二,把公司内部的敏感词、产品名、服务器名、域名变体都加进去,比如"prod-db-01"、"app-server"这类;第三,写一个简单的cron脚本每周自动拉取最新泄露密码片段并合并:

#!/bin/bash
# /usr/local/bin/update_pwdict.sh
DICT_FILE="/etc/security/pwdict.txt"
TEMP_FILE="/tmp/new_entries.txt"

# 从本地维护的泄露密码片段中提取
grep -v '^#' /opt/password_lists/common_passwords_2024.txt | head -5000 > $TEMP_FILE

# 合并去重
cat $TEMP_FILE $DICT_FILE | sort -u > ${DICT_FILE}.new
mv ${DICT_FILE}.new $DICT_FILE
chmod 600 $DICT_FILE

# 清理
rm -f $TEMP_FILE

然后加到crontab:

0 3 * * 1 /usr/local/bin/update_pwdict.sh

六、验证配置是否生效

改完配置后,不要直接拿root测试(root可能受其他策略豁免)。创建一个普通用户测试:

useradd testuser
passwd testuser

尝试设置一个字典里有的密码比如"Welcome123",系统应该直接拒绝并提示类似"BAD PASSWORD: it is based on a dictionary word"的错误。再试一个满足所有规则的强密码如"Kx9#mP2$vLnQ",应该能成功设置。

还可以用pam_pwquality模块的测试工具直接检测:

echo "password123" | pwscore -m -1 -n -1 -u -1 -l -1 -c 4 -r 3 -s 3

这个命令会模拟pwquality的检查逻辑,返回密码得分,分数越低越弱。如果你的字典生效了,包含字典词的密码得分会被进一步拉低。

七、CentOS 7和CentOS 8的差异注意事项

CentOS 7的pwquality版本较老,部分参数名和行为略有不同。比如CentOS 7上dictcheck参数可能叫enforcing,而且默认不加载字典检查,必须显式配置。CentOS 8使用authselect框架后,配置文件可能被标记为"autogenerated",直接修改会在下次authselect apply时被覆盖,所以一定要先创建自定义profile再改。另外CentOS 8上还可以通过/etc/authselect/custom/hardening/pwquality配置来管理,路径略有不同但参数含义一致。

八、常见问题和避坑指南

第一个坑:字典文件太大会导致密码修改操作变慢,因为每次都要逐行比对。建议控制在5万行以内,如果需要更大的覆盖范围,可以考虑用pam_cracklib模块的cracklib_check替代,它自带更高效的字典匹配机制。第二个坑:dictpath路径写错或文件权限不对,系统会静默跳过字典检查,密码策略看似生效其实形同虚设,一定要用passwd命令实测验证。第三个坑:在CentOS 8上如果同时装了authselect管理的sssd和本地pam配置,可能出现策略冲突,建议统一用authselect管理,避免两套机制打架。第四个坑:自定义字典不要包含系统默认禁止的词以外的所有短词,否则用户会频繁遇到"密码不符合要求"的提示,影响体验和运维效率。

九、进阶建议:结合其他安全模块形成纵深防御

pwquality只是密码策略的一环。建议同时配置pam_faillock锁定失败登录、设置密码过期策略(chage命令)、启用SSH密钥认证减少密码使用频率。在/etc/login.defs中设置PASS_MAX_DAYS 90和PASS_MIN_DAYS 7,强制用户定期换密码但不要太频繁导致用户写在便利贴上。把这些组合起来,才是一套完整的CentOS密码安全方案。

总结一下,自定义pwquality密码字典的核心就是三步:写好dict文件、配置dictpath和dictcheck参数、定期维护更新。这件事不复杂,但做好了能有效挡住大量基于字典的暴力破解攻击,是CentOS安全加固中投入产出比极高的一项操作。