第4章 常见拒绝根因定位方法:策略缺失、布尔值关闭、文件/进程上下文错误、dontaudit规则屏蔽、多域交互冲突;故障树分析法
现象识别
avc: denied 日志是 SELinux 拒绝的唯一直接证据。典型特征:日志中包含 type=AVC msg=audit(...),并附带 scontext(源上下文)、tcontext(目标上下文)、tclass(资源类别)、permission(被拒绝的操作)。拒绝动作本身可能表现为进程报错、文件无法访问、端口绑定失败等,但根因隐藏在 AVC 日志中。
日志示例
type=AVC msg=audit(1680000000.123:456): avc: denied { read } for pid=1234 comm="httpd" name="config" dev="dm-0" ino=5678 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:default_t:s0 tclass=file
解读:httpd_t 试图读取一个标记为 default_t 的文件,策略未允许 httpd_t 对 default_t 文件的 read 权限。
数据采集
- 收集最新的 AVC 日志:
ausearch -m avc --start recent或cat /var/log/audit/audit.log | grep denied。 - 确认当前布尔值状态:
getsebool -a | grep -E 'httpd|ftpd|named'(根据涉及进程筛选)。 - 检查文件上下文:
ls -Z /path/to/problem/file或matchpathcon /path。 - 检查进程上下文:
ps -Z -p PID。 - 确认是否被
dontaudit规则静默:semodule -l | grep dontaudit(临时关闭dontaudit可暴露静默拒绝:semodule -DB)。
原因定位——故障树分析法
下图展示从 AVC 拒绝日志到五种常见根因的决策分支。故障树顶部是“avc denied 日志”,向下按“权限是否明确允许?”、“上下文是否匹配?”、“布尔值是否开启?”、“是否存在 dontaudit 规则?”、“多域交互是否冲突?”层层分解。
根因排查对照表
| 根因 | 判断规则 | 典型日志特征 | 修复动作 |
|---|---|---|---|
| 策略缺失 | 使用 audit2allow -a 生成策略模块,若出现新权限则说明缺失。 |
日志中 scontext=t:类型A 对 tcontext=t:类型B 请求某权限。 |
|
| 布尔值关闭 | 检查涉及进程的布尔值:getsebool httpd_can_network_connect。若为 off 则关闭。 |
日志中 comm="httpd" 但 permission 为 name_connect 等受布尔值控制的权限。 |
|
| 文件/进程上下文错误 | ls -Z target_file 确认是否为预期类型。ps -Z -p PID 确认进程域是否正确。 |
日志中 tcontext=...:unlabeled_t 或 tcontext=...:default_t。 |
|
| dontaudit 规则屏蔽 | 执行 semodule -DB 后重新触发操作,若出现新 AVC 日志则说明之前被屏蔽。 |
原始日志不存在,但 ausearch 无结果,而操作实际失败。 |
|
| 多域交互冲突 | 检查域间过渡规则:sesearch -s domA -t domB -c process -p transition。若缺少过渡权限或类型强制规则。 |
日志中 permission=transition 或 entrypoint,且涉及两种不同域。 |
编写策略模块允许域间过渡,或使用 type_transition 规则。 |
修复动作
- 策略缺失:使用
audit2allow生成本地策略模块并加载。 - 布尔值关闭:
setsebool -P <name> on永久开启。 - 上下文错误:
semanage fcontext修正文件类型标签,再执行restorecon;对进程使用runcon或调整启动脚本的Type=域。 - dontaudit 屏蔽:仅开发环境使用
semodule -DB暴露拒绝,生产环境应编写auditallow规则并移除dontaudit。 - 多域交互冲突:添加
allow domA domB:process transition;并设置type_transition。
警告:semodule -DB 会重建整个策略,可能造成额外拒绝日志。使用前请备份当前策略:semodule -l > module_backup.txt。完成后务必执行 semodule -B 恢复默认 dontaudit 规则。
复测
- 重新触发被拒绝的操作(如重启服务、访问文件、尝试端口连接)。
- 检查最新审计日志:
ausearch -m avc --start recent | tail -20。 - 确认无新增
denied记录。若有,返回故障树重新定位。 - 对于
dontaudit场景,复测前需先semodule -B恢复屏蔽规则,确保操作被允许且不再记录。
预防
- 策略开发阶段:使用
audit2allow自动化生成初始策略,避免手工遗漏。 - 布尔值审计:定期执行
getsebool -a | grep 'off'检查关键布尔值状态。 - 文件上下文基线:使用
semanage fcontext -l维护自定义文件类型列表,配合restorecon -R脚本确保一致性。 - 禁止滥用 dontaudit:除开发者沙箱外,生产环境避免使用
semodule -DB,应编写显式auditallow规则代替。 - 多域交互测试:在部署前利用
sesearch和apol(SETools)验证域间过渡路径是否完整。