【学习】使用pam_cracklib校验密码复杂度
BMC设置用户密码需要支持校验密码复杂度与弱密码库。之前不清楚这部分是怎么实现的,还以为需要在前端对密码进行校验。优化相关功能的时候才发现,实际上是通过PAM模块来实现的。通过查资料与功能调试,总算对这里有了初步的了解。
PAM是Pluggable Authentication Modules的缩写,字面意思就是可插拔认证模块。它提供的一组动态链接库和API,可以实现把服务和认证方式分开。也就是说可以根据需要单独配置认证方式,而不需要修改服务相关的程序代码。
与密码复杂度相关的校验是通过pam_cracklib模块完成的,可以通过配置文件对其进行配置。对应的配置文件为/etc/pam.d/common-password。其内容是这样的:
#
# /etc/pam.d/common-password - password-related modules common to all services
#
# This file is included from other service-specific PAM config files,
# and should contain a list of modules that define the services to be
# used to change user passwords. The default is pam_unix.
# Explanation of pam_unix options:
#
# The "sha512" option enables salted SHA512 passwords. Without this option,
# the default is Unix crypt. Prior releases used the option "md5".
#
# The "obscure" option replaces the old `OBSCURE_CHECKS_ENAB' option in
# login.defs.
#
# See the pam_unix manpage for other options.
# As of pam 1.0.1-6, this file is managed by pam-auth-update by default.
# To take advantage of this, it is recommended that you configure any
# local modules either before or after the default block, and use
# pam-auth-update to manage selection of other modules. See
# pam-auth-update(8) for details.
# here are the per-package modules (the "Primary" block)
password [success=1 default=ignore] pam_unix.so obscure sha512
# here's the fallback if no module succeeds
password requisite pam_deny.so
# prime the stack with a positive return value if there isn't one already;
# this avoids us returning an error just because nothing sets a success code
# since the modules above will each just jump around
password required pam_permit.so
# and here are more per-package modules (the "Additional" block)
password optional pam_gnome_keyring.so
# end of pam-auth-update config
其中每一行的格式为Module-Type Control-flag Module-Path Arguments,即模块类型、控制字符、模块路径与模块参数。为了实现对密码复杂度的控制,在配置文件中加入了如下一行内容:
password [success=ok default=die] pam_cracklib.so debug enforce_for_root reject_username minlen=1 difok=0 lcredit=0 ocredit=0 dcredit=0 ucredit=0
这里模块类型password表示设置密码,success=ok和default=die应该是验证成功与失败状态下的处理。pam_cracklib.so是需要用到的模块。后面的参数说明如下:
- debug: 将debug信息写入syslog
- enforce_for_root: 密码复杂度的限制同样适用于root用户
- reject_username: 密码中不能含有用户名
- minlen: 密码最小长度
- difok: 新密码有几个字符不能和旧密码相同
- lcredit: 小写字母,数值大于0表示最多包含几个小写字母,数值小于0表示最少包含几个小写字母
- ocredit: 特殊字符,规则与lcredit相同
- dcredit: 数字,规则与lcredit相同
- ucrefit: 大写字符,规则与lcredit相同
这样在设置用户密码的复杂度时,根据需要设置以上这些参数即可。
pam_cracklib在检查密码时还会先检查弱密码库。系统默认的弱密码字典位于/user/share/cracklib目录下,共有三个文件:
cracklib_dict.hwm cracklib_dict.pwd cracklib_dict.pwi
如果不进行额外配置,则pam_cracklib会首先检查设置的密码是否在系统默认的弱密码字典中。如果不在,会再继续检查是否符合其他的密码规则。
也可以设置检查自定义的弱密码字典,只需要在以上增加的内容后面再增加如下内容:
password [success=ok default=die] pam_cracklib.so debug enforce_for_root reject_username minlen=1 difok=0 lcredit=0 ocredit=0 dcredit=0 ucredit=0 dictpath=/your/dict/path
其中/your/dict/path为自定义的弱密码字典目录。但在此之前还需要生成以上三个文件。比如当前有弱密码字典文件weakpwd_dict.txt,放在目录/etc/security下,其内容如下:
111111
123456
admin
Admin
在/etc/security目录下执行cracklib-pack命令可以生成以上三个文件:
sudo cracklib-packer weakpwd_dict
weakpwd_dict.hwm weakpwd_dict.pwi weakpwd_dict.pwd
生成三个文件之后,只需要将/your/dict/path
配置为/etc/security/weakpwd_dict
,就可以从自定义的弱密码库中检查弱密码了。