最可靠的方式是利用内核级 auditd 捕获 execve 系统调用,因其覆盖所有命令执行场景、抗绕过且不依赖用户环境;需配置 arch=b64/b32 规则并持久化至 /etc/audit/rules.d/,配合 ausearch/aureport 解析日志,并强化日志防篡改与远程备份。

最可靠的方式是利用内核级审计子系统 auditd 捕获 execve 系统调用,因为所有命令执行(无论是否经由 shell)最终都经过该调用。它不依赖用户环境、不被 unset HISTFILE 或非交互式场景绕过,能覆盖 su、sudo、cron、脚本内调用等全部场景。
配置 auditd 记录 execve 调用
auditd 是 Linux 内置的审计框架,直接监听系统调用,具备完整性和抗绕过能力。
- 对 x86_64 系统,添加规则:
sudo auditctl -a always,exit -F arch=b64 -S execve - 兼容 32 位程序(如部分容器进程),额外加:
sudo auditctl -a always,exit -F arch=b32 -S execve - 规则必须写入
/etc/audit/rules.d/execve.rules(文件名以.rules结尾)才能持久生效,否则重启后丢失 - 避免在规则中做用户过滤(如
-F uid!=0),应在查询时过滤,防止规则加载失败导致漏记
精准查询某用户或会话的操作记录
原始日志 /var/log/audit/audit.log 无结构、难读,必须用 ausearch + aureport 组合解析。
- 查用户
john所有命令:sudo ausearch -u john -m execve --raw | aureport -f -i - 查某次登录会话(如 session ID 为 12345):
sudo ausearch -m event --session 12345(session ID 可从last或 loginuid 字段获取) - 查含敏感关键词(如
passwd)的命令:sudo ausearch -m execve | grep -i passwd(注意这是文本层过滤,非审计层) - 推荐始终使用
-m execve而非-sc EXECVE,后者在部分 auditd 版本中不稳定
为什么不能只靠 /etc/profile + history?
这类方案看似简单,但在生产环境中存在根本性盲区,无法满足审计要求。
-
su或sudo -i后的新 shell 不会写入原用户 history 文件 - ssh 直接执行命令(如
ssh user@host 'ls')、cron job 等非交互式 shell 完全不加载/etc/profile - 攻击者可通过
unset HISTFILE、exec /bin/ls或直接调用二进制绕过所有 history 控制 - 多终端并行时,history 时间戳混乱,且无法关联到具体 tty 或登录会话 ID
补充建议:日志管理与加固
审计有效性的关键不仅在于记录,更在于防篡改和可持续性。
- 将
/var/log/audit/audit.log设置为 append-only:chattr +a /var/log/audit/audit.log - 配置 rsyslog 或 journald 将审计日志转发至远程 SIEM 系统,避免本地删除风险
- 启用
logrotate对审计日志定期归档压缩,并设置保留周期 - 限制普通用户对
/var/log/audit目录的读取权限,仅授权审计管理员访问

















