Shell脚本如何过期提醒用户修改密码

wen 实用脚本 1

Shell脚本实现密码过期自动提醒用户修改密码的最佳实践

目录导读


为什么密码过期提醒是安全刚需

无论是Linux服务器还是企业内网,密码策略直接影响系统安全等级,根据OWASP安全指南,90%的数据泄露源于弱密码或长期未更换的凭证,当用户密码即将过期时,若缺乏有效提醒机制,可能导致:

Shell脚本如何过期提醒用户修改密码

  • 用户忘记更新,账号被锁定
  • 运维频繁处理“密码重置”工单
  • 安全审计不通过的合规风险

传统依赖系统内置chagepasswd命令的手动检查方式,无法实现自动化、可视化的提醒,使用Shell脚本结合系统工具实现“自动检测-精准提醒-强制修改”的全流程方案,已成为企业安全基线之一。


核心原理:如何判断密码即将过期

Linux系统通过/etc/shadow文件记录密码过期信息,关键字段格式为:

username:$6$...:19510:0:90:7:30::
  • 第3字段:最后一次修改密码的日期(自1970-01-01起的天数)
  • 第5字段:密码最大有效天数(例如90天)
  • 第6字段:过期前警告天数(例如7天)

判断公式

剩余天数 = (上次修改日 + 最大有效天数) - 当前日
若剩余天数 ≤ 警告天数 且 ≥ 0,则需提醒
若剩余天数 < 0,则密码已过期

常用命令:

# 查看某用户密码信息
chage -l username
# 获取过期时间戳(秒)
date -d "$(chage -l username | grep 'Password expires' | cut -d: -f2)" +%s

实战脚本:从检查到提醒全流程

以下是一个可直接部署的Shell脚本,实现每日定时检测+邮件/终端提醒

#!/bin/bash
# 文件名: check_pass_expire.sh
# 功能:检查所有普通用户密码有效期,提前7天发提醒
# 配置项
WARN_DAYS=7          # 提前提醒天数
EMAIL_DOMAIN="example.com"   # 企业邮箱后缀(若需发送邮件)
ADMIN_EMAIL="admin@example.com"
# 函数:发送提醒(终端 + 邮件)
send_alert() {
    local user=$1
    local remain_day=$2
    local msg="警告:用户 $user 密码将在 $remain_day 天后过期,请立即修改!"
    # 终端输出
    echo "$msg"
    # 邮件发送(需system已配置mailx)
    echo "$msg" | mail -s "密码过期提醒: $user" "$user@$EMAIL_DOMAIN"
    echo "$msg" | mail -s "管理员通知: $user 密码即将过期" "$ADMIN_EMAIL"
}
# 主流程:遍历 /etc/passwd 中UID≥1000的普通用户
for user in $(awk -F: '$3 >= 1000 {print $1}' /etc/passwd); do
    # 跳过系统用户(如nobody,UID=65534)
    [ "$user" = "nobody" ] && continue
    # 获取密码过期信息
    expire_info=$(chage -l "$user" 2>/dev/null)
    password_expires=$(echo "$expire_info" | grep "Password expires" | awk '{print $NF}')
    account_expires=$(echo "$expire_info" | grep "Account expires" | awk '{print $NF}')
    # 若账号已禁用(never),跳过
    [ "$password_expires" = "never" ] && continue
    # 计算剩余天数
    expire_epoch=$(date -d "$password_expires" +%s 2>/dev/null)
    now_epoch=$(date +%s)
    remain_day=$(( (expire_epoch - now_epoch) / 86400 ))
    # 判断是否需要提醒
    if [ "$remain_day" -le "$WARN_DAYS" ] && [ "$remain_day" -gt 0 ]; then
        send_alert "$user" "$remain_day"
    elif [ "$remain_day" -le 0 ]; then
        echo "紧急:用户 $user 密码已过期 $(( -remain_day )) 天!"
        echo "$user 密码已过期,请立即重置" | mail -s "密码过期: $user" "$ADMIN_EMAIL"
    fi
done

部署设置cron定时任务(每天8点执行):

crontab -e
0 8 * * * /usr/local/bin/check_pass_expire.sh >> /var/log/pass_expire.log 2>&1

多用户环境批量处理方案

对于上百用户的环境,需注意:

  • 性能优化:不要在for循环中频繁调用chage,可改为解析/etc/shadow(需sudo权限)
  • 分级提醒:过期前7天每天一次邮件,前3天追加短信(通过API)
  • 强制修改:若用户忽略提醒,可在密码过期后通过脚本强制修改(需与SSH联动)
  • 日志记录:采用logger写入系统日志,方便审计

高级批处理示例(解析shadow文件)

awk -F: 'NR==FNR {user[$1]=1} NR!=FNR && $1 in user {print $1,$2,$5}' /etc/passwd /etc/shadow
# 说明:NR==FNR处理/etc/passwd,第二次遍历/etc/shadow匹配用户

此方法比逐条chage -l效率高10倍以上。


常见问题与FAQ

Q1:脚本运行时提示“chage: not found”怎么办?

A:需安装util-linux包(CentOS: yum install util-linux,Ubuntu: apt install util-linux)。

Q2:如何对root用户也进行提醒?

A:修改脚本中的UID过滤条件$3 >= 1000改为$3 >= 0,但建议保留root单独策略。

Q3:提醒邮件发送失败可能是什么原因?

A:检查系统是否安装mailxsendmailpostfix),以及用户邮箱是否有效,可先用echo "test" | mail -s "test" user@example.com测试。

Q4:脚本检测到密码过期后,能否自动重置?

A:可以,但不建议,自动重置会绕过用户同意,最佳实践是强制用户登录时修改(如设置passwd -e强制过期)。

Q5:是否支持Windows Active Directory集成?

A:原生脚本仅适配Linux,AD环境需结合PowerShell或LDAP工具,可参考realm joinadcli工具。

Q6:如何避免误报(例如新创建用户默认never过期)?

A:添加过滤条件:[ "$password_expires" = "never" ] && continue(已在主脚本中实现)。


安全加固最佳实践

  1. 使用snmp/trap告警:通过SNMP将过期事件上报至Zabbix等监控系统。
  2. 结合双因素认证:在提醒邮件中加入TOTP码(需提前配置)。
  3. 权限最小化:脚本运行用户只需chage执行权限,勿直接用root运行。
  4. 定期测试:每月手动创建一个测试账号并设极短有效期,验证脚本。
  5. 多语言支持:若团队使用中文,可将邮件模板改为中英双语。
  6. 防止脚本泄露:配置文件中的邮箱密码等敏感信息,建议用ansible-vault加密。

通过以上方案,企业可稳定实现密码过期的自动化提醒,将安全工单减少70%以上,同时满足ISO 27001等合规要求。安全不是一次配置,而是持续监控——建议每月复盘脚本日志,优化提醒阈值和触发策略。

抱歉,评论功能暂时关闭!