SELinux安全性管理详解
一、SELinux架构与核心原理
1.1 SELinux概述
安全增强型Linux(SELinux)是Linux系统核心安全机制,可对文件、端口、进程等系统资源进行精细化访问控制。进程仅能访问SELinux策略、布尔值规则明确授权的资源,未定义的操作默认全部禁止,可有效防护漏洞程序、恶意越权访问。
1.2 传统文件权限的缺陷(DAC自主访问控制)
常规Linux文件权限(所有者、所属组、其他用户)属于DAC自主访问控制,仅管控「谁能读写执行文件」,无法管控「文件的使用方式」。
示例:若用户拥有某结构化数据文件的写入权限,任意编辑器、程序均可修改该文件,可能造成数据损坏、信息泄露,传统权限无法拦截此类非预期访问。
1.3 MAC强制访问控制(SELinux核心)
SELinux提供MAC强制访问控制安全层,所有用户、进程必须遵循统一策略规则,普通用户无法自主绕过,弥补了DAC权限的安全短板。
SELinux采用目标策略机制:开发人员为每个服务/程序定义专属规则,明确二进制文件、配置、数据文件的合法操作权限,仅授权行为可执行。无专属策略的程序无SELinux防护,受限域程序严格遵循策略运行。
1.4 SELinux三种运行模式
| 运行模式 | 特性说明 | 适用场景 |
|---|---|---|
| Enforcing(强制模式) | 默认模式,加载并强制执行SELinux策略,违规访问直接拒绝并记录日志 | 生产环境,保障系统安全 |
| Permissive(宽容模式) | 加载策略、监控违规行为,仅记录日志,不拦截访问 | 测试、排错、调试策略规则 |
| Disabled(关闭模式) | 完全关闭SELinux,不加载策略、不记录、不拦截任何违规操作 | 不推荐使用,彻底丧失SELinux安全防护 |
1.5 SELinux上下文标签机制
系统所有资源(进程、文件、目录、端口)均携带SELinux上下文标签,标签包含user、role、type、securitylevel四个字段,RHEL默认目标策略仅通过type类型字段 控制权限(类型后缀多为_t)。
核心匹配规则:进程类型上下文 + 资源类型上下文 = 允许/拒绝访问,无明确允许规则则默认拒绝。
典型场景示例:
-
httpd进程:
httpd_t上下文,仅允许访问httpd_sys_content_t类型网页文件 -
mysql进程:
mysqld_t上下文,仅允许访问mysqld_db_t类型数据库文件 -
临时目录/tmp:默认
user_tmp_t上下文,httpd默认无访问权限,可防止失守网页进程越权读取临时文件
二、SELinux模式管理(临时+永久)
2.1 查看当前SELinux模式
bash
getenforce
返回结果:Enforcing(强制)/ Permissive(宽容)
2.2 临时修改SELinux模式(重启失效)
bash
# 临时设置为宽容模式
setenforce 0
# 临时设置为强制模式
setenforce 1
# 等价写法
setenforce Permissive
setenforce Enforcing
2.3 永久修改SELinux模式(重启生效)
修改核心配置文件 /etc/selinux/config,系统开机读取该文件生效,内核启动参数可覆盖该配置。
bash
# 编辑配置文件
vim /etc/selinux/config
# 配置参数说明
SELINUX=enforcing # 可选:enforcing/permissive/disabled
SELINUXTYPE=targeted # 默认目标策略,保护指定进程
bash
# 验证配置修改
grep '^SELINUX' /etc/selinux/config
# 重启系统生效
reboot
2.4 内核启动参数临时控制SELinux
系统开机阶段可通过内核参数临时修改SELinux状态,优先级高于 /etc/selinux/config 配置文件,常用于紧急调试、故障修复。
内核参数对应功能:
-
selinux=0:开机临时关闭SELinux -
selinux=1:开机临时开启SELinux -
enforcing=0:开机强制进入宽容模式 -
enforcing=1:开机强制进入强制模式
✅ 官方生产建议:将SELinux从宽容模式改为强制模式后,必须重启服务器,保证所有服务重新纳入SELinux策略管控,避免残留权限漏洞。
三、SELinux 文件上下文管理(高频考点+实操核心)
3.1 文件上下文核心概念
文件、目录的SELinux上下文标签,决定了哪个服务可以访问该资源 。绝大多数Linux网站403报错、文件访问拒绝,根源都是文件上下文标签错乱。
系统默认存在标准上下文策略数据库,存放路径:/etc/selinux/targeted/contexts/files/。
3.2 文件标签继承规则(重中之重)
-
复制文件 cp :生成新inode,继承目标目录默认上下文标签
-
移动文件 mv :保留原inode,继承原始目录标签,不会跟随新目录变更
3.3 常用上下文查看命令
bash
# 查看系统进程SELinux上下文
ps axZ
# 精准查看httpd进程上下文
ps -ZC httpd
# 查看文件SELinux标签
ls -Z
# 仅查看目录本身的SELinux标签(不递归子文件)
ls -Zd /var/www/html/
3.4 三种上下文修改方式区别
3.4.1 chcon(临时修改)
直接手动修改文件标签,不写入系统策略,临时生效。重启系统或执行restorecon后会还原,仅用于测试调试。
bash
# 修改目录上下文为网页服务标签
chcon -t httpd_sys_content_t /virtual
# 查看修改结果
ls -Zd /virtual
| 选项 | 说明 |
|---|---|
-t |
只修改 type 类型(最常用) |
-R |
递归处理目录及内部所有文件 |
-v |
显示修改详情 |
--reference=FILE |
复制参考文件完整 SELinux 上下文 |
3.4.2 restorecon(恢复默认策略标签)
读取系统默认SELinux策略,将错乱的文件/目录标签还原为标准合法标签,是排错最常用命令。
bash
# 恢复单个文件默认标签
restorecon -v /custom/mypage
# 递归恢复整个目录所有文件标签
restorecon -Rv /var/www/html/
| 选项 | 说明 |
|---|---|
-R |
递归子目录与文件 |
-v |
简要输出变更 |
-vv |
详细输出每一个文件变更 |
-F |
强制覆盖已有上下文,不管原来标签 |
3.4.3 semanage fcontext(永久策略)
生产环境唯一推荐方式:自定义目录标签策略并写入系统数据库,永久生效、重启不丢失。
正则语法说明:(/.*)? 匹配当前目录 + 目录下所有文件、子目录
bash
# 给自定义网页目录添加永久SELinux策略
semanage fcontext -a -t httpd_sys_content_t '/custom(/.*)?'
# 刷新生效标签
restorecon -RFvv /custom/
# 查看所有自定义上下文策略
semanage fcontext -l -C
| 选项 | 说明 |
|---|---|
-a |
add,新增一条路径规则 |
-d |
delete,删除一条路径规则 |
-l |
list,列出全部 fcontext 规则 |
-t TYPE |
指定 SELinux type 类型 |
目录名(/.*)?
(/.*):目录斜杠 + 所有子内容?:允许不带后面内容,匹配目录自己
有问号,才会匹配目录本身;没有问号只匹配目录里面的东西。
四、SELinux 布尔值策略调优
4.1 布尔值作用
SELinux布尔值是系统预设的可开关策略模块,无需修改源码,通过开关即可微调服务权限,适配不同业务场景。
简单区分:
- 安全上下文(type 标签):管文件 / 目录是什么类型
- 布尔值 boolean:管进程能不能做某一件特殊的事
举例子:
文件标签正确,但 httpd 依然 403,因为 SELinux 不让 httpd 访问用户家目录,打开布尔值httpd_enable_homedirs on就放行。
4.2 布尔值查询命令
bash
# 查看系统所有SELinux布尔值状态
getsebool -a
# 精准查询指定布尔值
getsebool httpd_enable_homedirs
# 查看布尔值详情(默认值、当前值、功能描述)
semanage boolean -l | grep httpd
4.3 布尔值临时/永久修改
bash
# 临时开启(重启失效)
setsebool httpd_enable_homedirs on
# 永久开启(-P 持久写入策略库,重启不失效)
setsebool -P httpd_enable_homedirs on
# 永久关闭
setsebool -P httpd_enable_homedirs off
4.4 实战:Apache访问用户家目录
默认SELinux禁止httpd读取用户家目录,如需实现 http://IP/~用户名 访问个人网页,需手动开启布尔值。
bash
# 1. 修改apache用户目录配置
vim /etc/httpd/conf.d/userdir.conf
# 注释:UserDir disabled
# 开启:UserDir public_html
# 2. 重启httpd服务
systemctl restart httpd
# 3. 客户端创建网页文件
su - student
mkdir ~/public_html
echo 'This is student content on SERVERA.' > ~/public_html/index.html
chmod 711 ~
# 4. 永久开启家目录访问权限
setsebool -P httpd_enable_homedirs on
五、SELinux 端口标签管理
5.1 端口标签原理
SELinux 通过端口标签绑定服务,仅允许服务绑定对应标签的端口。若服务监听非标准端口,标签不匹配会直接启动失败、提示 Permission denied。
例:httpd 仅允许绑定 http_port_t 标签端口(80、443、8080等)
5.2 端口标签核心命令
bash
# 查看所有SELinux端口标签
semanage port -l
# 过滤http服务端口
semanage port -l | grep http
# 新增端口标签(允许httpd监听82/tcp)
semanage port -a -t http_port_t -p tcp 82
# 修改已有端口标签
semanage port -m -t http_port_t -p tcp 71
# 删除端口标签
semanage port -d -t gopher_port_t -p tcp 71
# 查看自定义端口策略
semanage port -l -C
5.3 实战:httpd 监听非标准82端口
bash
# 1. 修改httpd监听端口
vim /etc/httpd/conf/httpd.conf
Listen 82
# 2. 重启服务(默认失败,SELinux拦截)
systemctl restart httpd
# 3. 配置SELinux端口放行
semanage port -a -t http_port_t -p tcp 82
# 4. 放行防火墙端口
firewall-cmd --permanent --add-port=82/tcp
firewall-cmd --reload
# 5. 重启服务验证
systemctl restart httpd
curl http://localhost:82
六、SELinux 故障排查全套方案
6.1 故障日志文件
-
审计原始日志:
/var/log/audit/audit.log(记录所有AVC拦截事件) -
简化提示日志:
/var/log/messages(携带UUID排错ID)
6.2 核心排错工具
bash
# 安装监控SELinux违规软件
yum install -y setroubleshoot-server
# 全自动分析所有SELinux报错,给出修复方案
sealert -a /var/log/audit/audit.log
# 根据UUID精准排查单条错误
sealert -l 你的UUID
# 筛选近期所有SELinux拦截记录
ausearch -m AVC -ts recent
6.3 经典故障与修复
6.3.1 网站403访问拒绝
原因:文件上下文标签错乱,非 httpd_sys_content_t
修复:restorecon -Rv 网站根目录
6.3.2 服务无法绑定自定义端口
原因:端口无对应服务SELinux标签
修复:使用 semanage port 绑定对应端口类型
6.3.3 无法访问用户家目录网页
原因:httpd家目录访问布尔值默认关闭
修复:setsebool -P httpd_enable_homedirs on
七、总结(运维必背)
-
SELinux 是内核级MAC强制安全机制,默认拒绝一切未授权访问
-
模式管理:
getenforce查看、setenforce 0/1临时改、配置文件永久改 -
文件上下文:临时chcon、永久semanage+fcontext、restorecon恢复默认
-
布尔值:微调服务权限,-P 参数实现永久生效
-
端口标签:非标准端口启动失败,优先排查SELinux端口策略
-
排错核心:
sealert一键分析日志,99%问题自动给出修复命令
💡 生产最佳实践:只放行必要权限,绝不直接关闭SELinux,临时排错可设宽容模式,修复后立刻切回强制模式!