SELinux 与 AppArmor¶
本文你会学到:
- DAC(自主式访问控制)与 MAC(强制访问控制)的区别
- SELinux 与 AppArmor 的设计哲学
- SELinux 的三个核心组件:Context、Role、Policy
- 文件的 SELinux Context 与进程的 Domain
- 查看与修改 SELinux 上下文(
ls -Z、chcon、restorecon) - SELinux 的工作模式(Enforcing、Permissive、Disabled)
- AppArmor 的配置文件与规则语法
- 常见的 SELinux 错误排查与审计日志
- 针对实际服务的 SELinux 策略调整
- MAC 在企业环境中的应用与注意事项
DAC vs MAC:两种访问控制模型¶
传统模型的局限:DAC¶
DAC(Discretionary Access Control,自主式存取控制)是 Linux 的传统权限体系,基于 rwx 权限位与文件所有者来决定访问权限。
它有两个致命弱点:
- root 无限权:任何以 root 身份运行的程序都拥有最高权限,一旦被入侵,整个系统门户洞开
- 权限可随意下放:用户可以将目录权限设为
777,所有程序均可读写,完全失控
典型风险场景:将 /var/www/html/ 权限设为 777 后,Apache 进程可以写入该目录,而 Apache 又对外提供服务,攻击者可借此写入恶意文件。
强制访问控制的解决思路:MAC¶
MAC(Mandatory Access Control,委任式存取控制)将控制粒度从"用户"细化到"进程"。
核心理念:每个进程只能访问系统策略明确授权的资源,即使是 root 进程也不例外。
以 Apache 为例:httpd 进程默认只能访问 /var/www/ 下的内容,即使 httpd 被攻击者控制,也无法读取 /etc/shadow 等敏感文件——因为策略根本没有授权 httpd 访问那些路径。
| 维度 | DAC | MAC |
|---|---|---|
| 控制主体 | 文件所有者 / 用户 | 系统策略(管理员制定) |
| root 是否受限 | ❌ 完全豁免 | ✅ 受策略约束 |
| 防内部误用 | 能力有限 | 有效隔离 |
| 典型实现 | Unix rwx 权限 |
SELinux、AppArmor |
两者并存,不是替代
MAC 是在 DAC 之上叠加的一层检查,两者同时生效。进程必须**同时通过** MAC 策略检查和 DAC 权限检查,才能访问目标文件。
SELinux(Red Hat 系默认)¶
SELinux(Security-Enhanced Linux)由美国国家安全局(NSA)开发并合并进 Linux 内核,是 RHEL/CentOS/Fedora 系列发行版的默认安全模块。
三种工作模式¶
| 模式 | 行为 | 使用场景 |
|---|---|---|
enforcing |
强制执行策略,拒绝违规访问并记录日志 | 生产环境(推荐) |
permissive |
只记录日志,不实际拦截 | 调试、排查问题 |
disabled |
完全禁用,不参与任何检查 | 不推荐,切换需重启 |
| 查看与切换模式 | |
|---|---|
永久修改需要编辑配置文件并重启:
| /etc/selinux/config | |
|---|---|
禁用 SELinux 需要重启
从 enforcing/permissive 切换到 disabled,或从 disabled 切换回来,都必须重启系统。从 disabled 启用时,系统需要重新为所有文件写入安全上下文标签,首次启动耗时较长,写完后还需再次重启。
安全上下文(Security Context)¶
SELinux 为每个**进程**和**文件**都打上安全标签,称为安全上下文(Security Context)。格式为:
user(身份):system_u(系统进程产生)、unconfined_u(用户 bash 产生)role(角色):object_r(文件/目录)、system_r(系统进程)type(类型):最关键的字段,也叫"域"(domain),决定进程能访问哪些资源level:MLS 安全级别(targeted策略下通常为s0,可忽略)
在默认的 targeted 策略下,只有 type 字段真正起作用——进程的 domain 必须与文件的 type 匹配,才能访问该文件。
| 查看 SELinux 上下文 | |
|---|---|
输出示例:
httpd 进程运行在 httpd_t 域,只有 httpd_sys_content_t 类型的文件才能被它读取——这就是 MAC 的核心机制。
修复文件上下文¶
⚠️ 最常见的 SELinux 问题就是**文件上下文类型不正确**,导致服务无法读取自己的文件(即使 rwx 权限是开放的)。
典型场景:将文件从 home 目录 mv 到 /etc/cron.d/,文件保留了原来的 admin_home_t 上下文,crond 进程读不到它,服务静默失败。
| 修复文件上下文 | |
|---|---|
布尔值(Boolean):细粒度开关¶
SELinux 的策略里内置了很多可以动态开关的规则,称为布尔值(Boolean)。不需要修改策略文件,通过布尔值就能控制是否允许某类行为。
| 布尔值管理 | |
|---|---|
常用布尔值速查:
| 布尔值 | 作用 |
|---|---|
httpd_can_network_connect |
允许 Apache 发起网络连接(反向代理等) |
httpd_enable_homedirs |
允许 Apache 访问用户主目录 |
samba_enable_home_dirs |
允许 Samba 共享用户主目录 |
allow_ftpd_anon_write |
允许 FTP 匿名写入 |
httpd_use_nfs |
允许 Apache 访问 NFS 挂载目录 |
端口管理¶
服务监听非标准端口时,SELinux 也会拦截。需要显式注册允许的端口:
| SELinux 端口管理 | |
|---|---|
排查拒绝问题¶
遇到疑似 SELinux 导致的权限问题时,按以下流程排查:
graph TD
A[服务访问失败] --> B{临时切换为 permissive\nsetenforce 0}
B -->|问题消失| C[确认是 SELinux 问题]
B -->|问题仍在| D[不是 SELinux 问题\n检查 rwx 权限]
C --> E[查看 audit 日志\naudit.log / journalctl]
E --> F[audit2why 分析原因]
F --> G{问题类型}
G -->|文件上下文错误| H[restorecon 恢复上下文]
G -->|功能开关问题| I[setsebool -P 调整布尔值]
G -->|非标准端口| J[semanage port 注册端口]
G -->|自定义需求| K[audit2allow 生成自定义策略]
classDef decision fill:transparent,stroke:#f57c00,color:#adbac7,stroke-width:2px
classDef action fill:transparent,stroke:#0288d1,color:#adbac7,stroke-width:1px
classDef terminal fill:transparent,stroke:#388e3c,color:#adbac7,stroke-width:1px
class B,G decision
class C,E,F action
class D,H,I,J,K terminal
| 审计日志与分析工具 | |
|---|---|
优先用 restorecon 和 setsebool,谨慎用 audit2allow
audit2allow 生成的自定义策略会绕过 SELinux 的保护意图,应优先通过 restorecon(修复上下文)或 setsebool(开启功能开关)解决问题,实在无法解决再考虑自定义策略。
AppArmor(Debian 系默认)¶
AppArmor 是 Debian/Ubuntu/SUSE 系列的默认 MAC 实现,相比 SELinux 采用更直观的**路径规则**(Profile)方式,学习曲线较平缓。
两种工作模式¶
| 模式 | 行为 |
|---|---|
enforce |
强制执行,拦截违规访问 |
complain |
仅记录日志,不拦截(类似 SELinux 的 permissive) |
常用操作¶
| 切换模式 | |
|---|---|
Profile 结构¶
AppArmor 的配置文件(Profile)存放在 /etc/apparmor.d/,以程序路径命名,内容直观:
权限字符说明:r(读)、w(写)、x(执行)、k(文件锁)、m(内存映射)。
查看拒绝日志与生成 Profile¶
| 拒绝日志 | |
|---|---|
| 生成与更新 Profile | |
|---|---|
SELinux vs AppArmor 对比¶
| 特性 | SELinux | AppArmor |
|---|---|---|
| 默认发行版 | RHEL / Fedora / CentOS | Debian / Ubuntu / SUSE |
| 控制粒度 | 极细(用户/角色/类型/级别) | 中等(路径/能力) |
| 学习曲线 | 较陡,概念较多 | 较平,规则直观 |
| 配置方式 | 类型强制(Type Enforcement) | 路径规则(Profile) |
| 调试工具 | audit2why / audit2allow |
aa-logprof |
| 内核实现 | 基于标签(inode 存储上下文) | 基于路径(文件名匹配) |
发行版安装与配置¶
SELinux 默认已启用(enforcing 模式),安装调试工具:
查看 setroubleshootd 的建议: