Linux可通过PAM+Shell脚本实现密码到期强提醒:设置chage警告天数,配置pam_exec.so执行高亮提示脚本,并用pam_pwquality.so强制过期改密,确保每次交互式登录均醒目提醒且无法绕过。
Linux本身不提供图形化弹窗或桌面级强提醒,但可通过Shell登录时的明确文字提示实现“强提醒”效果——关键在于让提示信息足够醒目、无法忽略,并在用户每次密码认证登录时稳定触发。
确保chage警告参数已正确设置
系统登录时的密码到期提示,直接依赖
中第6字段(warn)的值,该值由
写入。必须确认它已生效:
运行
(例如提前7天提醒),不要设为0或负数
用
检查输出,确认“Password expires”和“Weekly warning before password expires”两行都显示有效数值
若用户是新建的,还需检查
中
是否被设为非零值(否则新建用户可能默认无警告)
让提示在Shell登录时强制显示且视觉突出
默认提示(如
)容易被快速滚动的启动信息淹没。可通过PAM在登录成功后插入高亮提示:
CentOS Linux 7.9.2009
CentOS Linux 7.9.2009是传统CentOS Linux 7的最后主要版本,也是很多企业历史服务器中仍可能遇到的系统版本。它以稳定、兼容RHEL 7生态、文档丰富和软件支持广泛著称,曾长期用于Web服务、数据库、虚拟化节点和企业内部业务系统。不过CentOS Linux 7已于2024年6月30日停止维护,现在继续使用会面临安全补丁缺失风险。该版本更适合旧业务迁移、历史环境恢复或离线兼容性测试。
下载
编辑
(SSH登录)或
(TTY登录),在末尾添加一行:
创建脚本
,内容为:
赋予执行权限:
配合PAM拦截过期密码,杜绝静默绕过
仅靠提示不够——必须确保密码真正过期后,用户无法跳过修改流程。这需要PAM模块主动干预:
确认
(Debian/Ubuntu)或
(RHEL/CentOS)中包含有效策略:
(可选,增加暴力尝试延迟)
重点验证
是否启用:它不仅校验复杂度,还会读取
数据并在密码过期时拒绝
操作,强制用户面对修改界面
测试:用
模拟刚过期状态,再以该用户SSH登录,应看到明确提示并进入强制改密流程,而非直接进入Shell
补充:对非交互式登录场景做兜底
纯SSH密钥登录、
切换、cron任务等不会触发上述Shell登录提醒。如需覆盖,建议:
禁用密钥登录用户的密码过期提醒意义不大,应统一要求启用双因素或定期轮换密钥
在用户
中加入轻量检查(仅对交互式Bash有效):
/etc/shadowchage -Wsudo chage -W 7 usernamesudo chage -l username/etc/login.defsPASS_WARN_AGEYour password will expire in 3 days/etc/pam.d/sshd/etc/pam.d/loginsession optional pam_exec.so stdout /usr/local/bin/passwd-expiry-notice.sh/usr/local/bin/passwd-expiry-notice.sh#!/bin/bash
days=$(chage -l "$PAM_USER" 2>/dev/null | awk -F': ' '/Password expires/ {print $2}' | xargs)
if [[ "$days" =~ "never" ]] || [[ -z "$days" ]]; then exit 0; fi
remaining=$(echo "$days" | awk '{print $1}')
if [[ "$remaining" =~ ^[0-9]+$ ]] && [ "$remaining" -le 7 ] && [ "$remaining" -gt 0 ]; then
echo ""
echo "⚠️ WARNING: Your password expires in ${remaining} day(s)!"
echo " Please run 'passwd' now to update it."
echo ""
fisudo chmod +x /usr/local/bin/passwd-expiry-notice.sh/etc/pam.d/common-password/etc/pam.d/system-authpassword [success=ok default=ignore] pam_unix.so obscure sha512auth [default=die] pam_faildelay.so delay=3000000pam_pwquality.sochagepasswdchage -d $(date -d 'yesterday' +%s) usernamesu -~/.bashrcif [ -z "$PS1" ]; then return; fi
exp_days=$(chage -l "$USER" 2>/dev/null | awk -F': ' '/Password expires/ {print $2}' | awk '{print $1}')
if [[ "$exp_days" =~ ^[0-9]+$ ]] && [ "$exp_days" -le 3 ]; then
echo -e "\033[1;31m*** PASSWORD EXPIRES IN ${exp_days} DAYS! RUN 'passwd' NOW! ***\033[0m"
fi