Shell脚本如何审计管理员操作日志

wen 实用脚本 3

本文目录导读:

Shell脚本如何审计管理员操作日志

  1. 场景一:审计Shell脚本内部执行的操作
  2. 场景二:审计管理员在终端的所有操作
  3. 进阶:统一日志平台与 logger
  4. 总结建议

在Shell脚本中审计管理员操作日志,通常有两种主要场景:

  1. 审计通过Shell脚本执行的操作(脚本内部记录)
  2. 审计管理员在Shell终端执行的所有命令(全局记录)

以下分别给出针对这两种场景的解决方案。


审计Shell脚本内部执行的操作

如果你的目标是记录某个特定脚本在执行过程中做了什么(例如修改了哪个配置文件、重启了哪个服务),最佳实践是在脚本的关键操作点插入日志记录函数。

方案:使用日志函数 + 时间戳

创建一个通用的日志函数,并在关键操作前后调用它。

#!/bin/bash
# 日志文件路径
LOG_FILE="/var/log/admin_audit.log"
# 创建日志函数
log_audit() {
    local user=$(whoami)
    local pid=$$
    local timestamp=$(date "+%Y-%m-%d %H:%M:%S")
    # 输出到日志文件
    echo "[${timestamp}] [USER:${user}] [PID:${pid}] [ACTION]: $*" >> "${LOG_FILE}"
}
# 示例脚本操作
main() {
    log_audit "开始执行部署脚本"
    # 模拟备份配置
    cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak
    if [ $? -eq 0 ]; then
        log_audit "备份 nginx.conf 成功"
    else
        log_audit "备份 nginx.conf 失败"
    fi
    # 模拟修改配置
    sed -i 's/worker_processes 1/worker_processes auto/' /etc/nginx/nginx.conf
    log_audit "修改 nginx worker_processes 设置"
    # 重启服务
    systemctl restart nginx
    log_audit "重启 nginx 服务"
    log_audit "部署脚本执行完毕"
}
main "$@"

优点:

  • 记录精确,可自定义格式(用户、PID、操作详情)。
  • 可以记录操作结果(成功/失败)。

注意:

  • 必须确保LOG_FILE目录存在且脚本有写入权限。
  • 生产环境建议使用logger命令配合syslog(见下方“进阶”)。

审计管理员在终端的所有操作

如果你的目标是捕获所有管理员(特别是root用户)在Shell中输入的所有命令和输出,通常需要操作系统级别的审计工具。

方案 A:启用 history 命令的高级配置

Linux的history默认只记录命令,不记录时间、用户、IP(SSH连接时),以下配置可以增强审计。

修改 ~/.bashrc/etc/bashrc(对所有用户生效):

# 记录时间戳
export HISTTIMEFORMAT="%F %T "
# 增大历史记录容量
export HISTSIZE=100000
export HISTFILESIZE=500000
# 多终端合并,避免覆盖
shopt -s histappend
# 实时写入,而非退出时才写
export PROMPT_COMMAND="history -a; $PROMPT_COMMAND"

缺点:

  • 只能记录命令,无法记录命令的输出(例如cat /etc/shadow的结果不会记录)。
  • 用户可以通过unset HISTORYhistory -c清除,安全性较低

方案 B:使用 script 命令记录完整会话(推荐)

script 可以记录终端的所有输入和输出,包括程序运行结果,适合临时审计或对特定用户启用。

登录即启动 script

/etc/profile/etc/bashrc 末尾添加(适用于所有bash用户):

# 记录所有登录用户的终端会话
if [ -z "$SCRIPT" ]; then
    SCRIPT=1
    LOG_DIR="/var/log/session"
    if [ ! -d "$LOG_DIR" ]; then
        sudo mkdir -p "$LOG_DIR"
        sudo chmod 755 "$LOG_DIR"
    fi
    # 生成带时间戳和用户名的文件名
    LOG_FILE="${LOG_DIR}/$(date +%Y%m%d)_$(whoami)_$$.log"
    script -q -t 2>"${LOG_FILE}.timing" "${LOG_FILE}"
    exit
fi

优点:

  • 完整记录所有输入输出,包括文件内容、编辑操作等。
  • 可通过scriptreplay回放(需要.timing文件)。

缺点:

  • 日志文件体积增长快(文本格式)。
  • 需要定时清理归档。

方案 C:审计守护进程 auditd(企业级)

Linux内核自带的 auditd 是最强大的审计工具,可以审计系统调用、文件访问、命令执行等,适合需要合规(如等保2.0、PCI-DSS)的环境。

安装并启动

yum install audit audit-libs   # CentOS/RHEL
apt install auditd             # Ubuntu/Debian
systemctl enable auditd
systemctl start auditd

添加审计规则

# 审计所有root用户的命令执行(使用execve系统调用)
auditctl -a exit,always -F arch=b64 -S execve -F uid=0
# 审计所有用户的sudo执行
auditctl -a exit,always -F arch=b64 -S execve -F exe=/usr/bin/sudo
# 审计特定敏感文件访问(/etc/shadow)
auditctl -w /etc/shadow -p rwxa -k shadow_access

查看日志

ausearch -k shadow_access   # 按关键词搜索
ausearch -ui root -sc execve   # 查看root用户执行的命令
aureport --tty              # 查看所有tty输入(类似script记录)

优点:

  • 内核级,不可绕过(即使管理员禁用history)。
  • 日志格式标准化,支持远程发送到日志服务器(如SIEM)。
  • 不影响系统性能(针对规则数量优化)。

缺点:

  • 配置稍复杂。
  • 需要专门学习ausearch / aureport 查询语法。

进阶:统一日志平台与 logger

无论是脚本内记录还是全局记录,建议最终将日志发送到集中式日志服务(如rsyslog、syslog-ng、ELK)。

在脚本中使用 logger 命令:

log_audit() {
    local message="[AUDIT] $*"
    logger -p authpriv.info -t admin_script "$message"
}

这样,所有日志会被发送到 /var/log/messages/var/log/secure,并可配置rsyslog转发到远程服务器,即使管理员清除本地日志,也无法销毁远程副本。


总结建议

需求 推荐方案 安全性 实现难度
审计特定脚本操作 脚本内 echo >> /var/log/xxx.log 中低
审计管理员所有命令 增强 history + script
合规性审计(等保/PCI) auditd + rsyslog 远程备份
实时监控与告警 auditd + 日志分析工具(如Wazuh)

核心原则:

  1. 日志必须异地存储(写入远程syslog服务器),否则管理员可以rm -rf销毁证据。
  2. 日志文件权限严格:设为640,属主root,属组adm,禁止普通用户读取。
  3. 日志轮转:使用logrotate定期压缩、归档、删除旧日志,避免写满磁盘。

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