Shell脚本如何记录所有登录会话

wen 实用脚本 2

如何编写Shell脚本记录所有登录会话:实战指南与最佳实践

目录导读

  • 为什么要记录登录会话?
  • 环境准备与核心思路
  • 实战:两个Shell脚本实现登录审计
  • 日志存储与旋转策略
  • 常见问题与错误排查
  • 安全加固建议

为什么要记录登录会话?

在服务器运维中,记录所有用户的登录行为是安全审计的基础,无论是合规要求(如PCI-DSS、SOX),还是日常排查异常登录,一个可靠的登录会话记录脚本都能帮助管理员快速定位问题。传统方式依赖 lastlastlog 命令,但这些只能显示远程登录记录,且无法捕捉登录后的完整会话行为

Shell脚本如何记录所有登录会话

问答环节
问:直接使用系统自带的 auditd 是否足够?
答:auditd 能够监控系统调用,但对于非pam触发的登录(如SSH密钥直接登录)可能记录不全,Shell脚本可以更灵活地捕获 utmp/wtmp 文件变化,并支持自定义报警。

环境准备与核心思路

核心监控点

  1. /var/log/wtmp:保存所有登录、退出、重启等事件,使用 last 命令读取。
  2. /var/log/lastlog:记录每个用户的最新登录时间,使用 lastlog 命令。
  3. 过程记录:通过 script 命令或 pam_tty_audit 模块捕获终端输入输出。

推荐方案:使用 inotifywait(来自inotify-tools)监控 wtmp 文件变化,一旦有写入就触发脚本解析。

安装依赖

sudo apt-get install inotify-tools  # Debian/Ubuntu
sudo yum install inotify-tools      # CentOS/RHEL

实战:两个Shell脚本实现登录审计

脚本1:实时捕获登录事件

该脚本通过 inotifywait 监听 wtmp 文件,一旦有修改就调用 last 命令提取最新记录:

#!/bin/bash
LOG_FILE="/var/log/wtmp"
OUTPUT_LOG="/var/log/login_monitor.log"
inotifywait -m -e modify "$LOG_FILE" | while read file event; do
    # 获取最后一条登录记录
    LATEST=$(last -w -1 | head -n 1)
    echo "$(date '+%Y-%m-%d %H:%M:%S') - LOGIN: $LATEST" >> "$OUTPUT_LOG"
    # 可选:发送邮件或Webhook报警
    # echo "$LATEST" | mail -s "New login detected" admin@example.com
done

注意-w 参数显示完整用户名称,避免被截断。

脚本2:记录会话详细行为(使用 script 命令)

通过 pam_scriptsystemdExecStartPost 钩子,在用户登录后自动启动 script 记录:

#!/bin/bash
USER=$(whoami)
SESSION_ID=$(date +%s)
SCRIPT_DIR="/var/log/sessions/$USER"
mkdir -p "$SCRIPT_DIR"
/usr/bin/script -t=2>"${SCRIPT_DIR}/${SESSION_ID}_timing.log" -a "${SCRIPT_DIR}/${SESSION_ID}_session.log"

问答环节
问:script 命令会占用大量磁盘空间吗?
答:是的,建议配合 logrotate 定期清理,并设置最大保留天数,只保留最近7天的会话日志。

日志存储与旋转策略

为避免日志填满磁盘,必须配置滚动策略,在 /etc/logrotate.d/ 下新建配置文件:

/var/log/login_monitor.log {
    monthly
    rotate 12
    compress
    missingok
    notifempty
    postrotate
        systemctl restart login-monitor.service  # 如果脚本以服务运行
    endscript
}

对于会话记录目录,可添加以下配置:

/var/log/sessions/*/*.log {
    daily
    maxsize 50M
    rotate 7
    compress
    minsize 10M
    create 640 root root
}

问答环节
问:如何防止攻击者篡改日志文件?
答:使用 chattr +a 设置日志文件为追加模式(仅允许追加,不允许删除和覆盖),并配置远程日志服务器(如syslog-ng)实现日志异地备份。

常见问题与错误排查

问题1:inotifywait 无法检测到文件变化

  • 原因:某些系统上 /var/log/wtmp 可能被其他进程独占锁。
  • 解决:改用 tail --follow=name 命令替代:
    tail --follow=name /var/log/wtmp | while read line; do
      # 处理新行
    done

问题2:last 命令输出包含中文字符乱码

  • 解决:强制设置 LANG=C
    LANG=C last -w -1 | head -n 1

问题3:认证方式不同导致记录不全

  • 场景:通过 sudosu 切换用户不会被 wtmp 记录。
  • 补充:额外启用 auditd 监控 execve 系统调用,或使用 pam_loginuid.so 模块。

安全加固建议

  1. 最小权限原则:脚本以非root用户运行,仅允许读取 wtmp 和写入指定目录。
  2. 加密传输:如果使用邮件或Webhook报警,务必使用SSL/TLS(如 curl --ssl-reqd)。
  3. 定期审计:每周手动检查 /var/log/login_monitor.log 是否被篡改(计算哈希值并与备份对比)。
  4. 避免IP泄露:如果日志中包含内网IP,在输出到外部系统前进行脱敏处理。

技术延伸:对于企业级需求,可以结合 fail2ban 实现自动封禁暴力破解IP,脚本只需在检测到连续失败登录时调用 iptablesufw 规则即可。

通过上述Shell脚本组合,你不仅能够记录所有登录会话,还能实现实时告警、存储优化和安全审计,运维工作的本质不在于“监控”,而在于“可追溯”——当事件发生时,你能拿出精确到秒的日志作为证据。

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