linux权限审计的核心是实时监测系统调用入口处的“身份+能力+策略”三重验证:先校验uid/gid基础权限,再比对capabilities,最后匹配selinux/apparmor策略;任一环节失败即返回-eperm/-eacces并可被audit捕获。

Linux权限审计中监测系统调用时的权限验证逻辑,核心在于看清内核如何在每次系统调用入口处做“身份+能力+策略”三重判断。这不是事后日志回溯,而是实时拦截点上的决策过程。真正有效的审计,必须覆盖这三层验证行为本身。
系统调用入口的权限验证链
当进程执行如 open()、execve() 或 bind() 等操作时,内核并非只看文件权限位(rwx),而是在进入内核后依次完成:
-
UID/GID 基础校验:检查调用者真实用户/组 ID 是否对目标资源有传统 POSIX 权限(例如
stat()返回的 mode 中的 owner/group/other 位); -
Capabilities 细粒度比对:确认进程是否持有对应能力(如
CAP_DAC_OVERRIDE可绕过读写权限检查,CAP_NET_BIND_SERVICE允许绑定 1024 以下端口); -
SELinux 或 AppArmor 上下文匹配:验证进程域(domain)与目标对象类型(type)是否被策略允许交互(例如
httpd_t进程能否write到var_log_t类型的日志文件)。
这三步全部通过,系统调用才继续执行;任一环节拒绝,内核立即返回 -EPERM 或 -EACCES,且该拒绝事件可被 audit 捕获。
用 auditctl 监测权限验证失败行为
单纯记录成功调用意义有限,真正暴露配置风险的是被拒绝的权限请求。可通过以下规则捕获关键拒绝事件:
监控所有因权限不足被拒的文件访问:
sudo auditctl -a always,exit -F arch=b64 -S openat,open,openat64 -F exit=-13 -k perm_denied_file
(exit=-13对应EACCES,即权限拒绝)捕获 capability 不足导致的 exec 失败:
sudo auditctl -a always,exit -F arch=b64 -S execve -F exit=-1 -k cap_denied_exec
(exit=-1常见于 capability 缺失或 seccomp 过滤拦截)记录 SELinux 策略拒绝(需确保
ausearch能解析 avc 日志):sudo auditctl -a always,exit -F msgtype=AVC -F key=avc_denied
这些规则不依赖路径,能发现非标准位置的提权尝试或策略盲区。
验证权限验证逻辑是否生效
审计规则写完不等于机制起作用,需主动触发并验证:
- 手动测试:以普通用户运行
touch /etc/shadow,应被拒绝并生成 audit 日志; - 检查日志是否含
res=0(成功)或res=1(失败)字段,并匹配key标签; - 使用
ausearch -k perm_denied_file --raw | aureport -f -i查看失败详情,确认comm=(命令名)、name=(目标路径)、auid=(原始登录用户)等字段完整; - 若无日志,检查
auditd是否运行、/proc/sys/kernel/audit是否为 1、以及是否存在更高优先级的 seccomp 或 eBPF 过滤器提前截断调用。
生产环境需注意的边界情况
-
CAP_SYS_ADMIN持有者可能绕过多数检查,但其调用仍会被 audit 记录 —— 审计重点应转向“谁获得了该能力”而非“它做了什么”; - 容器内进程受 cgroup + seccomp + capabilities 三重限制,
auditctl规则需部署在宿主机,且arch=b64或b32必须与容器内应用架构一致; -
syscall过滤规则对clone()、fork()等派生调用无效,需配合--pid或auid字段关联父子进程链。
权限验证逻辑本身不会写入磁盘日志,但它的每一次判定结果都会留下痕迹。抓住 exit 状态码、res 字段和上下文标签,就能让内核的“拒绝理由”开口说话。











