第1章 SELinux强制访问控制基础:MAC与DAC区别、安全上下文、类型强制
理解SELinux首先需要厘清它与其他访问控制模型的核心差异。传统Linux使用自主访问控制(DAC),而SELinux引入强制访问控制(MAC),并通过安全上下文和类型强制机制实现精细化的安全策略。本章从原理出发,对比DAC与MAC,拆解安全上下文结构,并演示类型强制的基本概念。
1.1 DAC与MAC的对比
DAC基于用户‑组‑其他(ugo)和文件权限位(rwx),拥有资源的用户可以自行修改权限。MAC则由内核安全服务器强制实施,即使root也无法绕过策略规则。下表列出关键区别:
| 维度 | DAC(自主访问控制) | MAC(强制访问控制) |
|---|---|---|
| 决策依据 | 用户身份(UID/GID)和文件权限 | 主体/客体的安全上下文 + 策略规则 |
| 控制粒度 | 读/写/执行(粗粒度) | 读/写/执行/创建/删除/信号等(细粒度) |
| root权限 | 无限制(可绕过任何DAC) | 受MAC策略约束 |
| 策略可变更性 | 资源所有者可随意修改 | 仅由管理员通过策略模块修改 |
| 典型漏洞场景 | 提权后直接访问敏感文件 | 即使提权,仍需违反策略才能访问 |
⚠ 注意:DAC是Linux的基础访问控制,永远不会被MAC替代。SELinux在DAC之后进行二次检查,两者是叠层关系――只有当DAC和MAC都允许时,操作才能成功。
1.2 安全上下文(Security Context)
每个进程(主体)和文件、端口、设备(客体)都被赋予一个安全上下文。格式统一为:
user:role:type:level
各字段含义如下:
| 字段 | 示例 | 说明 |
|---|---|---|
| user | system_u | SELinux用户身份,用于约束角色继承(非Linux UID) |
| role | object_r | 角色,决定进程可访问的角色类型(对象通常为object_r) |
| type | httpd_t | 类型标识符,MAC最核心字段,用于类型强制规则 |
| level | s0 | 多级安全(MLS)等级,用于更严格的机密性控制 |
使用以下命令查看当前进程和文件的安全上下文:
# 查看当前shell进程的安全上下文
id -Z
# 输出示例:unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
# 查看文件安全上下文
ls -Z /etc/passwd
# 输出示例:system_u:object_r:passwd_file_t:s0 /etc/passwd
# 查看所有进程上下文
ps -eZ | head -5
🔍 现场排查技巧:当应用出现“Permission denied”且DAC权限(ls -l)看似正常时,执行
ls -Z并对比主体类型(进程)与客体类型(文件)是否匹配策略规则。
1.3 类型强制(Type Enforcement)
类型强制是SELinux最核心的机制。所有主体(进程)拥有一个主体类型(如httpd_t),所有客体(文件、端口等)拥有一个客体类型(如httpd_sys_content_t)。策略规则定义主体类型对客体类型可以执行的操作,格式为:
allow 主体类型 客体类型:类别 {许可集合};
# 实例:允许httpd进程读/执行web内容文件
allow httpd_t httpd_sys_content_t:file { read execute };
类型强制遵循默认拒绝原则:未明确 allow 的操作一律拒绝。这使得系统只赋予进程完成任务所需的最小权限。
1.4 MAC整体检查流程
下图展示从进程请求访问文件到最终授权的完整检查链路:
1.5 常见调试命令与排查起点
- 查看AVC拒绝日志:
ausearch -m avc -ts recent # 或直接搜索审计日志 grep "avc: denied" /var/log/audit/audit.log - 临时开启宽松模式排查:
# 仅在调试环境使用,生产环境严格禁止 setenforce 0 # 临时关闭强制模式(Permissive) # 运行可疑操作,观察日志 setenforce 1 # 恢复强制模式 - 查看当前上下文的类型:
seinfo -t httpd_t -x # 列出httpd_t的所有许可继承链
💡 性能提示:类型强制检查在每次系统调用时进行,但SELinux使用AVC(访问向量缓存)有效缓存已决策的访问许可,对大多数常规操作无显著性能损耗。若需极致优化,可考虑针对高频操作预加载策略(
semodule -B)。
1.6 常见错误与纠正
| 错误现象 | 原因 | 解决方向 |
|---|---|---|
应用日志提示“Permission denied”,但ls -l显示权限正确 | MAC拒绝了操作 | 使用ausearch -m avc找到缺失规则,编写自定义策略模块 |
使用setenforce 0后恢复正常 | 确认是SELinux问题 | 不可用Permissive模式作为方案,必须补全允许规则 |
| 修改了文件上下文但未生效 | 未执行restorecon或策略未重新加载 | 执行restorecon -Rv /path或semodule -i |
掌握以上基础概念后,第2章将进入实际的域定义与类型声明,正式开启策略编写之旅。