六.管理SELinux安全
1.管理SELinux模式
1.1SELinux概念
SELinux 的全称是 Security-Enhanced Linux(安全增强式 Linux)。它并非一个独立的 Linux 发行版,而是由美国国家安全局(NSA)贡献给 Linux 社区的一个强制访问控制 安全模块,并直接集成到 Linux 内核中。
它通过策略规则 和安全上下文标签 ,实现对系统资源 (文件、进程、网络端口等)的细粒度访问控制,弥补了 Linux 传统 "自主访问控制(DAC,如 rwx 权限)" 的安全短板。
对比:
|------------|------------------------|-------------------------------|
| 维度 | 自主访问控制(DAC) | 强制访问控制(SELinux) |
| 控制粒度 | 基于用户/组身份(如 root、普通用户) | 基于策略+安全上下文标签 ,与用户身份解耦 |
| 权限限制 | 若用户拥有 root 权限,可突破大部分限制 | 即使是 root 用户,也受策略严格约束 |
| 安全目标 | 满足 "用户自主授权" 需求 | 防止权限滥用(如服务被入侵后扩散攻击)、最小权限原则落地 |
其核心实现依赖****"Targeted 策略"****:
仅对关键网络服务 (如sshd、mysqld等)做细粒度控制,对普通用户操作影响极小 ,是RHEL 9 的默认策略。
1.2为什么使用SELinux
(1) 漏洞隔离:
某服务(如 Apache)被入侵后,SELinux 会 "禁锢" 入侵行为在该服务的权限范围内,避免影响整个系统;
(2) 额外安全层:
弥补传统权限的不足(如误配置文件权限导致的泄露),实现 "默认拒绝"------ 所有未明确允许的操作都被阻断;
(3) 合规需求:
政府、金融等行业对服务器安全的强制要求,SELinux 是满足 "最小权限原则" 的核心工具。
1.3.SELinux核心组件
SELinux 的访问控制依赖两个核心:安全上下文 (Label) 和策略规则,理解这两个概念是管理 SELinux 的关键。
1.3.1安全上下文(身份证)
1.3.1.1SELinux 上下文(context)
每个 "进程、文件、目录、端口" 都有一个唯一的 "标签",称为SELinux 上下文。
格式为:
User:Role:Type:Level:File
(1)User------SELinux用户
SELinux内部的"身份标识";
不是 Linux 系统的用户(如 root、user1),而是 SELinux 自身定义的 "用户身份",用于区分系统资源和普通用户资源的归属。
常见值:
unconfined_u :普通用户的 SELinux 身份(默认不受 SELinux 严格限制);
system_u:系统级资源的 SELinux 身份(如系统服务、配置文件)。
(2)Role------SELinux角色
关联 "SELinux 用户" 和 "权限范围",用于限制用户能访问的资源类型,通常以_t结尾。
常见值:
object_r:资源类对象的角色(如文件、目录、端口);
system_r:系统服务类进程的角色(如 httpd、sshd 进程)。
(3)Type------域/类型
SELinux 强制访问控制 的核心依据 。进程的 type 称为 "域 ",资源 (文件、目录、端口)的 type 称为 "类型"。策略通过"域-类型"的规则,决定进程能否访问资源。
常见值:
进程域:httpd_t(Apache进程的域)、sshd_t(SSH进程的域);
资源类型:httpd_sys_content_t(Apache 可访问的网页文件类型)、ssh_port_t(SSH 服务的端口类型)。
(4)Level
用于多级安全(MLS)场景(如政府、军工),区分 资源的"机密性级别"(如"绝密""机密")。
常见值:
默认是s0(无特殊级别),高安全场景会有s0:c0.c1023 等细分级别。
(5)总结
|------------|-------------------------|--------------------|----------------------------------------|
| 字段 | 含义类比(公司门禁场景) | 核心作用 | 常见示例 |
| user | 公司内部身份(普通员工/管理员) | 区分资源的 SELinux 身份归属 | unconfined_u、system_u |
| role | 门禁卡用途分类(资源门 / 服务门) | 关联用户与权限范围 | object_r、system_r |
| type | 门牌号 + 权限(进程卡类型 / 资源门类型) | 强制访问控制的核心决策依据 | httpd_t(进程域)、httpd_sys_content_t(资源类型) |
| level | 门的机密级别(普通 / 机密) | 多级安全场景的机密性控制 | s0、s0:c123 |
如:

解释:
unconfined_u:
SELinux用户(表示该资源关联的SELinux身份,这里是"不受限用户");
object_r:
SELinux角色(用于资源类对象的角色标识);
user_home_t:
SELinux类型(核心字段 ,表明该目录属于"用户家目录类型",SELinux会基于此类型判断进程是否有权访问);
s0:
安全级别(RHEL默认的基础安全级别,多用于多级安全场景,此处无特殊限制);
Desktop/:
对应的目录路径。
1.3.1.2查看上下文
查看文件/目录上下文:
ls -Z 文件路径;
ls -Zd 目录路径;
如:

查看进程的上下文:
ps -Z 进程名;

但有些 Linux 发行版(如采用 BSD 风格 ps 的系统),需要通过 -C 参数明确指定 "进程的命令名称",才能正确过滤并显示上下文。
即:
ps -ZC 进程名;

1.3.2SELinux策略规则
SELinux 的 "策略" 是预定义的规则集,核心逻辑是:"允许特定域(进程 type)访问特定类型(资源 type)的资源"若没有明确的 "允许规则",则默认拒绝访问;
即定义哪些进程 可以访问 哪些资源。
1.3.2.1规则组成
|----------------------------|-----------------------------------|------------------------------------------------------------------|
| 组件 | 作用 | 示例 |
| 类型强制 (Type Enforcement,TE) | 控制进程域(即进程的type)与资源类型(Type)之间的访问权限 | allow httpd_t httpd_sys_content_t:file read; (允许 Apache 进程读网页文件) |
| 角色(Role) | 关联"用户"与"进程域",限制用户能切换到哪些域 | user_r角色默认仅能切换到 unconfined_t 域(普通用户域) |
| 用户(User) | 关联"角色"与"策略类型",实现多用户场景的权限隔离 | system_u(系统用户)、user_u(普通用户) |
| 布尔值(Boolean) | 策略的"开关",无需修改规则即可动态调整访问权限 | httpd_enable_homedirs (控制 Apache 是否能访问用户家目录) |
1.3.2.2策略规则的核心构成
SELinux 策略规则基于类型强制(Type Enforcement,TE),这是其最核心的访问控制机制。规则的基本语法为:
allow 主体类型(进程type) 资源类型:资源类别 权限列表
解释:
主 体类型:
进程的 SELinux 类型(如httpd_t、sshd_t),代表 "谁在发起访问"。
资源 类型:
资源(文件、端口、进程等)的 SELinux 类型(如httpd_sys_content_t、ssh_port_t),代表 "被访问的对象"。
资源 类别:
资源的类别(如file、tcp_socket、process),用于区分不同类型的资源。
权限列表:
允许的操作(如read、write、execute、connect、name_bind等)。
如:
allow httpd_t httpd_sys_content_t:file (read write)
解释:
允许类型为httpd_t的进程 ,对类型为httpd_sys_content_t 的文件类资源,执行读、写操作。
1.3.3 SELinux模式
1.3.3.1SELinux运行模式
SELinux 通过 "模式" 控制管控强度;
三种运行模式:
|--------------|----------------|----------------------------------------------------|--------------|---------------------------|
| 模式类型 | 对应命令识别 | 核心行为 | 适用场景 | 关键特点 |
| 强制模式 | Enforcing | 严格执行 SELinux 策略,阻止所有违反策略的操作 ,并记录日志 | 生产环境 | 保障系统安全的 "强管控" 模式 |
| 宽容模式 | Permissive | 不阻止违反策略的操作,但会详细记录所有违规行为到日志 | 测试/故障排查 | 用于调试策略、定位权限问题 |
| 禁用模式 | Disabled | 完全关闭 SELinux,不做任何安全管控 | 特殊兼容场景(不推荐) | 无安全保护,且需重启系统 才能生效 |
注:
自RHEL9起,不能通过修改****/etc/selinux/confi**** g 文件中设置的SELINUX=disabled选项来关闭 SELinux;
必须通过"内核参数"实现:(selinux=0)
(1) 永久禁用:
grubby --update-kernel ALL --args selinux=0(修改所有内核的启动参数);
(2) 恢复启用:
grubby --update-kernel ALL --remove-args selinux(删除禁用参数);
操作后需重启系统生效。
1.4组件关系与工作流程
关系图:

工作流程:
(1)上下文管理与策略验证流程
SELinux 对 "资源(文件 / 目录、网络端口)" 和 "主体(进程)" 的安全上下文初始化流程,是访问控制的基础。

上述三类资源/进程的上下文初始化完成后,会统一进入策略规则验证环节 ------ 检查 "进程域" 与 "资源类型" 的权限是否匹配策略中的 allow 规则,最终做出 "允许" 或 "拒绝" 的访问控制决策。
(2)SELinux策略规则匹配流程

上图是(1)中"策略规则验证" 环节的细节逻辑,展示了 SELinux 如何判断 "是否允许访问"。
(3)SELinux整体访问控制流程

2.更改当前SELinux模式
首先确定当前SELinux的模式。
执行命令:
getenforce;
如:

(1)临时生效
要将SELinux设置为其他模式,使用命令:
setenforce(临时生效)
如:

再进行设置:
强制模式:(Enforcing)
setenforce Enforcing或setenforce 1

宽容模式:(Permissive)
setenforce Permissive或setenforce 0.

(2)永久生效
/etc/selinux/config文件可以永久设置SELinux模式,系统在启动时读取并配置
如:
执行vim /etc/selinux/config命令;
对SELINUX的值进行更改:

修改完成后重启系统使配置生效:

3.控制SELinux文件上下文
3.1初始SELinux上下文
所有资源都标有SELinux上下文,称为SELinux context;
SELinux在****/etc/selinux/targeted/contexts/files/****目录中维护基于文件的文件标签策略数据库,新文件在文件名与现有便签策略匹配时获得默认标签。
新文件的 SELinux context通常从父目录继承,但有两个例外命令:mv和cp -a。
常规继承:
如在/var/www/html/目录(假设其context为httpd_sys_content_t)下新建文件info.txt,该文件会继承父目录的 context,即httpd_sys_content_t。
例外情况:
使用mv移动文件时,文件的 SELinux context保持不变(因为mv只是改变位置,不改变文件本身的安全属性)。
使用cp -a复制文件时,也会有特殊的 context 处理(通常不会从目标父目录继承,而是保留原文件或遵循其他规则)。
使用ls -Z/Zd命令查看文件/目录的SELinux context
3.2更改文件的SELinux context
命令包括:semanage fcontext,restorecon和chcon;
3.2.1semanage fcontext 命令
声明文件的默认标签策略,并将该策略持久化 到 SELinux 上下文数据库 (存储于/etc/selinux/相关目录的策略文件中)。
本质:
"定义规则"------指定某类文件(通过路径匹配)应具备的默认 SELinux context。
格式:
semanage fcontext 选项 路径表达式
核心选项:
-a:添加一条标签策略;
-m:修改已有标签策略;
-d:删除一条标签策略;
-t:指定 SELinux 类型标签(如httpd_sys_content_t、etc_t等);
如:
让 a.txt 被 Web 服务器(httpd 进程)可读:
执行命令:
semanage fcontext -a -t httpd_sys_content_t \
/home/student/a.txt
#或"/home/student/a.dir(/.*)?"
解释:
-a 表示添加策略;
-t httpd_sys_content_t 指定 Web 服务器可读内容的标签类型;
路径精确匹配 a.txt。
(/.*)?匹配目录本身和所有子文件 / 子目录。
注:
此时只是添加规则,并未应用,需要restorcon命令应用;
示例
将TCP 82 端口 添加到 SELinux 的 http_port_t 类型中。

3.2.2restorecon 命令
将semanage fcontext声明的默认 context应用到实际文件,即扫描文件并根据策略数据库 "修复" 其 SELinux context。
当通过semanage新增/修改策略后,需用restorecon让策略生效;或文件 context 被意外篡改时,用于 "恢复" 正确标签。
格式:
restorecon 选项 文件/目录
核心选项:
-R:递归处理目录下的所有文件 / 子目录;
-v:显示详细操作(打印哪些文件的标签被修改);
-n:仅检查不修改(测试哪些文件标签不符合策略)。
如:
让3.2.1中的添加的新策略应用到a.txt
执行命令:
restorecon -v /home/student/a.txt
验证:
ls -Z a.txt,观察是否更改
示例:
恢复目标文件的安全上下文。

3.2.3chcon命令
直接临时修改文件的 SELinux context;
修改不会持久化到 SELinux 上下文数据库,若后续执行restorecon ,chcon设置的标签会被还原(因为restorecon会强制应用数据库中的默认策略)。
格式
(1)直接指定类型标签
chcon -t 目标类型 文件
(2)参考其他文件标签
chcon --reference=参考文件 目标文件
--reference:让"目标文件" 的标签复制自 "参考文件"。
如:
临时将a.txt文件标签改为tmp_t;
执行命令:
chcon -t tmp_t /home/student/a.txt
3.2.4修改命令与流程
|---------------------------|-------------------------|---------|----------|
| 命令 | 作用 | 持久性 | 使用场景 |
| semanage fcontext | 定义 文件的默认标签规则 | 永久 | 策略配置 |
| restorecon | 应用 默认context到文件 | 永久 | 恢复正确标签 |
| chcon | 直接更改 context | 临时 | 快速测试 |
流程:

4.用bool调整SELinux策略
使用SELinux布尔值;
SELinux 布尔值是 控制 SELinux 策略行为的 "开关参数",它可以启用(开)或禁用(关)某一条具体的安全规则。
SELinux 策略本身非常"精细复杂",直接修改策略文件门槛高且易出错。布尔值相当于给用户提供了一组"灵活开关"------ 用动底层策略,只需通过 "开关(布尔值)" 就能调整某类安全规则的生效状态,从而快速适配不同场景的安全需求。
核心命令:
|---------------------|---------------------------|------------------------------------------------------------------|
| 命令 | 功能说明 | 示例用法 |
| getsebool | 列出布尔值及其当前状态 (开/关) | getsebool -a 列出所有布尔值的状态getsebool httpd_enable_homedirs 查看单个布尔值状态 |
| setsebool | 临时修改 布尔值状态(重启后还原) | setsebool httpd_can_network_connect on 临时允许 httpd 进程进行网络连接 |
| setsebool -P | 永久修改 布尔值状态(重启后保持) | setsebool -P httpd_enable_homedirs on 永久允许 httpd 访问用户家目录 |
| semanage boolean -l | 报告布尔值的永久状态 + 简短描述 | semanage boolean -l |
流程:

5.分析和解决SELinux问题
5.1SELinux冲突常见根源
(1)文件context不对:
文件的SELinux标签错误导致进程无法访问
如:
本该是httpd_sys_content_t,却配成了default_t。
(2)布尔值设置不对:
SELinux 布尔值的"开关"没调对,导致进程被拦截。
如:
该启用httpd_enable_homedirs却没开。
5.2安装监控工具
要实现 SELinux 冲突的自动监控和日志整理,需安装setroubleshoot-server软件包;
命令:
dnf install setroubleshoot-server
会监听****/var/log/audit/audit.log中的 SELinux 审计消息**** ,并将关键冲突信息 "翻译" 后写入/var/log/messages日志,让你能直观看到问题。
如:

5.3日志中的唯一标识符(UUID)
当 SELinux 发生冲突时,/var/log/messages 或****/var/log/audit/audit.log**** 中会记录一个唯一的 UUID(类似 "事件编号")。
通过这个 UUID,可以精准定位某一次冲突的详细信息。
5.4生成冲突报告的命令
5.4.1 sealert命令
(1)单个UUID生成报告
命令:
sealert -l UUID
如:
sealert -l 123e4567-e89b-12d3-a456-426614174000
解释:
生成该 UUID 对应的 SELinux 冲突详细报告,包括问题原因、建议修复步骤(比如告诉你该改哪个 context 或布尔值)。
(2)针对整个审计日志生成全量报告
命令:
sealert -a /var/log/audit/audit.log
解释:
扫描audit.log中所有 SELinux 事件,生成一份完整的报告 ,方便批量排查多个冲突。
(3)排除流程

5.4.2 ausearchg工具
ausearch 是 SELinux 审计日志的搜索工具 ,用于从 /var/log/audit/audit.log 文件中筛选特定类型 的审计消息,帮助排查 SELinux 导致的访问冲突问题。
格式:
ausearch 选项 条件
核心选项:
-m:按照消息类型搜索
-ts:根据开始时间执行搜索
-te:根据开始时间执行搜索
-i选项解释输出(可读性更好)
如:
(1) 搜索所有 SELinux 访问被拒的事件。
ausearch -m AVC
(2)按时间范围筛选日志
ausearch -m AVC -ts 10:00
排查流程

6.总结管理SELinux安全流程:
6.1查看SELinux报错信息
ausearch -m -AVC -ts recent(最近报错)
找到报错的目录(如A_dir)
或:
使用sealert获取更详细的解释
sealert -a /var/log/audit/audit.log
6.2更改SELinux上下文,解决报错
查看上下文:
ls -Z/Zd 目录/目录内容
添加规则:
semanage fcontext -a \
-t 类型设置(如httpd_sys_content_t) \
目录及其内容
应用:
restorecon -Rv 目录路径(如/A_dir)
6.3验证
ls -Z 目录路径
检测是否有新增报错:
ausearch -m AVC -ts recent