4. 常见审计事件类型:AVC拒绝、USER_CMD、LOGIN、SYSCALL、PATH、CWD事件的含义与关联
SELinux 审计日志并非单一事件流,而是由多种事件类型共同编织的上下文网络。本章聚焦六种最核心的审计事件类型,在问题排查六步框架中逐一拆解其含义、日志特征及关联分析路径。
4.1 现象识别
当 SELinux 拒绝发生时,audit.log 中不会只有一条孤立的 AVC 记录,而是同时出现一组关联事件。识别这六种事件类型的日志特征,是排查的第一步。
六种事件类型速查表
| 事件类型 | 日志关键字 | 核心信息 | 排查价值 |
|---|---|---|---|
| AVC | type=AVC | 源/目标上下文、权限、决策 | 记录拒绝的“是什么”与“为什么” |
| USER_CMD | type=USER_CMD | 执行命令、用户、PID | 确定触发拒绝的“谁”与“哪个命令” |
| LOGIN | type=LOGIN | 登录 ID、UID、会话 | 关联拒绝发生的“登录会话” |
| SYSCALL | type=SYSCALL | 系统调用号、参数、返回值 | 还原拒绝发生的“系统调用层细节” |
| PATH | type=PATH | 文件名、inode、设备号 | 指明被拒绝访问的“具体文件路径” |
| CWD | type=CWD | 当前工作目录路径 | 标明拒绝发生时进程的“工作目录” |
4.1.1 典型日志示例
以下是一组关联的审计记录,展示 AVC 拒绝与上下文事件同时出现的真实场景:
type=AVC msg=audit(1698123456.789:1234): avc: denied { read } for pid=5678
comm="httpd" name="config.php" dev=dm-0 ino=998877
scontext=system_u:system_r:httpd_t:s0
tcontext=unconfined_u:object_r:var_t:s0 tclass=file
type=SYSCALL msg=audit(1698123456.789:1234): arch=c000003e syscall=open
success=no exit=-13 a0=7ffe12345678 a1=0 a2=1 a3=0 items=1
pid=5678 loginuid=1001 uid=48 auid=1001 ses=2
comm="httpd" exe="/usr/sbin/httpd"
type=PATH msg=audit(1698123456.789:1234): item=0 name="/var/www/html/config.php"
inode=998877 dev=08:01 mode=0100644 ouid=0 ogid=0 rdev=00:00
obj=unconfined_u:object_r:var_t:s0
type=CWD msg=audit(1698123456.789:1234): cwd="/var/www/html"
type=USER_CMD msg=audit(1698123456.789:1234): pid=5678 uid=48
cmd="/usr/sbin/httpd -k start" terminal=ssh res=success
type=LOGIN msg=audit(1698123456.789:1234): login-id=1001
ses=2 subj=system_u:system_r:httpd_t:s0
识别要点:所有关联事件共享同一个
msg=audit(时间戳:序列号) 中的序列号(如 1234),这是多事件关联的“连接键”。在日志中看到同一序列号跨越多行时,应将其作为一组完整上下文整体分析。
4.2 数据采集
使用 ausearch 按事件类型和关联键精准采集,避免人工翻阅大量无关日志。
4.2.1 按事件类型筛选
# 采集所有 AVC 拒绝事件
ausearch --type AVC
# 采集指定时间范围内的 SYSCALL 事件
ausearch --type SYSCALL --start 09:00:00 --end 09:30:00
# 同时采集 AVC 和 PATH 事件
ausearch --type AVC --type PATH
4.2.2 按序列号关联采集
# 先找到目标 AVC 的序列号(假设为 1234)
ausearch --type AVC --message 1234
# 用同一序列号采集所有关联事件
ausearch --message 1234 --raw | aureport --file --summary
采集判断规则:
- 若 AVC 拒绝 无 同序列号的 SYSCALL → 可能为内核策略拒绝,需检查
dmesg。 - 若 AVC 拒绝 有 SYSCALL 但 无 PATH → 拒象可能为 socket、IPC 或抽象资源。
- 若缺少 USER_CMD → 使用
ausearch --pid $PID --type USER_CMD按 PID 补充采集。
4.3 原因定位
定位阶段的核心任务:利用事件间的关联关系,将一条抽象的 AVC 拒绝还原为可理解的操作场景。
4.3.1 故障树:AVC 拒绝根因定位
┌─ 上下文类型不匹配?
│ → 检查 PATH.obj 与 SYSCALL.comm 的 Domain
┌─ 策略缺失 ──┼─ 类别/权限缺失?
│ │ → 检查 avc: denied { 权限 } 中的权限名
│ └─ 布尔值关闭?
│ → semanage boolean -l | grep httpd
│
AVC 拒绝 ─┼─ 标签错误 ── 文件上下文标签与策略预期不一致
│ → matchpathcon $PATH
│
├─ 违规访问 ── 进程 Domain 无权访问目标类型
│ → 审查策略是否允许该 Domain 访问 tclass
│
└─ 日志截断 ── 缺少 SYSCALL/PATH 等关联记录
→ 检查 auditd 缓冲区是否溢出
4.3.2 关联定位排查表
| AVC 拒绝特征 | 关联事件线索 | 典型根因 |
|---|---|---|
denied { write } 到 var_t | PATH 显示 /var/www/html,CWD 同路径 | httpd 无权写入默认文档目录 |
denied { connectto } | SYSCALL 为 connect,无 PATH | Socket 连接被策略阻断 |
denied { execute } | PATH 为 /tmp/*,USER_CMD 为脚本 | 临时目录执行被禁止 |
| 高频重复 AVC | LOGIN 显示同一 ses,USER_CMD 为 cron 作业 | 周期性任务触发策略违规 |
4.3.3 定位决策规则
1. 提取 AVC 中的 scontext 与 tcontext
2. 在 PATH 中找到被访问文件的 obj 标签
3. 若 obj 标签 ≠ tcontext → 文件标签异常,优先修复标签
4. 若 obj 标签 == tcontext → 检查策略中是否允许 scontext Domain 对 tclass 执行 权限
5. 通过 USER_CMD 判断是否为预期行为:
- 预期行为 → 添加策略允许
- 非预期行为 → 检查进程是否被入侵或错误配置
常见误区:仅凭 AVC 拒绝中的
scontext 和 tcontext 就下结论,忽略 CWD 和 USER_CMD 会导致误判。例如,httpd 访问 /var/www/html 被拒,若 CWD 显示为 /root,说明进程工作目录异常,可能是配置错误而非策略缺失。
4.4 修复动作
根据定位结果选择对应的修复策略,修复动作必须与事件关联分析结论一致。
| 根因类别 | 修复动作 | 验证命令 |
|---|---|---|
| 策略缺失(预期行为) | 使用 audit2allow 生成自定义策略模块 | ausearch --type AVC --raw | audit2allow -M mymodule |
| 文件标签错误 | 使用 semanage fcontext 或 restorecon 修正 | restorecon -v /var/www/html/config.php |
| 布尔值关闭 | 使用 setsebool 启用对应布尔值 | setsebool -P httpd_enable_homedirs on |
| 非预期违规 | 排查进程异常,修复应用配置,无需加策略 | ps aux | grep httpd 确认进程上下文 |
修复前快照:执行修复前,使用
aureport --type AVC --start $(date +%H:%M) --end $(date +%H:%M) --summary 记录当前拒绝频率,作为修复效果的基准线。
4.5 复测
修复后必须通过端到端的场景复测,确保 AVC 拒绝消失且业务功能正常。
4.5.1 复测步骤
- 触发同一操作:根据 USER_CMD 中记录的命令重新执行(如
curl http://localhost/config.php)。 - 实时监控拒绝:
# 实时跟踪 AVC 拒绝(持续 10 秒)
ausearch --type AVC --start recent --end now --raw | tail -f &
sleep 10
kill %1
- 检查关联事件是否同步消失:
# 查找最近 1 分钟内的 AVC 记录
ausearch --type AVC --start $(date -d '-1 min' +%H:%M) --end now
- 验证业务功能:确认应用无异常报错,日志中无新的
denied出现。
复测通过标准:
- audit.log 中无新增与本次修复相关的 AVC 拒绝。
- SYSCALL 的返回值从
-13 (EACCES)变为0或成功码。 - USER_CMD 对应的业务操作可正常完成。
4.6 预防
基于本章六种事件类型的关联分析经验,建立长效预防机制。
| 预防措施 | 实施方法 | 关联事件类型 |
|---|---|---|
| 基线采集 | 每周运行 aureport --type AVC --summary 记录拒绝基线 | AVC |
| 异常告警 | 监控同一序列号下 AVC + SYSCALL 失败组合,超过阈值时告警 | AVC + SYSCALL |
| 变更关联 | 部署新应用时,提前采集 PATH 与 CWD 预先制定策略 | PATH + CWD |
| 会话审计 | 定期检查 LOGIN + USER_CMD 异常命令组合 | LOGIN + USER_CMD |
| 策略版本管理 | 使用 audit2allow 生成模块并用 git 管理 | 所有类型 |
日常巡检命令组合:
# 每日 crontab 巡检脚本片段
#!/bin/bash
# 统计今日 AVC 拒绝总数
today_avc=$(ausearch --type AVC --start $(date +%H:%M) --end $(date -d '+1 min' +%H:%M) --raw | wc -l)
# 若有拒绝,输出 TOP10 源上下文
[ "$today_avc" -gt 0 ] && ausearch --type AVC --raw | aureport --source --summary | head -10
通过将六种事件类型的关联分析能力固化到日常巡检和变更流程中,团队可以从被动响应逐步转向主动防御,大幅缩短 SELinux 问题的平均修复时间(MTTR)。