Linux PAM 模块之 cracklib
2020-03-20 15:39:33 阿炯

简单的介绍一下PAM,PAM(Pluggable Authentication Modules )是由Sun提出的一种具有相当灵活性的认证机制。它通过提供一些动态链接库和一套统一的API,将系统提供的服务和该服务的认证方式分开,使得系统管理员可以灵活地根据需要给不同的服务配置不同的认证方式而无需更改服务程序,同时也便于向系统中添加新的认证手段。PAM模块是一种嵌入式模块,修改后即时生效。

如何在Linux系统中限制密码长度的同时对密码的复杂程度也进行管理,密码符合长度规则但却很简单很容易被猜出来,查了相关资料后发现了PAM中的pam_cracklib模块就是用来做密码复杂度检测的。

pam的重要文件如下:
/usr/lib/libpam.so.*## PAM核心库
/etc/pam.conf   ## PAM配置文件
/etc/pam.d/*    ## PAM各个模块的配置文件
/lib/security/pam_*.so     ## 可动态加载的PAM模块

PAM配置文件的每一行的格式:Module-type   Control-flag   Module-path   Arguments

模块类型控制字符    模块路径模块参数

Module-type:
auth:确定有关用户认证的两方面。1、他确认用户就是他们自己,这通过应用程序提示用户输入密码 或者其他正式身份的办法。2、这类模块会赋予成员资格。
account:处理非认证级的账号管理。典型的用法是基于一天的不同时间来限制、允许访问某服务。限制 当前可用的系统资源(最大用户数)或者限制特定用户—root只能从控制台登陆。
session:一系列有关动作,只在用户得到/失去服务时要做的事。这包括记录用户的登录/退出、挂载必要 的目录等。
password:设置密码。


Control-flag:
required:表示本模块必须返回成功才能通过认证,但是如果该模块返回失败的话,失败结果也不会立即通知用户,而是要等到同一stack中的所有模块全部执行完毕再将失败结果返回给应用程序。可以认为是一个必要条件。
requisite:与required类似,该模块必须返回成功才能通过认证,但是一旦该模块返回失败,将不再执行同一stack内的任何模块,而是直接将控制权返回给应用程序。是一个必要条件。注:Solaris不支持。
sufficient:表明本模块返回成功已经足以通过身份认证的要求,不必再执行同一stack内的其它模块,但是 如果本模块返回失败的话可以忽略。可以认为是一个充分条件。
optional:表明本模块是可选的,它的成功与否一般不会对身份认证起关键作用,其返回值一般被忽略。
include:从字面就知道什么意思了,包含另外一个配置文件。


Module-path:
Debian的PAM module存放目录默认是在/lib/security。在各个模块的配置文件里,不用写绝对路径,直接写这个默认目录下面的模块名就可以了。当然也可以写绝对路径。


Arguments:
各个模块的参数都不一样,具体的要开发者的man手册。无效参数不会对结果有影响,但是会被日志记录 下来。首先看/lib/security有没有这个模块,再使用模块名。


pam_cracklib是一个PAM模块,用来检查密码是否违反密码字典,这个验证模块可以通过插入password堆栈,为特殊的应用提供可插入式密码强度性检测。它的工作方式就是先提示用户输入密码,然后使用一个系统字典和一套规则来检测输入的密码是否不能满足强壮性要求。密码的强度检测分二次进行,第一次只是检测密码是否是提供的对比字典中的一部分,如果检测结果是否定的,那么就会提供一些附加的检测来进一步检测其强度,例如检测新密码中的字符占旧密码字符的比例,密码的长度,所用字符大小写状况,以及是否使用了特殊字符等等(libpam-cracklib)。

下面是cracklib模块的一些参数:
debug:将debug信息写入syslog
type=XXX:提示输入密码的文本内容。默认是"New UNIX password: " and "Retype UNIX password: ",可自定义
retry=N:用户最多可以几次输入密码后报错。默认是1次。
difok=N:新密码有几个字符不能和旧密码相同,默认是5个。另外如果新密码有1/2的字符于旧不同,也会被接受。
diginore=N:默认当新密码有23个字符时,difok选项会被忽略。
minlen=N:最小密码长度。
dcredit=N:当N>=0时,N代表新密码最多可以有多少个阿拉伯数字。当N<0时,N代表新密码最少要有多少个阿拉伯数字。
ucredit=N:和dcredit差不多,但是这里说的是大写字母。
lcredit=N:和dcredit差不多,但是这里说的是小写字母。
ocredit=N:和dcredit差不多,但是这里说的是特殊字符。
use_authtok:在某个与密码相关的验证模块后使用此选项,例如pam_unix.so验证模块

pam_cracklib 模块式PAM配置接口的基本模块,在Debian系统中配置文件是 /etc/pam.d/common-password 但是在Redhat系统中配置文件是 /etc/pam.d/system-auth 配置大致像这样:
password required pam_cracklib.so retry=3 minlen=6 difok=3
password required pam_unix.so md5 use_authtok

第一行是 pam_cracklib模块和设置的几个模块参数
第二行是 pam_unix模块,MD5表示采用MD5加密

pam_cracklib可以记录用户使用的历史密码,并且不允许用户重复使用旧的密码,实际上存储用户旧密码的是通过pam_unix模块实现的。第一步是建立一个空文件用来存储旧密码/etc/security/opasswd,如果你没有建立文件却使用了历史密码记录功能的话,所有的密码更新都会失败,因为pam_unix模块会报错。

opasswd就像/etc/shadow文件,因为他记录用户密码的哈希
touch /etc/security/opasswd
chown root:root /etc/security/opasswd
chmod 600 /etc/security/opasswd

一旦建立了opasswd文件,就可以在pam_unix模块后面加上参数remember=N来开始记录旧密码,remember参数记录你想记录多少旧密码,他的最大值是400,如果你设置的值超过400会当做400来对待,例如:
password required pam_cracklib.so retry=3 minlen=12 difok=4
password required pam_unix.so md5 remember=12 use_authtok

opasswd文件内容格式如下:
hal:1000:<n>:<hash1>,<hash2>,...,<hashn>

文件以':'分割,第一列是用户名,第二列是用户ID,第三列是目前记录了该用户多少个旧密码,hashN是每次密码的MD5值,opasswd在某些系统安装PAM模块时会自动建立。

密码字典检查

pam_cracklib 也可以检查用户设置的密码是不是违反系统内部的密码字典,在Debian系统中pam_cracklib的密码字典在/var/cache/cracklib目录下,而且每天晚上update-cracklib脚本会自动的rebuild密码字典。

/etc/login.defs 文件设置密码过期时间等一系列参数,注意login.defs中设置的参数只有是用系统的useradd程序新建的一个用户时才会有login.defs中设置的属性,如果是用其他机器新建的用户,则没有以上属性,不过可以试用chage命令手动添加相关属性。

chage参数如下:
-m 密码可更改的最小天数。 为零时代表任何时候都可以更改密码。
-M 密码保持有效的最大天数。
-W 用户密码到期前,提前收到警告信息的天数。
-E 帐号到期的日期。过了这天,此帐号将不可用。
-d 上一次更改的日期
-i 停滞时期。如果一个密码已过期这些天,那么此帐号将不可用。
-l 例出当前的设置。由非特权用户来确定他们的密码或帐号何时过期。


关于 opasswd

相当于old-paswwd,记录了每用户在过去的5次密码的hash值,来看其最近使用的5次密码中有没有重复使用的。

Prevent From Using Or Reuse Same Old Passwords

In Red Hat Enterprise Linux 7 (RHEL 7) the password history is stored in the file /etc/security/opasswd. You can only edit this file while logged in as the root user.

pam_unix/pam_unix2 module

This is the standard Unix authentication module. It uses standard calls from the system's libraries to retrieve and set account information as well as authentication. Usually this is obtained from the /etc/passwd and the /etc/shadow file as well if shadow is enabled.

This module provides functionality for PAM modules such as authentication, account management and more. Same module can be used to maintain a list of old passwords for every user. This is useful if you want to disallow use of old passwords. The old password list is located in the /etc/security/opasswd file.

Configuration files

You need to edit the following files:
/etc/login.defs – Shadow password suite configuration
/etc/pam.d/common-auth – OpenSuse/Suse Enterprise Linux pam config file.
/etc/pam.d/system-auth – CentOS/RHEL/Fedora/Red Hat/Scientific Linux pam config file.
/etc/pam.d/common-password – Debian / Ubuntu Linux pam config file.
/etc/security/opasswd – Store old passwords.

/etc/pam.d/common-auth

Edit/add password line and append remember=13 to prevent a user from re-using any of his or her last 13 passwords:
password sufficient pam_unix.so use_authtok md5 shadow remember=13

IF you are using pam_unix2.so, update it as follows:
password sufficient pam_unix2.so use_authtok md5 shadow remember=13

Save and close the file. Please note that the last 13 passwords for each user are saved in /etc/security/opasswd file in order to force password change history and keep the user from alternating between the same password too frequently.

Enable password aging

Edit /etc/login.defs,pam_unix.so/pam_unix2.so is configured to remember 13 passwords. User can not use the same password for at least 3 months (13*7=91 days = 3 months)

# vim /etc/login.defs
#Set the minimum number of days (PASS_MIN_DAYS=7) allowed between password changes:
### Minimum number of 7 days before a user can change the password since the last change ###
PASS_MIN_DAYS=7

Save and close the file.

If the file /etc/security/opasswd does not exist, create the file using touch or shell redirection command:
# [ ! -f /etc/security/opasswd ] && touch /etc/security/opasswd
OR
# [ ! -f /etc/security/opasswd ] && >/etc/security/opasswd

Use the following ls command to verify file permissions:
# ls -lZ /etc/security/opasswd

Linux based system will remember last 13 passwords. If user tries to use any one of the last 13 old passwords, he/she will get an error message as follows on screen:
Password has been already used. Choose another.


参考链接

Linux cracklib模块

sysadmin_pam_cracklib