第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

各字段含义如下:

字段示例说明
usersystem_uSELinux用户身份,用于约束角色继承(非Linux UID)
roleobject_r角色,决定进程可访问的角色类型(对象通常为object_r)
typehttpd_t类型标识符,MAC最核心字段,用于类型强制规则
levels0多级安全(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整体检查流程

下图展示从进程请求访问文件到最终授权的完整检查链路:

SELinux MAC与DAC叠层检查流程 进程访问请求 DAC(ugo权限)检查 DAC拒绝 → 操作失败 DAC通过 → 进入MAC检查 MAC(类型强制)检查 AVC拒绝 → 操作失败 MAC通过 → 操作成功 AVC拒绝记录 type=AVC ... denied { read } scontext=... tcontext=... 总则:DAC和MAC均通过 → 操作成功;任一拒绝 → 操作失败(日志记录在 /var/log/audit/audit.log)

1.5 常见调试命令与排查起点

  1. 查看AVC拒绝日志:
    ausearch -m avc -ts recent
    # 或直接搜索审计日志
    grep "avc:  denied" /var/log/audit/audit.log
  2. 临时开启宽松模式排查:
    # 仅在调试环境使用,生产环境严格禁止
    setenforce 0    # 临时关闭强制模式(Permissive)
    # 运行可疑操作,观察日志
    setenforce 1    # 恢复强制模式
  3. 查看当前上下文的类型:
    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章将进入实际的域定义与类型声明,正式开启策略编写之旅。