第2章 audit日志采集与关键字段解析

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

当系统出现以下现象时,通常意味着SELinux正在阻止某一操作,必须采集AVC日志进行分析:

  • 应用/服务启动失败:如nginx、httpd、MySQL等无法启动或返回权限错误。
  • 文件/设备访问被拒:进程无法读写某个文件、套接字或设备节点。
  • 网络连接异常:bind、connect操作失败,本地端口无法监听。
  • dmesg或messages中出现“avc: denied”关键词:这是直接证据。
  • audit.log中记录了大量“DENIED”条目:即使应用未显式报错,也应检查是否有非关键路径的AVC拒绝。
关键词触发器:日志中包含“avc: denied”、“permissive=0”、“scontext=... tcontext=...”其中之一时,应立刻执行日志采集。

2.2 数据采集:ausearch -m avc 命令使用

ausearch是auditd套件中最核心的检索命令,用于从 /var/log/audit/audit.log 中按条件过滤AVC事件。

前提条件:系统必须已安装 auditd 软件包,并且服务处于运行状态。
# systemctl status auditd          # 检查服务是否运行
# ausearch -i -m avc -ts today   # 立即测试命令可用性

2.2.1 基本语法与常用选项

选项含义示例
-m avc限定只检索AVC消息类型ausearch -m avc
-ts设置起始时间(today/yesterday/date)ausearch -m avc -ts 09:00:00
-te设置结束时间ausearch -m avc -ts 09:00 -te 10:00
-i解释模式,将SELinux用户/角色转换为可读名称ausearch -i -m avc
-p PID按进程PID过滤ausearch -m avc -p 12345
-c COMM按进程名过滤ausearch -m avc -c httpd
--highlight高亮匹配的关键词(avc/ denied等)ausearch -m avc --highlight

2.2.2 典型采集命令套路

排产铁律:不要一次性检索全部日志,应按“时间+进程”组合过滤。下面三类命令覆盖90%场景:
# 场景A:查看今天的全部AVC拒绝
ausearch -i -m avc -ts today

# 场景B:查看特定进程httpd在过去10分钟内的拒绝
ausearch -i -m avc -c httpd -ts 10:00 -te 10:10

# 场景C:直接查看最新5条拒绝(适合快速验证修复)
ausearch -i -m avc --latest 5
输出重定向建议:将采集结果保存到单独文件,避免污染原始日志。
ausearch -i -m avc -ts today > /tmp/avc_today.log

2.3 原因定位:AVC日志关键字段详解

一条完整的AVC日志由10个以上字段组成,排错时只需聚焦以下7个核心字段。以下是对某条真实日志的逐字段拆解:

type=AVC msg=audit(1680001234.789:12345): avc: denied { write } for pid=12345 comm="httpd" name="index.html" dev="sda1" ino=98765 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:default_t:s0 tclass=file permissive=0

字段速查表

字段名含义排错价值(★)示例值
type审计消息类型,AVC固定为“AVC”★ 确认是SELinux拒绝AVC
audit时间戳(秒.微秒:序列号),用于关联其他事件★★ 排查时间线串联1680001234.789:12345
pid发起拒绝操作的进程ID★★ 定位具体进程12345
scontext源安全上下文(进程的上下文)★★★★★ 排错起点system_u:system_r:httpd_t:s0
tcontext目标安全上下文(被访问对象的上下文)★★★★★ 定义被拒象身份unconfined_u:object_r:default_t:s0
tclass目标对象类别(file/dir/socket等)★★★ 确定访问类型file
permissions被拒绝的操作({ read write execute open })★★★★ 知道缺了什么权限write
排错三步骤口诀:
1️⃣ 看scontext:谁在发起请求?(例: httpd_t)
2️⃣ 看tcontext+tclass:要访问什么类型对象?(例: default_t类型的file)
3️⃣ 看permissions:具体要执行什么操作?(例: write)

2.4 修复动作:快速辅助分析命令

得到字段后,用以下命令确认是否可以放行或需要添加策略:

# 检查布尔值是否可解决(若tcontext与scontext同类型)
seinfo -t httpd_t -x | grep default_t

# 查看当前策略是否已有类似规则
sesearch --allow -s httpd_t -t default_t -c file -p write

# 生成最小化类型强制模块(仅用于后续步骤,此处只采集不做更改)
# ausearch -m avc -ts today | audit2allow -M my_policy

2.5 复测:验证日志采集是否生效

修复前先确认日志采集成功,修复后再执行一次采集确认拒绝条目消失或变化:

# 1. 采集修复后日志
ausearch -i -m avc -ts 10:10 -te 12:00 > /tmp/avc_after_fix.log

# 2. 对比条目数
wc -l /tmp/avc_before_fix.log /tmp/avc_after_fix.log

# 3. 检查核心字段是否变化(scontext/tclass/permissions可能变为allow)
grep "denied" /tmp/avc_after_fix.log || echo "无拒绝 - 修复成功"

2.6 预防:建立日志采集规范

  • 日常监控:设置cron每小时执行一次 ausearch -i -m avc -ts 1 hour ago >> /var/log/avc_archive.log
  • 存储隔离:每天将原始audit.log轮转,避免日志过大导致采集慢。
  • 采集模板:在排错手册中固定使用“时间+进程”组合模板,减少随机采集。
AVC日志关键字段解析流程图 AVC日志字段解析流程 原始AVC日志行 avc: denied { write } for pid=12345 comm="httpd" ... scontext (源) httpd_t: system_u:system_r:httpd_t:s0 tcontext (目标) default_t: unconfined_u:object_r:default_t:s0 tclass + permissions file (类型) + write (权限) 对比源(scontext) 与 目标(tcontext+tclass) 的类型 是否同一个类型? → 看布尔值;不同 → 需要添加允许规则 权限需要 放行? 是 → audit2allow 否 → 检查布尔值或权限
字段深度解析提醒:comm 字段有时与进程名一致,但若进程在执行前rename自身,则 comm 可能与 exe 不同。必须额外使用 ausearch -m avc -c $comm 和 grep "pid=$pid" /proc/pid/status 交叉验证。