在Ubuntu系统中,/etc/login.defs文件是控制用户密码策略的核心配置文件,它直接决定了密码最大使用天数、最小使用天数、过期警告天数以及账户禁用天数等关键安全参数。默认情况下,Ubuntu 20.04及以上版本的login.defs中PASS_MAX_DAYS设为99999,PASS_WARN_AGE设为7,这意味着密码几乎不会过期,用户只会在过期前7天收到提醒。如果你想让系统强制用户定期更换密码并提前收到警告,就需要手动修改这个文件中的对应参数。下面我会从参数含义、修改方法、验证方式到安全建议,把这个话题彻底讲透。
login.defs文件的核心参数详解
login.defs位于/etc/login.defs,它是shadow-utils软件包提供的全局用户配置文件。这个文件中与密码过期直接相关的参数有以下几个:
PASS_MAX_DAYS:密码最大有效天数,超过这个天数后用户必须修改密码。默认值99999,基本等于不过期。
PASS_MIN_DAYS:两次密码修改之间的最小间隔天数,防止用户频繁改回旧密码。默认值0,表示随时可以改。
PASS_WARN_AGE:密码过期前多少天开始向用户发送警告提示。默认值7天。
PASS_MIN_LEN:密码最小长度,默认在Ubuntu中通常是6,但实际生效可能受PAM模块影响。
INACTIVE:账户过期后禁用的天数。如果设为-1则表示不禁用,设为正数则在密码过期后该天数内未登录就锁定账户。
你可以用以下命令查看当前文件内容:
cat /etc/login.defs
输出中你会看到类似这样的行:
PASS_MAX_DAYS 99999 PASS_MIN_DAYS 0 PASS_WARN_AGE 7
如何修改密码过期天数和警告设置
修改login.defs需要root权限,使用你熟悉的编辑器打开文件:
sudo vim /etc/login.defs
或者用nano:
sudo nano /etc/login.defs
找到对应参数行,去掉前面的注释符号#(如果有的话),然后改成你想要的值。比如你希望密码每90天过期、提前14天警告:
PASS_MAX_DAYS 90 PASS_MIN_DAYS 1 PASS_WARN_AGE 14
这里PASS_MIN_DAYS设为1是为了防止用户当天改密码后立即又改回来,强制至少间隔一天。
保存退出后,修改对新创建的用户立即生效。但对于已经存在的用户,需要用chage命令单独设置,因为login.defs只影响新建账户的默认值。
用chage命令针对现有用户设置密码策略
chage命令是管理用户账户过期信息的专用工具,它会把信息写入/etc/shadow文件。查看某个用户当前的密码策略:
sudo chage -l username
输出示例:
Last password change : May 15, 2025 Password expires : never Password inactive : never Account expires : never Minimum number of days between password change : 0 Maximum number of days between password change : 99999 Number of days of warning before password expires : 7
要修改现有用户的密码过期策略,比如设为90天过期、14天警告:
sudo chage -M 90 -m 1 -W 14 username
参数说明:-M是最大天数,-m是最小天数,-W是警告天数。如果想让账户在密码过期后30天不登录就锁定:
sudo chage -I 30 username
如果想强制用户下次登录就必须改密码:
sudo chage -d 0 username
这会把"上次修改密码日期"设为epoch(1970-01-01),系统会认为密码已经过期。
login.defs与PAM模块的关系和区别
很多人容易混淆login.defs和PAM(Pluggable Authentication Modules)的作用。login.defs是shadow-utils包的配置文件,主要影响useradd、usermod等命令创建或修改用户时的默认行为。而PAM模块中的pam_unix.so才是在用户实际登录时强制执行密码策略的组件。
PAM的密码策略配置在/etc/pam.d/common-password文件中,Ubuntu系统典型内容如下:
password requisite pam_pwquality.so retry=3 password [success=1 default=ignore] pam_unix.so obscure use_authtok try_first_pass sha512 password requisite pam_deny.so password required pam_permit.so
如果你想从PAM层面控制密码复杂度(比如最小长度、字符种类要求),需要修改pam_pwquality.so的参数。但密码过期天数这个逻辑,主要还是由login.defs的默认值和chage的实际设置来控制。
需要特别注意:如果你只改了login.defs但没有改PAM中pam_unix.so的参数,某些情况下密码过期策略可能不会被严格执行。检查pam_unix.so是否包含相关参数:
grep pam_unix /etc/pam.d/common-password
确保pam_unix.so行没有被注释掉,并且包含sha512等加密方式。
企业级安全建议:密码策略的最佳实践
根据等保2.0和CIS Benchmark的建议,生产环境中的密码策略应该满足以下标准:
密码最大有效期不超过90天(高安全场景建议60天)。
密码最小有效期至少1天,防止循环使用旧密码。
过期警告天数设为14天,给用户充足的准备时间。
账户锁定策略:密码过期后30天内未登录则禁用账户。
密码最小长度至少12位,包含大小写字母、数字和特殊字符。
在Ubuntu上实现这些策略,除了修改login.defs,还需要配合PAM的pwquality模块。编辑/etc/security/pwquality.conf:
minlen = 12 dcredit = -1 ucredit = -1 ocredit = -1 lcredit = -1
dcredit=-1表示至少1个数字,ucredit=-1至少1个大写,ocredit=-1至少1个特殊字符,lcredit=-1至少1个小写。
批量设置所有用户密码策略的方法
如果你管理的服务器有几十甚至上百个用户,逐个用chage设置显然不现实。可以写一个简单的脚本批量处理:
#!/bin/bash
# 批量设置所有普通用户的密码策略
for user in $(awk -F: '$3>=1000 && $3<60000 {print $1}' /etc/passwd); do
echo "Setting policy for $user"
chage -M 90 -m 1 -W 14 -I 30 "$user"
done
这个脚本会遍历所有UID在1000到60000之间的普通用户(排除系统账户),统一设置90天过期、1天最小间隔、14天警告、30天锁定。保存为set_policy.sh后执行:
sudo bash set_policy.sh
执行后可以用以下命令抽查几个用户确认生效:
sudo chage -l user1 sudo chage -l user2
常见问题排查和注意事项
修改login.defs后新用户自动继承新策略,但如果你发现新用户的密码策略还是旧值,检查是否有其他配置文件覆盖了默认值。某些情况下/etc/default/useradd也会影响useradd的行为,查看一下:
cat /etc/default/useradd
如果里面有INACTIVE或其他参数设置,可能会与login.defs产生冲突,以login.defs为准。
另外,如果系统启用了LDAP或AD域认证,本地的login.defs可能对域用户不生效,需要在域控端统一设置密码策略。
还有一个容易忽略的点:root用户的密码策略默认不受login.defs约束。要单独设置root的密码过期:
sudo chage -M 90 -m 7 -W 14 root
root的PASS_MIN_DAYS建议设长一些,比如7天,避免管理员频繁被强制改密码影响运维工作。
验证修改是否真正生效
修改完成后,创建一个测试用户来验证:
sudo useradd -m testuser sudo passwd testuser
然后查看测试用户的策略:
sudo chage -l testuser
确认PASS_MAX_DAYS、PASS_WARN_AGE等参数是否符合预期。同时用testuser登录一次,系统应该会在接近过期时弹出警告信息。警告信息通常显示在登录时的终端提示中,内容类似"Your password will expire in X days"。
如果你想模拟密码即将过期的场景来测试警告是否正常工作,可以手动把测试用户的密码过期日期改成几天后:
sudo chage -d $(date -d "+5 days" +%Y-%m-%d) testuser
然后用testuser登录,应该能看到"Your password will expire in 5 days"的提示。
总结
Ubuntu系统中login.defs是密码过期策略的基础配置文件,但它只定义默认值,真正对现有用户生效需要配合chage命令。安全加固不是改一个参数就完事,需要login.defs、chage、PAM的pwquality模块三者协同配合。建议在生产环境中将密码最大天数控制在60到90天之间,警告天数设为14天,同时配合密码复杂度要求和账户锁定策略,才能构建一套完整的密码安全体系。定期用脚本审计所有用户的密码策略状态,是运维人员应该养成的习惯。
