当服务器上的关键文件不翼而飞,或者需要满足合规性要求,精准追溯到是谁、在什么时间、通过什么命令删除了文件,传统的日志系统往往无能为力。Linux 内核自带的 Audit 子系统正是解决这类问题的终极武器。它不依赖任何外部日志记录,直接在内核层面拦截系统调用,这意味着只要配置得当,任何用户空间的逃逸手段都无法绕过它的监控。本文将直接聚焦于如何利用 auditd 精准捕获 Ubuntu 系统上的文件删除行为,并给出生产环境可用的实战配置。
理解核心:我们到底在监控什么系统调用文件删除在 Linux 底层并非一个单一动作。使用 rm 命令删除文件,实际上会触发 unlink 系统调用;而删除目录则触发 rmdir。但仅仅监控这两个调用是不够的。当用户使用编辑器覆盖文件,或者应用程序执行重命名操作导致原文件被替换时,文件实际上也被“删除”了,这对应的是 rename 系统调用。一个严密的审计策略必须同时覆盖 unlink、rmdir 和 rename 这三个关键入口。Auditd 的强大之处在于,它不仅能告诉你谁执行了操作,还能记录下被删除文件的完整路径、进程ID、父进程乃至当时的终端环境。
在 Ubuntu 20.04/22.04/24.04 等现代版本中,auditd 通常已预装但未启动。首先确认软件包状态并安装必要组件:
sudo apt update && sudo apt install auditd audispd-plugins -y
安装完成后,立即检查服务状态。这里有一个容易被忽略的坑:auditd 服务默认可能被 mask 或处于 inactive 状态,必须确保它被启用并设置为开机自启:
sudo systemctl unmask auditd sudo systemctl enable auditd sudo systemctl start auditd sudo systemctl status auditd
验证内核审计模块已加载,这是 auditd 正常工作的前提:
sudo auditctl -s
如果输出显示 enabled 1 且没有报错,说明内核级审计已就绪。如果遇到内核不支持的情况,需要检查 /boot/config-$(uname -r) 中 CONFIG_AUDIT=y 是否生效。
直接使用 auditctl 添加的规则是临时的,重启即失效。生产环境必须将规则写入 /etc/audit/rules.d/ 目录下的规则文件中。创建一个专门用于监控文件删除的规则文件:
sudo vim /etc/audit/rules.d/audit-delete.rules
文件内容如下,每条规则都有其明确的战术目的:
# 1. 监控所有用户的文件删除操作(unlink系统调用) # -S unlink 指定系统调用,-k 设置过滤关键词方便后续搜索 -a always,exit -F arch=b64 -S unlink -S unlinkat -k delete-file -a always,exit -F arch=b32 -S unlink -S unlinkat -k delete-file # 2. 监控目录删除操作 -a always,exit -F arch=b64 -S rmdir -k delete-dir -a always,exit -F arch=b32 -S rmdir -k delete-dir # 3. 监控重命名操作(覆盖文件也算删除) -a always,exit -F arch=b64 -S rename -S renameat -k rename-file -a always,exit -F arch=b32 -S rename -S renameat -k rename-file # 4. 针对特定关键目录的精细化监控(例如监控 /etc 和 /var/log 下的删除) # 这种方式比全局监控更高效,能大幅减少日志量 -w /etc/ -p wa -k etc-modify-delete -w /var/log/ -p wa -k log-modify-delete
这里有三个关键点需要理解。第一,必须同时添加 b64 和 b32 架构的规则,因为 64 位系统上依然可能运行 32 位程序,遗漏 32 位规则会造成审计盲区。第二,unlinkat 和 renameat 是相对路径操作时使用的系统调用变体,现代应用程序大量使用它们,忽略会导致漏报。第三,-w 方式基于文件系统路径监控,比系统调用监控更轻量,适合保护已知的关键目录,但它无法监控通过绑定挂载等特殊方式进行的操作,因此系统调用监控依然是兜底手段。
规则文件编写完成后,需要重启 auditd 服务使其加载。直接使用 augenrules 工具可以将 rules.d 下的所有规则合并并加载:
sudo augenrules --load sudo systemctl restart auditd
验证规则是否真正生效,使用以下命令列出当前内核中的审计规则:
sudo auditctl -l
你应该能看到刚才添加的所有系统调用规则和文件监控规则。如果列表为空,说明规则加载失败,需要检查 /var/log/audit/audit.log 中是否有语法错误提示。常见错误包括系统调用名称拼写错误、架构标识遗漏等。
现在进行真实测试。创建一个测试文件并删除它:
echo "audit test content" > /tmp/test_audit_file.txt rm /tmp/test_audit_file.txt
立即使用 ausearch 工具检索刚才的删除事件。这里的关键词 delete-file 就是我们在规则中定义的 key:
sudo ausearch -k delete-file -i
输出会非常详细,我们需要关注的核心字段包括:uid(执行操作的用户ID)、auid(登录时的原始用户ID,即使通过 sudo 提权也能追溯到原始登录者)、exe(执行删除操作的程序路径,例如 /usr/bin/rm)、name(被删除的文件名)、cwd(执行命令时的工作目录)、syscall(具体系统调用号)以及精确到毫秒的时间戳。如果输出信息量过大,可以用 --format text 参数获得更易读的格式,或者配合 --interpret 自动将 UID 翻译为用户名。
在繁忙的服务器上,即使只监控删除操作,日志量也可能很大。掌握 ausearch 的高级过滤语法是效率的关键。要查找特定用户在特定时间段内删除的所有文件:
# 查找用户 john 在今天中午12点到13点之间的所有删除操作 sudo ausearch -k delete-file -ui john -ts 12:00:00 -te 13:00:00 -i
要定位某个特定文件是被谁删除的,即使只知道部分文件名:
# 查找文件名中包含 secret 的删除事件 sudo ausearch -k delete-file -f secret -i
对于需要生成合规报告的团队,aureport 工具可以生成汇总视图。例如生成一个文件删除事件的统计报告:
sudo aureport -f -i --summary
这个报告会列出每个被删除文件的路径、操作次数和涉及的用户,非常适合提交给审计部门或进行安全事件复盘。
应对日志膨胀:配置合理的轮转策略审计日志默认写入 /var/log/audit/audit.log,在高负载系统上可能迅速填满磁盘。Ubuntu 使用 audisp-remote 或本地轮转来控制日志大小。修改 /etc/audit/auditd.conf 中的关键参数:
max_log_file = 100 # 单个日志文件最大100MB max_log_file_action = ROTATE # 达到上限后轮转而非暂停审计 num_logs = 10 # 保留10个历史日志文件 space_left_action = email # 磁盘空间不足时发送邮件告警 action_mail_acct = admin@example.com
更进一步的方案是将审计日志实时转发到集中的日志平台,但这属于扩展架构范畴。对于单机场景,务必确保 max_log_file_action 设置为 ROTATE,默认的 SUSPEND 会导致磁盘满后审计系统停止工作,造成监控盲区,这是一个生产事故隐患。
一个高级攻击者在删除文件后,很可能会尝试清除审计规则或停止 auditd 服务。虽然完全阻止 root 用户修改审计配置几乎不可能,但我们可以通过设置不可变规则来增加攻击难度。在规则文件的最后添加:
-e 2
-e 2 表示将审计规则设置为不可变模式,此后直到系统重启,任何对审计规则的修改都会被内核拒绝,包括 root 用户。重启 auditd 服务也无法清除规则,只有物理重启机器才能解除。这是一种强力的防篡改措施,适用于高安全等级环境。需要注意的是,在启用 -e 2 之前,务必确认所有规则都正确无误,否则只能重启机器来修正错误。
实际部署中经常遇到规则添加后无日志输出的问题。排查步骤应该是:首先确认 auditctl -l 能看到规则,如果看不到,检查 /var/log/audit/audit.log 中是否有规则解析错误。其次,确认系统调用名称是否正确,unlinkat 容易误写为 unlink_at。再次,检查是否有更早加载的规则表覆盖了你的规则,某些安全软件会预先插入大量审计规则。最后,确认被监控的操作确实触发了对应的系统调用,可以用 strace rm testfile 来观察实际调用的系统调用,确保与规则匹配。
单纯的审计日志价值有限,真正的威力在于联动。可以将 auditd 日志通过 syslog 插件转发到 SIEM 系统,设置实时告警规则。例如,当检测到 /etc/shadow 或 /var/lib/mysql 下的文件被删除时,立即触发安全事件响应流程。auditd 记录的 ses(会话ID)和 pid(进程ID)可以关联到登录日志和进程链,还原完整的攻击路径。这种基于内核级证据链的追溯能力,是任何用户态日志工具都无法提供的。
