本文目录导读:

在Shell脚本中审计管理员操作日志,通常有两种主要场景:
- 审计通过Shell脚本执行的操作(脚本内部记录)
- 审计管理员在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 HISTORY或history -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) | 高 | 高 |
核心原则:
- 日志必须异地存储(写入远程syslog服务器),否则管理员可以
rm -rf销毁证据。 - 日志文件权限严格:设为
640,属主root,属组adm,禁止普通用户读取。 - 日志轮转:使用
logrotate定期压缩、归档、删除旧日志,避免写满磁盘。