某Linux发行版本用户密码复杂度设置的研究

本文主要研究某国产Linux操作系统的用户密码复杂度的配置。

背景

最近遇到一个业务程序迁移不同操作系统的问题:该业务需要使用服务器特定的账户提供指定目录的数据的下载功能。而服务器需安装一国产Linux高级服务器操作系统。按既定的账户信息设置密码,系统提示鉴定令牌操作错误无法设置。由于业务程序分散较广,因此服务器的账号、目录等配置必须符合要求。因此需调整操作系统以适应使用场景。即改造操作系统也是适配工作的一项。

问题

使用root登陆,添加组和用户及密码,出错,如下:

# groupadd sftp
# useradd -g sftp -s /sbin/nologin -M latelee
# echo "lateleePWD" | passwd --stdin latelee
passwd: 鉴定令牌操作错误

分析密码,只有大小写,且含有用户名,因此无法设置成功,需去掉此限制。

解决

查询网上资料,提到修改/etc/pam.d/system-auth,将字段

password requisite pam_pwquality.so try_first_pass local_users_only

改为

password requisite pam_cracklib.so difok=0 minle=3 ucredit=0 lcredit=0 dcredit=0

但该系统上无pam_cracklib.so库,而作为参考操作系统的centos7则存在该库,位置在/usr/lib64/security/

后经了解,pam_cracklib已经使用pam_pwquality.so替换了,在目录/usr/lib64/security/中。该库对应的配置文件为/etc/security/pwquality.conf。下面针对pwquality.conf部分字段作说明。

# difok = 5 定义新密码中必须有几个字符要与旧密码不同。带#表示默认为注释。
minlen = 8 密码的最小长度,默认为8,最小值不能低于6
dcredit = 0 大于0时表示新密码中数字出现的最多次数,小于0时表示最少次数 (密码中含数字的情况,下同)
ucredit = 0 同上,大写字母
lcredit = 0 同上,小写字母
ocredit = 0 同上,特殊字母
minclass = 3 至少含多少种字符类型(数字、大写、小写、特殊),默认至少其中的3种
# maxrepeat = 0 最大允许有多少个连续相同的字符
# dictcheck = 1 是否检查字典
# usercheck = 1 是否检查密码含用户名,非0表示检查(注:默认注释,但也会检查)
# retry = 3 重试次数

结合问题,将 minclass改为2,usercheck改为0。即密码含2种类型(大写+小写),允许密码出现用户名,其它保持默认值。

除改pwquality.conf配置文件后,也可以直接修改 /etc/pam.d/system-auth文件,在

password    requisite     pam_pwquality.so try_first_pass local_users_only

后再增加:

usercheck=0 minclass=2

修改参数后,再设置密码,成功。如下:

# echo "lateleePWD" | passwd --stdin latelee
更改用户 latelee 的密码 。
passwd:所有的身份验证令牌已经成功更新。

实验

对密码强度做一些测试。

配置:usercheck=0 minclass=2,即不检查用户名,密码含2种类型

# echo "latelee" | passwd --stdin latelee    长度小于8,错误
更改用户 latelee 的密码 。
passwd: 鉴定令牌操作错误

# echo "lateleee" | passwd --stdin latelee   仅有字母,错误
更改用户 latelee 的密码 。
passwd: 鉴定令牌操作错误

# echo "latelee1" | passwd --stdin latelee  含字母、数字,长度大于8,成功
更改用户 latelee 的密码 。
passwd:所有的身份验证令牌已经成功更新。

# echo "latelee2" | passwd --stdin latelee  修改为与前密码相近的密码,成功
更改用户 latelee 的密码 。
passwd:所有的身份验证令牌已经成功更新。

配置:usercheck=0 minclass=2 dcredit=-2 ,即不检查用户名,密码含2种类型,如含数字,数字至少为2位。

# echo "LateLee1" | passwd --stdin latelee  长度大于8,含数字且数字为1位,错误
更改用户 latelee 的密码 。
passwd: 鉴定令牌操作错误

# echo "LateLee$$" | passwd --stdin latelee  长度大于8,含特殊字母,不含数字,正常
更改用户 latelee 的密码 。
passwd:所有的身份验证令牌已经成功更新。

# echo "$$LateLee22" | passwd --stdin latelee 长度大于8,含数字且数字为2位,错误
更改用户 latelee 的密码 。
passwd:所有的身份验证令牌已经成功更新。

设置错误的密码若干次后:

# echo "lateleePWD" | passwd --stdin latelee
更改用户 latelee 的密码 。
passwd: 已经超出服务重试的最多次数

小结

根据实际情况,通过修改pwquality.confsystem-auth文件达到调整Linux密码复杂度的目的。

密码强度配置文件

一CentOS 7上的pwquality.conf配置文件:

# Configuration for systemwide password quality limits
# Defaults:
#
# Number of characters in the new password that must not be present in the
# old password.
# difok = 5
#
# Minimum acceptable size for the new password (plus one if
# credits are not disabled which is the default). (See pam_cracklib manual.)
# Cannot be set to lower value than 6.
# minlen = 9
#
# The maximum credit for having digits in the new password. If less than 0
# it is the minimum number of digits in the new password.
# dcredit = 1
#
# The maximum credit for having uppercase characters in the new password.
# If less than 0 it is the minimum number of uppercase characters in the new
# password.
# ucredit = 1
#
# The maximum credit for having lowercase characters in the new password.
# If less than 0 it is the minimum number of lowercase characters in the new
# password.
# lcredit = 1
#
# The maximum credit for having other characters in the new password.
# If less than 0 it is the minimum number of other characters in the new
# password.
# ocredit = 1
#
# The minimum number of required classes of characters for the new
# password (digits, uppercase, lowercase, others).
# minclass = 0
#
# The maximum number of allowed consecutive same characters in the new password.
# The check is disabled if the value is 0.
# maxrepeat = 0
#
# The maximum number of allowed consecutive characters of the same class in the
# new password.
# The check is disabled if the value is 0.
# maxclassrepeat = 0
#
# Whether to check for the words from the passwd entry GECOS string of the user.
# The check is enabled if the value is not 0.
# gecoscheck = 0
#
# Path to the cracklib dictionaries. Default is to use the cracklib default.
# dictpath =

一国产Linux系统的配置文件:

# Configuration for systemwide password quality limits
# Defaults:
#
# Number of characters in the new password that must not be present in the
# old password.
# difok = 5
#
# Minimum acceptable size for the new password (plus one if
# credits are not disabled which is the default). (See pam_cracklib manual.)
# Cannot be set to lower value than 6.
minlen = 8
#
# The maximum credit for having digits in the new password. If less than 0
# it is the minimum number of digits in the new password.
dcredit = 0
#
# The maximum credit for having uppercase characters in the new password.
# If less than 0 it is the minimum number of uppercase characters in the new
# password.
ucredit = 0
#
# The maximum credit for having lowercase characters in the new password.
# If less than 0 it is the minimum number of lowercase characters in the new
# password.
lcredit = 0
#
# The maximum credit for having other characters in the new password.
# If less than 0 it is the minimum number of other characters in the new
# password.
ocredit = 0
#
# The minimum number of required classes of characters for the new
# password (digits, uppercase, lowercase, others).
minclass = 3
#
# The maximum number of allowed consecutive same characters in the new password.
# The check is disabled if the value is 0.
# maxrepeat = 0
#
# The maximum number of allowed consecutive characters of the same class in the
# new password.
# The check is disabled if the value is 0.
# maxclassrepeat = 0
#
# Whether to check for the words from the passwd entry GECOS string of the user.
# The check is enabled if the value is not 0.
# gecoscheck = 0
#
# Whether to check for the words from the cracklib dictionary.
# The check is enabled if the value is not 0.
# dictcheck = 1
#
# Whether to check if it contains the user name in some form.
# The check is enabled if the value is not 0.
# usercheck = 1
#
# Whether the check is enforced by the PAM module and possibly other
# applications.
# The new password is rejected if it fails the check and the value is not 0.
# enforcing = 1
#
# Path to the cracklib dictionaries. Default is to use the cracklib default.
# dictpath =
#
# Prompt user at most N times before returning with error. The default is 1.
# retry = 3
#
# Enforces pwquality checks on the root user password.
# Enabled if the option is present.
# enforce_for_root
#
# Skip testing the password quality for users that are not present in the
# /etc/passwd file.
# Enabled if the option is present.
# local_users_only
#
# Whether to check the new password is a palindrome or not
# Enabled if the option is present
palindrome
#
# Whether to check the new password is simliar with old one
# Check include only case changes and rotated
# Disabled if the option is present
# no_similar_check

用户登陆配置

修改/etc/login.defs文件,可以调整密码有效期等信息。相关字段:

# Password aging controls:
#
#       PASS_MAX_DAYS   Maximum number of days a password may be used.
#       PASS_MIN_DAYS   Minimum number of days allowed between password changes.
#       PASS_MIN_LEN    Minimum acceptable password length.
#       PASS_WARN_AGE   Number of days warning given before a password expires.
#
PASS_MAX_DAYS   99999  
PASS_MIN_DAYS   0
PASS_MIN_LEN    5
PASS_WARN_AGE   7

本次不含密码有效期的调整,仅列出。