1. SELinux基础与AVC拒绝现象识别

SELinux(Security-Enhanced Linux)是内核级强制访问控制安全模块,为系统进程和文件提供细粒度权限管控。当进程试图访问未获授权的资源(文件、端口、进程等)时,内核会生成 AVC(Access Vector Cache)拒绝消息。本章从故障排查视角出发,帮助您快速识别AVC拒绝现象,掌握数据采集与初步定位方法。

现象识别

AVC拒绝不会直接弹出图形化警告,而是通过服务异常、功能中断等间接症状表现。典型症状包括:

  • 服务启动失败:如 httpd 启动时报错 Permission denied 或 无法绑定端口,但系统防火墙已放行。
  • 文件访问被拒:应用读取配置文件、写入日志或访问共享库时返回 EACCES,且文件权限正确。
  • 网络连接断开:已建立的 TCP 连接被突然重置(RST),或新连接被拒绝,而 iptables / nftables 规则未限制。

上述现象在其他安全层(文件权限、防火墙)检查无误时,应优先怀疑 SELinux 策略限制。

快速识别流程:当出现上述任一症状且常规权限正常时,按以下流程图定位 AVC 拒绝。
AVC拒绝识别流程 出现典型症状 检查文件/网络权限 有? 常规权限排查 采集 audit 日志 ausearch / journalctl 确认 AVC denied 消息 提取 scontext/tcontext/class 若日志中出现 "type=AVC ... denied" 字样,即可确定 SELinux 为根因。

数据采集

确认疑似 SELinux 问题后,立即采集审计日志。推荐两条命令:

命令适用场景示例
ausearch -m avc -ts recent搜索最近 AVC 事件快速查看近5分钟拒绝
journalctl -t setroubleshoot --since "5 min ago"通过 systemd 日志查看详细解释含文字化建议
ausearch -m avc -c httpd按进程名过滤定位具体服务
# 查看最近 AVC 拒绝事件
ausearch -m avc -ts recent

# 通过 journalctl 查看 SELinux 冲突
journalctl -t setroubleshoot --since "10 min ago"

原因定位

采集到 denied 日志后,提取以下关键字段用于定位:

  • scontext — 源安全上下文(发起访问的进程)
  • tcontext — 目标安全上下文(被访问的资源)
  • class — 访问类别(file、socket、dir、process 等)
  • comm — 进程名

典型日志片段:

type=AVC msg=audit(1700000000.123:456): avc: denied { read } for pid=1234 comm="httpd" name="index.html" dev="sda1" ino=789 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:default_t:s0 tclass=file

可见 httpd_t 尝试读取 default_t 类型的文件,而策略未允许该访问。

修复动作

临时验证可切换为宽容模式,但切勿在生环境长期使用:

# 临时将系统切换为 Permissive 模式(仅用于验证)
sudo setenforce 0

# 再次触发症状,若问题消失则确认 SELinux 是根本原因

警告:生产环境禁止长期开启宽容模式。验证完毕后应立即恢复强制模式:setenforce 1。

复测

恢复强制模式后,运行 ausearch -m avc -ts recent 确认再无新拒绝事件,然后重新启动目标服务并验证功能正常。

# 重新启动服务
sudo systemctl restart httpd

# 验证服务状态与业务功能
curl -I http://localhost/

预防

  • 保持 SELinux 处于强制模式,仅通过策略调优解决问题。
  • 部署新应用前,使用 audit2allow -a 生成初步策略模块并审查。
  • 记录所有 AVC 拒绝日志,按周审计,提前发现隐蔽问题。