暗色模式

Linux 安全审计:从 auditd 规则监控到 ausearch 操作溯源

技术教程
2026-09-03
8
0
本文要点
  • auditd 是 Linux 内核层的审计框架:它在系统调用这一层记录文件被谁打开、修改、删除,入侵者清掉 shell history 也抹不掉审计日志
  • auditctl -w 路径 -p 权限 -k 键名 监控文件读写与属性变化,-a always,exit -F arch=b64 -S execve -k 键名 记录每一次程序执行
  • 规则都要起一个 键名(key),查询时 ausearch -k 键名 按主题取数——实测日志里十几秒就能攒下几十条事件,没有键名就像大海捞针
  • 演示还原了"入侵者加后门账号"现场:useradd/etc/passwd 的写打开与原子替换(openat + rename)被完整记录,时间精确到秒
  • ausearch 支持按键名、程序名(-c)、用户等维度组合过滤;aureport 生成按时间/用户/键名的汇总报表
  • 全部命令在 Ubuntu 24.04(auditd 3.1.2、内核 6.8)上真实执行,截图即真实输出

Linux 安全审计:服务器上的"行车记录仪"

假设你的服务器被入侵了:攻击者添加了一个后门账号,改了几处配置,然后溜之大吉。事后你打开服务器排查——history 被清空了,应用日志被改过了,你甚至不知道对方是什么时候进来的、动了哪些文件。除非你提前装了一套 auditd

auditd(Linux Audit 子系统)是内核层面的审计框架:不依赖 shell history,不依赖应用自己写日志,而是在系统调用这一层做记录。任何进程——包括 root——要打开、修改、删除一个文件,都必须经过内核的系统调用,而 auditd 就守在这里。只要规则配置得当,/etc/passwd 被谁用哪个程序改过、/etc/shadow 被谁读过、服务器上执行过哪些命令,全部有据可查,且普通进程根本无法察觉或绕过(shell history 可以清,审计日志是内核记的)。

本文在一台 Ubuntu 24.04 服务器(内核 6.8、auditd 3.1.2)上完整演示:装好 auditd → 配置三类规则 → 用两个"入侵小剧场"还原攻击行为 → 用 ausearch 把肇事者揪出来。

安装 auditd 与确认内核审计状态

Ubuntu 上安装 auditd 后,守护进程和命令行工具一次到位:

apt install -y auditd
systemctl enable --now auditd

auditctl -s 查看内核审计开关的状态:

auditctl -s 查看审计状态

逐行解读:enabled 1 表示内核审计已开启;backlog_limit 8192 是事件队列上限,事件太多来不及写盘时先在这里排队;lost 0backlog 0 表示没有事件丢失、队列没有积压——这是健康的运行状态;failure 是累积的失败计数,只有当它持续增长时才需要警觉。

auditd 把事件写进 /var/log/audit/audit.log。这个文件默认按大小轮转(/etc/audit/auditd.conf 里配置),不会无限膨胀。

配置三类审计规则

审计规则分三类:文件监控规则(watch)系统调用规则(syscall)可执行文件规则。日常用得最多的是前两类,用 auditctl 添加。先看本文演示环境的三条规则:

auditctl -l 列出已加载规则

对应的添加命令(截图是 auditctl -l 的查询结果,这 3 条规则是预先用下面的命令加好的):

auditctl -w /etc/passwd -p wa -k identity
auditctl -w /etc/shadow -p r -k shadow_read
auditctl -a always,exit -F arch=b64 -S execve -k cmdexec

逐条拆解:

  • auditctl -w /etc/passwd -p wa -k identity:监控 /etc/passwdw(写入)和 a(属性变化)操作,事件打上 identity 键。修改用户账号必然动这个文件,专门盯它。
  • auditctl -w /etc/shadow -p r -k shadow_read:监控 /etc/shadowr(读取)——注意读取也要审计。文件监控权限位一共四个:r(读)、w(写)、x(执行)、a(属性)。
  • auditctl -a always,exit -F arch=b64 -S execve -k cmdexec:系统调用规则,记录每一次 execve(执行程序)系统调用。arch=b64 限定 64 位系统调用入口(否则 32 位程序会重复记录),always,exit 表示每次调用退出时都记录。

细心的读者会发现截图里第三条规则显示成了 -F key=cmdexec,而不是添加时的 -k cmdexec——这是 auditctl -l 回显规则的内部表示形式,-k 只是 -F key= 的简写。知道这一点,写脚本解析规则输出时才不会懵。

入侵剧场一:后门账号动了 /etc/passwd

攻击者最经典的动作之一是添加后门账号——这样下次就能直接登录。这里用 useradd 模拟:

useradd -M audituser01

然后作为管理员,用 ausearch 查询 identity 键下、由 useradd 程序触发的事件:

ausearch -k identity -c useradd --format text

ausearch 查询 useradd 对 passwd 的写操作

仅仅一个 useradd,审计日志就留下了两条关键证据(同一秒 05:15:09):

  1. root successfully opened-file /etc/passwd using /usr/sbin/useradd——useradd 以写方式打开了 /etc/passwd
  2. root successfully renamed /etc/passwd+ to /etc/passwd using /usr/sbin/useradd——useradd 把临时文件 /etc/passwd+ 重命名覆盖了 /etc/passwd

这正是现代账号管理工具写系统文件的原子替换模式:先写一个 passwd+ 临时副本,改好后一次性 rename 覆盖原文件,避免中途崩溃留下半截文件。审计日志把这两步都记了下来——时间、进程、操作对象、成功与否,一应俱全。--format text 把原始事件翻译成人话(successfully opened-file 对应 openat 系统调用成功),直接可读;想看原始格式去掉它即可。

查询里的 -c useradd 是"只看 useradd 这个程序触发的事件"。如果机器上经常有人正常改账号,这个过滤能立刻把噪音排除掉。想知道精确时间ausearch -ts 05:15:00 -te 05:15:10 可以按时间窗过滤(-ts/-te 支持 todaymm/dd/yyyy hh:mm:ss 等格式)。

入侵剧场二:谁伸向 /etc/shadow

/etc/shadow 存着密码哈希,是审计的重中之重——监控它的读取往往能发现攻击者在"数哈希":wc -l /etc/shadow 可以数出系统里有几个账号(有多少个密码可尝试破解)。演示里就用这一招:

wc -l /etc/shadow

然后查询 shadow_read 键下都发生了哪些读取:

ausearch -k shadow_read --format text

ausearch 查询 shadow 读取事件

三条记录还原了完整时间线:

  • 05:15:07 add_ruleauditctl 添加 shadow_read 规则的动作本身也被审计了(规则一生效,此后一切相关动作都在记录中);
  • 05:15:09 useradd opened-file /etc/shadow:上一个小剧场里 useradd 添加账号时也会读取 shadow(它需要核对用户名是否已存在),属于正常业务;
  • 05:15:13 wc opened-file /etc/shadowwc 这个普通文本计数工具去读密码哈希文件,本身就是危险信号——正常运维没有任何理由让 wc 碰 shadow。

三条记录同样发生在几秒内,时间、程序一目了然。这就是审计的威力:不靠猜,靠证据链。

如果只想揪出 wc 这一次可疑读取,加上 -c wc 按程序名过滤:

ausearch -k shadow_read -c wc --format text

ausearch 组合过滤锁定 wc 的读取

ausearch 的常用过滤维度整理如下:

过滤目标参数示例
按规则键-kausearch -k shadow_read
按程序名-causearch -c wc
按可执行文件路径-xausearch -x /usr/bin/wc
按用户 ID-uaausearch -ua 1000
按时间窗-ts / -teausearch -ts 05:15:00 -te 05:15:10
只看成功/失败-sv yes / -sv noausearch -sv no

命令执行审计:钉死"每一条命令"

第三条规则 execve 记录每一次程序执行,攻击者敲的每条命令都会留下痕迹。但它的代价也很实在:在演示这台机器上,仅仅十几秒的交互操作,cmdexec 键下就攒下了几十条事件(lsdategrep 这些命令本身也在记录之列)。日志增长很快、查询噪音大,所以:

  • 能定向监控文件就用文件规则,execve 全量规则适合"这台机器就是要全量留痕"的合规场景;
  • 无论哪种,键名(key)是审计规则的第一等公民——没有键名,事后只能用时间盲查,有了键名,ausearch -k 一条命令精确取数。

想快速看报表而不是逐条翻,用 aureport

aureport -k        # 按规则键汇总事件数
aureport -u        # 按用户汇总
aureport -x        # 按可执行文件汇总

aureport -k 会输出每类键名(identity / shadow_read / cmdexec)下的事件清单,是巡检时的第一站。

规则的清理与持久化

演示用的规则都是 auditctl 直接加载到内核的运行时规则,重启后失效。清理它们:

auditctl -D    # 删除全部运行时规则

生产环境要长期生效,把规则写进 /etc/audit/rules.d/(比如新建 security.rules),格式与 auditctl 参数一致、一行一条。系统重启时 auditd 会通过 augenrules 把该目录下的规则文件合并加载。注意:auditctl 改的是内存中的规则,rules.d/ 里的文件才是持久配置,两者别搞混。

两个影响查询准确性的配置项也值得知道(都在 /etc/audit/auditd.conf,改后 systemctl restart auditd 生效):

log_format = RAW      # 默认 ENRICHED 会在事件里附带命令上下文,RAW 更纯净
flush = SYNC          # 事件即时落盘,避免查询滞后于事件(本文演示环境采用)

审计的边界:它能做什么,不能做什么

  • 不能阻止攻击:auditd 只记录不拦截。想"挡"请配合文件权限、SELinux/AppArmor(本站有 AppArmor 强制访问控制 的专题)。
  • root 可以破坏现场:root 能 auditctl -D 清规则、删审计日志。所以生产环境要把审计日志实时转发到远程集中存储(auditd 支持 remote logging),让日志与服务器分离——这是合规审计的基本要求。
  • 规则越多代价越大execve 全量规则下日志增长明显,规则要按"监控什么风险"来设计,而不是什么都记。

总结

一个实用的审计基线可以这样起步:/etc/passwd/etc/shadow/etc/sudoers 等关键文件用 -w 规则监控(写 + 读分别设计),关键服务目录加写监控,再配合一条 execve 规则记录命令执行;事后用 ausearch -k 按键取数、aureport -k 出报表。入侵者可以清空 shell history,却清不掉内核审计日志里那个"05:15:13,wc 读了一次 /etc/shadow"。

进一步阅读:auditd(8) 手册页auditctl(8) 手册页ausearch(8) 手册页

发表评论

暂无评论,快来抢沙发吧!