应使用 -F auid=1000 而非 -F uid=1000 监控指定用户,因 auid 从首次登录起固定不变,可覆盖 su/sudo/子进程等场景;需配合 -F arch=b64(及 b32)和系统调用过滤,避免用 -w 混合 UID 条件。

auditctl 怎么监控指定 UID 的所有文件访问行为
直接用 -F uid=1000 无法捕获该用户的所有文件操作——因为很多操作(如 su、sudo -i、脚本内子进程)会切换实际 UID(uid),但保留原始登录 UID(auid)。真正稳定标识“谁发起这次登录会话”的是 auid 字段,它从用户首次登录起就固定,不可被子进程篡改。
所以监控特定用户,必须用 -F auid=1000,而不是 -F uid=1000。否则你会漏掉 90% 以上的操作,尤其是提权后的行为。
-
auditctl -a always,exit -F arch=b64 -F auid=1000 -S openat -S open -S creat -S unlink -S unlinkat -k user_1000_file_ops:覆盖常见文件打开、创建、删除动作(x86_64 系统必须加-F arch=b64) - 若需兼容 32 位程序(如某些容器内进程),额外加一条:
auditctl -a always,exit -F arch=b32 -F auid=1000 -S open -S unlink -k user_1000_file_ops_32 - 不要加
-F success=1过滤成功操作——失败的 open(如权限拒绝)同样重要,可能暴露暴力探测或配置错误 - 避免对高频路径(如
/proc、/sys、/tmp)盲目加-w,会导致日志爆炸;-a ... -S方式按系统调用过滤更可控
为什么不能用 -w 目录 + -F uid 匹配用户行为
-w 规则只支持路径和权限(-p),不支持 uid 或 auid 过滤。你写 auditctl -w /home/john -p rwxa -F auid=1000 会直接报错:Invalid option: -F。这是语法硬限制,不是配置问题。
想实现“某用户访问某目录”的组合条件,只能退回到系统调用级规则,并在日志分析阶段用 ausearch 关联:ausearch -auid 1000 -f /home/john。运行时规则本身做不到路径 + UID 双条件实时匹配。
-
-w适合监控固定敏感路径(如/etc/passwd),不管谁动 -
-a always,exit -F auid=... -S ...适合追踪特定用户的所有动作,不管在哪发生 - 两者定位不同:一个是“事出地点导向”,一个是“人导向”
如何验证 auid 规则是否生效且没漏事件
别只靠 auditctl -l 看规则是否存在——它只确认加载成功,不验证逻辑覆盖。真实漏记往往发生在架构不匹配或字段误用时。
- 先确认目标用户的
auid值:loginuid=$(awk '/^john:/ {print $3}' /etc/passwd); echo $loginuid(注意:普通用户默认auid是其 UID,但需实测确认) - 手动触发测试行为:
touch /tmp/testfile; rm /tmp/testfile - 立即查日志:
sudo ausearch -auid $loginuid -m open -m unlink --raw | aureport -f -i,看是否出现对应记录 - 如果无输出,检查是否漏了
-F arch=b64(x86_64 系统下缺失该参数,规则完全不触发) - 注意:
ausearch -u john查的是当前uid,不是auid,容易误导;必须显式用-auid
永久化规则时要注意的两个坑
临时规则用 auditctl 加完就跑,但生产环境必须固化。这里有两个极易踩的点:
- 规则文件名必须以
.rules结尾,且只能含字母、数字、下划线、短横线,例如/etc/audit/rules.d/user-1000.rules—— 写成user1000或user1000.conf,augenrules会直接跳过 - 加载命令必须是
sudo augenrules --load,不是systemctl restart auditd。后者只重读/etc/audit/audit.rules,而忽略rules.d/下所有片段 - 加载后务必执行
sudo auditctl -l | grep user_1000,确认规则已出现在内存中;否则说明augenrules编译失败(常见于语法错误或重复-k标签) - 别在规则里写
-F uid!=0之类排除 root 的条件——它可能导致整条规则加载失败,反而让所有用户操作都漏记;过滤应留在ausearch阶段
真正难的不是写对一条规则,而是理解 auid 和 uid 的生命周期差异,以及 augenrules 对文件名和加载流程的隐式约定。这两个点一旦出错,审计就形同虚设,你还以为它在默默工作。











