在企业级 Linux 系统中,SELinux(Security-Enhanced Linux)是防止越权访问的"终极防线"。它由美国国家安全局(NSA)开发,openEuler 作为企业级发行版,默认启用 SELinux 提供强制访问控制(MAC),远超传统的自主访问控制(DAC)。本章将带你从零理解 SELinux 的核心概念,掌握日常管理命令,让你在享受安全防护的同时,不再被"SELinux 拒绝访问"所困扰。
🌟 本章目标
- 理解 SELinux 的基本原理与强制访问控制(MAC)机制
- 掌握 SELinux 的三种运行模式:enforcing、permissive、disabled
- 使用
sestatus、getenforce查看 SELinux 状态 - 理解安全上下文(Security Context)与文件标签
- 使用
ls -Z、chcon、restorecon管理文件上下文 - 使用
semanage管理端口、布尔值与策略 - 实战:修复因 SELinux 导致的 Web 服务无法启动问题
17.1 什么是 SELinux?
SELinux(Security-Enhanced Linux) 是 Linux 内核的一个安全模块,提供 强制访问控制(Mandatory Access Control, MAC),即使 root 用户也不能绕过。
✅ 传统 DAC vs SELinux MAC
| 机制 | 自主访问控制(DAC) | 强制访问控制(MAC) |
|---|---|---|
| 权限模型 | 用户/组/其他 + rwx | 用户:角色:类型:级别 |
| 谁能改权限 | 文件所有者 | 策略定义,用户不能随意更改 |
| root 权限 | root 可以访问一切 | root 也受策略限制 |
| 安全级别 | 基础防护 | 高强度隔离 |
💬 类比:
- DAC = 房间门锁,主人可以给任何人钥匙
- SELinux = 门禁系统,即使有钥匙,也要看权限卡是否允许进入
17.2 SELinux 运行模式
SELinux 有三种运行模式,可通过 /etc/selinux/config 永久设置。
🔧 三种模式
| 模式 | 说明 | 命令 |
|---|---|---|
| enforcing | 强制模式:拒绝违规操作并记录日志(默认) | setenforce 1 |
| permissive | 宽容模式:允许所有操作,但记录违规(调试用) | setenforce 0 |
| disabled | 禁用模式:完全关闭 SELinux(不推荐) | 修改配置文件 |
🔍 查看 SELinux 状态
bash
sestatus
输出示例:
SELinux status: enabled
SELinuxfs mount: /sys/fs/selinux
SELinux root directory: /etc/selinux
Loaded policy name: targeted
Current mode: enforcing
Mode from config file: enforcing
Policy MLS status: enabled
...
🛠️ 临时切换模式
bash
sudo setenforce 0 # 切换到 permissive
sudo setenforce 1 # 切换回 enforcing
⚠️
setenforce不能将 disabled 模式启用,只能在 enabled 状态下切换 enforcing/permissive。
📦 永久修改模式
编辑配置文件:
bash
sudo vim /etc/selinux/config
修改:
ini
SELINUX=enforcing # 可选:enforcing, permissive, disabled
SELINUXTYPE=targeted # 策略类型,保持默认
⚠️ 修改后需重启机器(reboot)生效。
17.3 安全上下文(Security Context)
SELinux 通过为每个进程、文件、端口打上"标签"(即安全上下文)来控制访问。
查看安全上下文
bash
ls -Z
示例:
bash
ls -Z /etc/passwd
# 输出:system_u:object_r:passwd_file_t:s0 /etc/passwd
格式:用户:角色:类型:级别
| 部分 | 说明 |
|---|---|
system_u |
SELinux 用户(不是 Linux 用户) |
object_r |
角色(object role) |
passwd_file_t |
类型(Type) --- 最关键,决定谁能访问 |
s0 |
多级安全(MLS)级别 |
常见文件类型示例
| 类型 | 用途 |
|---|---|
httpd_sys_content_t |
Apache 可读的网页文件 |
httpd_sys_script_exec_t |
Apache 可执行的 CGI 脚本 |
ssh_home_t |
用户家目录下的 SSH 文件 |
var_log_t |
日志文件 |
bin_t |
可执行程序 |
17.4 管理文件上下文
🔧 临时修改:chcon
bash
# 将文件类型改为 httpd 可读
sudo chcon -t httpd_sys_content_t /var/www/html/index.html
-t:指定类型-u:用户-r:角色
⚠️
chcon的修改是临时的,restorecon或make relabel会覆盖。
🧼 恢复默认上下文:restorecon
bash
# 恢复单个文件
sudo restorecon /var/www/html/index.html
# 递归恢复目录
sudo restorecon -R /var/www/html/
# 查看将要恢复的内容(不执行)
sudo restorecon -nR /var/www/html/
✅ 推荐:修改文件后使用
restorecon而非chcon
📁 查看默认上下文规则
bash
semanage fcontext -l | grep /var/www
输出:
/var/www(/.*)? all files system_u:object_r:httpd_sys_content_t:s0
说明:所有 /var/www 下的文件默认应为 httpd_sys_content_t 类型。
17.5 使用 semanage 管理 SELinux
semanage 是 SELinux 的高级管理工具,需安装:
bash
sudo dnf install -y policycoreutils-python-utils
🔌 管理端口
Web 服务默认只能绑定 80、443、8080 等端口。若你使用 8081,需添加:
bash
# 添加 HTTP 服务可绑定的端口
sudo semanage port -a -t http_port_t -p tcp 8081
# 查看
sudo semanage port -l | grep http
# 删除
sudo semanage port -d -t http_port_t -p tcp 8081
🎚️ 管理布尔值(Booleans)
布尔值用于开启/关闭某些 SELinux 策略行为。
查看所有布尔值
bash
getsebool -a | grep http
常见布尔值:
httpd_can_network_connect:允许 Apache 连接网络httpd_enable_homedirs:允许 Apache 读取用户家目录allow_ssh_keysign:允许 SSH 使用密钥签名
修改布尔值
bash
# 临时生效
setsebool httpd_can_network_connect on
# 永久生效
setsebool -P httpd_can_network_connect on
-P表示永久保存,重启后仍有效。
17.6 实战:修复 SELinux 导致的服务无法启动
场景
你将 Nginx 的网站根目录设为 /data/web,但启动失败。
bash
sudo systemctl start nginx
Job for nginx.service failed...
排查步骤
1. 查看服务状态
bash
systemctl status nginx
可能无明确错误。
2. 查看 SELinux 拒绝日志
bash
sudo ausearch -m avc -ts recent
或:
bash
sudo grep "denied" /var/log/audit/audit.log | tail -5
输出:
type=AVC msg=audit(1712345678.123:456): avc: denied { read } for pid=1234 comm="nginx" name="index.html" dev="sda1" ino=5678 scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:default_t:s0 tclass=file
✅ 说明:Nginx (httpd_t) 被拒绝读取文件(类型为 default_t)
3. 修复文件上下文
bash
# 临时修复
sudo chcon -R -t httpd_sys_content_t /data/web/
# 或永久修复(推荐)
sudo semanage fcontext -a -t httpd_sys_content_t "/data/web(/.*)?"
sudo restorecon -R /data/web/
4. 重新启动服务
bash
sudo systemctl start nginx
systemctl status nginx
✅ 服务成功启动!
✅ 本章小结
| 命令 | 用途 | 示例 |
|---|---|---|
sestatus |
查看 SELinux 状态 | |
setenforce 0/1 |
临时切换模式 | |
ls -Z |
查看安全上下文 | ls -Z /etc/passwd |
chcon |
临时修改上下文 | chcon -t httpd_t file |
restorecon |
恢复默认上下文 | restorecon -R /var/www/ |
semanage fcontext |
永久设置上下文规则 | 添加 /data/web 规则 |
semanage port |
管理端口标签 | 开放 8081 给 httpd |
setsebool -P |
永久启用布尔值 | httpd_can_network_connect |
📝 课后练习
- 运行
sestatus查看当前 SELinux 模式。 - 使用
ls -Z查看/etc/shadow的安全上下文。 - 创建一个目录
/testweb,放入index.html,尝试用 Nginx 服务访问(会失败)。 - 使用
ausearch或grep audit.log查看 SELinux 拒绝记录。 - 使用
semanage fcontext和restorecon修复上下文,使 Nginx 可访问。 - (挑战)将 Nginx 配置为监听 8081 端口,并使用
semanage port添加该端口到http_port_t。
🔜 下一章预告:第18章《Shell 脚本编程基础》
我们将学习:
- 什么是 Shell 脚本?为何要写脚本
- 脚本结构:
#!/bin/bash与执行方式 - 变量定义与使用(环境变量、位置参数)
- 条件判断:
if、test、[ ]、[[ ]] - 循环:
for、while、until - 函数定义与调用
- 实战:编写系统监控脚本
准备好从"命令行用户"升级为"自动化工程师"了吗?