第3章:avc日志采集与过滤方法——auditd配置、ausearch命令、grep与时间窗口截取

帧率抖动若与SELinux拒绝策略相关,avc日志是唯一能直接揭示“谁被拒绝、因何拒绝、被拒绝了几次”的源头数据。本章按排查流程,从“如何确保auditd正确记录avc”到“如何从海量日志中精确截取抖动时间窗内的avc记录”逐步展开。

3.1 现象识别:何时需要采集avc日志?

当帧率抖动出现时,先观察是否伴随以下现象之一:

  • 抖动时刻系统日志(dmesg / journalctl)中出现大量 avc: denied 条目
  • perf 或 ftrace 显示进程频繁进入内核安全钩子函数
  • 应用启动/资源访问时出现短暂的“权限不足”类错误

若符合任意一条,则采集avc日志是定位根因的关键入口。

排查线索:抖动通常出现在进程首次访问某受限资源(如GPU内存、共享文件、网络socket)的瞬间,avc日志中的时间戳与帧率掉帧点高度重合。

3.2 数据采集:auditd配置与avc日志激活

默认情况下auditd可能未记录所有avc事件。需要显式启用对SELinux AVC的监控,并调整缓冲区大小防丢消息。

3.2.1 auditd.conf关键参数

参数 推荐值 作用
log_file /var/log/audit/audit.log 日志存放路径,确保磁盘空间足够
max_log_file 100 单个日志文件最大MB,建议≥100
num_logs 5 保留的轮转文件数,用于历史对比
priority_boost 4 提高auditd优先级,减少采集延迟
freq 50 每秒刷盘次数,太高增加IO,太低可能丢消息
注意: 若系统使用rsyslog转发audit日志,需确保 imuxsock 模块已加载且未过滤avc事件。否则日志会被无声丢弃。

3.2.2 启动并验证auditd

# 启动服务
sudo systemctl start auditd
# 确保开机自启
sudo systemctl enable auditd
# 检查运行状态
sudo auditctl -s | grep enabled
# 输出应为 enabled 1

3.2.3 设置avc捕获规则(可选)

默认规则已捕获所有avc,但若需限制只记录指定类型(如 file, capability),可使用 auditctl 添加规则:

# 仅记录文件相关的avc拒绝
sudo auditctl -a exclude,always -F avc,denied -F success=0 -F subj_type=unconfined_t
# 查看当前规则
sudo auditctl -l

3.3 数据过滤:ausearch命令与grep时间窗口截取

audit.log 文件通常巨大,直接 grep 全量搜索效率极低。推荐组合使用 ausearch(按字段检索)与 grep(时间窗口截取)。

3.3.1 ausearch常用选项

选项 示例 说明
-m avc ausearch -m avc 仅显示avc类型的记录
-ts -ts 14:30:00 起始时间(24小时制)
-te -te 14:31:00 结束时间
-ui -ui 1000 按用户UID过滤
-p -p 1234 按进程PID过滤
-f -f /path/to/file 按文件路径过滤
-i ausearch -i -m avc 解释数字ID为用户/组名(推荐)

3.3.2 精准截取抖动时间窗口

假设帧率抖动发生在14:30:15~14:30:25之间,使用以下命令提取该窗口内的avc记录:

ausearch -m avc -ts 14:30:15 -te 14:30:25 -i > avc_drop_window.log
# 或结合grep做二次过滤
ausearch -m avc -ts 14:30:15 -te 14:30:25 -i | grep -E "(denied|permitted)" > avc_filtered.log
性能技巧: 若抖动窗口较长(如数秒),先用 ausearch -ts 和 -te 缩小范围,再用 grep 按关键词精滤。避免单用 grep 全量扫描大日志。

3.3.3 时间戳对齐与跨天处理

audit日志时间戳为Unix纪元秒。若跨天,需使用完整格式:

# 获取2025-03-20 14:30:00的epoch
date -d "2025-03-20 14:30:00" +%s
# 输出 1742544600
ausearch -m avc -ts 1742544600 -te 1742544620 -i

3.4 原因定位:从过滤结果中快速锁定冲突规则

过滤后的avc日志每条包含以下关键字段:

type=AVC msg=audit(1742544615.123:456): avc:  denied  { open } for  pid=3567 comm="video_encoder" path="/dev/dri/renderD128" dev="devtmpfs" ino=1234 scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=system_u:object_r:dri_device_t:s0 tclass=chr_file

定位脚本可通过以下规则自动提取:

  • 被禁止的操作:{ open }
  • 目标类型:tcontext=dri_device_t
  • 进程标识:comm="video_encoder" 和 pid=3567
判断规则: 若抖动窗口内同一 scontext 与 tcontext 的 denied 记录出现频次 > 10次/秒,且 tclass 为 chr_file 或 sock_file,则很可能是因为SELinux策略在热路径上反复拒绝导致性能抖动。

3.5 修复动作:基于过滤结果调整策略

根据定位出的具体冲突,生成定制化策略模块:

# 假设需要允许video_encoder访问dri_device_t
sudo checkmodule -M -m -o avc_fix.mod avc_fix.te
sudo semodule_package -o avc_fix.pp -m avc_fix.mod
sudo semodule -i avc_fix.pp

详细修复步骤将在后续章节展开,本章仅强调采集数据后应立即执行该动作以使收集到的日志具有决策意义。

3.6 复测:验证采集方法的正确性

修复后需复测avc日志是否仍产生大量 denied:

# 同一时间窗口再次过滤
ausearch -m avc -ts 14:30:15 -te 14:30:25 -i | grep "denied" | wc -l
# 若行数接近0,说明修复生效;若仍>0,需扩大时间窗口或检查策略加载

3.7 预防:日志采集系统的定期校验

将以下检查项加入运维巡检:

  • 每天自动检查 auditd 是否运行:systemctl is-active auditd
  • 日志轮转后保留至少72小时历史以便回溯
  • 预设avc捕获规则确保不遗漏新进程的新访问模式
易错点: 若使用 grep 直接读取 /var/log/audit/audit.log 而忽略 ausearch,可能丢失部分已轮转的日志。务必使用 ausearch 作为首选工具。
avc日志采集与过滤流程 ① 现象识别 帧率抖动+avc疑似 ② auditd配置 log_file / max_log_file ③ 捕获规则 avc deny监控 ④ 时间窗口截取 ausearch -ts -te ⑤ ausearch过滤 -m avc -i -p PID ⑥ grep精筛 | grep -E "denied" ⑦ 原因定位 scontext/tcontext冲突 ⑧ 修复动作 生成策略模块 ⑨ 复测 ausearch过滤验证 ⑩ 预防:定期校验auditd systemctl is-active auditd 核心原则:先缩时间窗 → 再用ausearch按字段筛选 → 最后grep精化,避免全量扫描 时间戳必须与系统时钟一致,建议使用NTP同步