7.5 RHCSA 备考:SELinux 配置
预计阅读时间:22 分钟
📖 目录
SELinux(Security-Enhanced Linux,安全增强型 Linux)是 RHCSA 考试的必考内容,也是 RHEL 与 Ubuntu 最重要的区别之一。考试要求能修改 SELinux 模式、管理文件上下文和布尔值、以及排查 SELinux 导致的故障。几乎每场 RHCSA 考试都会有 1-2 道 SELinux 相关题目,通常以故障排查场景出现。
学习目标
- 理解 SELinux 三种工作模式(Enforcing/Permissive/Disabled)的区别与切换方法
- 掌握文件上下文(context)的查看、修改和恢复方法
- 熟练管理 SELinux 布尔值(boolean)来控制服务访问权限
- 能够通过审计日志和 sealert 命令排查 SELinux 导致的服务故障
前置知识
- 1.7:用户与权限管理 用户与权限管理——传统权限模型,对比理解 MAC 与 DAC
- 5.1:Linux 安全加固 Linux 安全加固——安全机制整体视角
- 5.6:SELinux 与 AppArmor SELinux 与 AppArmor——SELinux 在启动阶段的作用
考试要点
| 考点 | 权重 | 典型题目 |
|---|---|---|
| SELinux 模式切换 | 15% | 将 SELinux 设为 Permissive 或 Enforcing |
| 文件上下文管理 | 30% | 为自定义目录设置正确的 SELinux context |
| 布尔值管理 | 25% | 开启 httpd_enable_homedirs 等布尔值 |
| 故障排查 | 20% | 排查服务因 SELinux 启动失败的问题 |
| 端口标签 | 10% | 为非标准端口设置 SELinux 端口标签 |
1. SELinux 模式管理
# 查看当前模式
getenforce
# 预期输出:Enforcing
/usr/sbin/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
# 临时切换(立即生效,重启恢复)
sudo setenforce 0 # Permissive(只记录,不阻止)
sudo setenforce 1 # Enforcing(强制阻止)
# 永久修改(需重启)
# 编辑 /etc/selinux/config
sudo sed -i 's/SELINUX=enforcing/SELINUX=permissive/' /etc/selinux/config
# 三种模式的区别:
# Enforcing - 强制策略,违规操作被阻止并记录
# Permissive - 只记录违规日志,不阻止操作
# Disabled - 完全关闭(不推荐,标签可能丢失)
模式切换注意事项
- 从 Disabled 切换到 Enforcing:需要重启系统,因为文件系统需要重新打标签
- 考试中不要随意禁用 SELinux:这可能导致后续题目无法正常进行
- 临时切换到 Permissive 是排查问题的第一步:如果关闭后服务正常,说明是 SELinux 问题
- 查看当前配置文件:
cat /etc/selinux/config
三种模式对比
| 模式 | 配置值 | 策略执行 | 日志记录 | 考试建议 |
|---|---|---|---|---|
| Enforcing | enforcing | 阻止违规操作 | 记录到 audit.log | 考试默认模式,保持不变 |
| Permissive | permissive | 仅警告,不阻止 | 记录到 audit.log | 排查问题时临时使用 |
| Disabled | disabled | 完全关闭 | 不记录 | 不推荐:重启后需全盘重新打标签 |
核心机制:SELinux 采用"类型强制"(Type Enforcement)——每个进程有"域"(domain),每个文件有"类型"(type),只有策略允许的域-类型组合才能访问。这是 MAC(强制访问控制)区别于传统 DAC(自主访问控制)的关键。
2. 文件上下文管理
每个文件/目录都有 SELinux context(用户:角色:类型:级别)。
# 查看 context
ls -Z /var/www/html/index.html
# 输出:system_u:object_r:httpd_sys_content_t:s0 index.html
ps auxZ | grep httpd # 查看进程 context
# 修改 context(restorecon 方式——推荐)
sudo chcon -t httpd_sys_content_t /var/www/html/index.html
sudo restorecon -v /var/www/html/index.html # 恢复到策略默认
# 递归恢复目录
sudo restorecon -Rv /var/www/html/
# 使用 semanage 修改默认 context(新文件自动继承)
sudo semanage fcontext -a -t httpd_sys_content_t "/custom/web(/.*)?"
sudo restorecon -Rv /custom/web/
Context 各字段含义
| 字段 | 含义 | 示例 |
|---|---|---|
| 用户 | SELinux 用户身份 | system_u |
| 角色 | 访问角色 | object_r(文件)、system_r(进程) |
| 类型 | 最核心字段,决定访问权限 | httpd_sys_content_t |
| 级别 | MLS/MCS 安全级别 | s0 |
常见文件 Context 类型
| 类型 | 用途 |
|---|---|
| httpd_sys_content_t | Web 服务器可读内容 |
| httpd_sys_script_exec_t | CGI 脚本 |
| httpd_log_t | Web 服务器日志 |
| ssh_home_t | SSH 用户 home 目录 |
| user_home_t | 普通用户 home 目录 |
| admin_home_t | 管理员 home 目录 |
3. 查看默认 context 映射
# 查看所有文件 context 映射
sudo semanage fcontext -l
# 查询特定路径的默认 context
sudo semanage fcontext -l | grep /var/www
sudo semanage fcontext -l | grep /home
# 注意:/var/www 有两个重要路径
# /var/www(/.*)? → httpd_sys_content_t(默认 Web 内容)
# /var/www/html(/.*)? → httpd_sys_content_t(Apache 文档根目录)
4. SELinux 布尔值
布尔值是 SELinux 规则的开关,用于微调策略。这是考试常考的内容。
# 查看所有布尔值
getsebool -a
# 查看特定布尔值
getsebool httpd_enable_homedirs
# httpd_enable_homedirs --> off
# 设置布尔值(临时)
sudo setsebool httpd_enable_homedirs on
# 永久生效(重启后保留)
sudo setsebool -P httpd_enable_homedirs on
# 用 semanage 方式查看布尔值详情
sudo semanage boolean -l | grep httpd
考试常考布尔值
| 布尔值 | 功能 | 默认 |
|---|---|---|
| httpd_enable_homedirs | 允许 httpd 访问用户 home 目录 | off |
| httpd_can_network_connect | 允许 httpd 发起网络连接 | off |
| httpd_can_network_connect_db | 允许 httpd 连接数据库 | off |
| httpd_execmem | 允许 httpd 执行内存中的代码 | off |
| httpd_use_nfs | 允许 httpd 使用 NFS 挂载的文件 | off |
| ftpd_full_access | 允许 FTP 完全访问 | off |
| sftpd_write_dirs | 允许 SFTP 写入目录 | off |
5. 排查 SELinux 故障
# 当服务因 SELinux 启动失败时:
# 1. 临时切换 Permissive 模式确认问题
sudo setenforce 0
# 重试服务启动——如果成功,说明是 SELinux 阻止
# 2. 查看审计日志
sudo ausearch -m avc -ts recent
sudo journalctl -t setroubleshoot | tail -30
sudo grep "SELinux" /var/log/messages | tail -20
# 3. 使用 sealert 获取修复建议(最快捷)
sudo sealert -a /var/log/audit/audit.log | tail -50
# 4. 生成自定义策略模块
sudo grep "denied" /var/log/audit/audit.log | audit2allow -M mymod
sudo semodule -i mymod.pp
故障排查流程图
- 服务启动失败 → 执行
setenforce 0切换 Permissive - 重试操作 → 如果成功,确认是 SELinux 问题
- 执行
ausearch -m avc -ts recent查看被拒绝的操作 - 根据 sealert 建议选择修复方式:
- 如果需要修改文件 context →
chcon或restorecon - 如果需要修改端口标签 →
semanage port - 如果需要修改布尔值 →
setsebool -P - 如果以上都不适用 → 生成自定义策略模块
- 如果需要修改文件 context →
- 切回 Enforcing:
setenforce 1 - 验证服务正常运行
6. semanage 常用命令速查
# 管理文件上下文
sudo semanage fcontext -a -t httpd_sys_content_t "/path(/.*)?"
sudo semanage fcontext -d -t httpd_sys_content_t "/path(/.*)?"
# 管理端口上下文(为非标准端口打标签)
sudo semanage port -a -t http_port_t -p tcp 8080
sudo semanage port -l | grep http
# 管理布尔值
sudo semanage boolean -l
sudo semanage boolean --modify --on httpd_enable_homedirs
# 管理登录用户上下文映射
sudo semanage login -l
semanage 端口标签详解
如果服务需要监听非标准端口,必须为该端口设置 SELinux 端口标签,否则 SELinux 会阻止:
# 查看当前 http 相关端口标签
sudo semanage port -l | grep http_port_t
# 为 8080 端口添加 http 标签
sudo semanage port -a -t http_port_t -p tcp 8080
# 修改已有端口标签
sudo semanage port -m -t http_port_t -p tcp 8080
# 删除端口标签
sudo semanage port -d -t http_port_t -p tcp 8080
考试中常见的 SELinux 场景
| 场景 | SELinux 配置 |
|---|---|
| Nginx/Apache 文档目录移到非标准位置 | semanage fcontext + restorecon |
| Web 服务器需要访问用户 home 目录 | setsebool -P httpd_enable_homedirs on |
| 服务监听非标准端口 | semanage port -a -t 对应类型 -p tcp 端口 |
| NFS 文件系统上运行的脚本需要执行权限 | setsebool -P httpd_execmem on(视情况) |
| FTP 用户需要写入特定目录 | setsebool -P ftpd_full_access on + 修改目录 context |
7. 完整配置案例:把自建服务部署到非标准位置
真实场景:运维要把自研 Web 服务部署在 8080 端口、/opt/app/web 目录(以 httpd 为例)。非标准目录 + 非标准端口会同时踩中文件上下文和端口标签两个坑,正好覆盖 semanage 的两大核心功能。
步骤 1:准备目录与服务(先复现故障)
sudo mkdir -p /opt/app/web
echo "<h1>Internal App</h1>" | sudo tee /opt/app/web/index.html
sudo vi /etc/httpd/conf/httpd.conf
# DocumentRoot "/opt/app/web"
# Listen 8080
sudo systemctl start httpd
# 启动失败 —— 正是我们要复现的故障
步骤 2:定位失败原因(两个坑逐一排除)
# 坑 1:SELinux 阻止 httpd 绑定 8080 端口
sudo ausearch -m avc -ts recent | grep denied | tail -3
# type=AVC msg=audit(...): avc: denied { name_bind } for pid=... comm="httpd"
# scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:system_r:httpd_t:s0
# tclass=tcp_socket
# 坑 2:/opt/app/web 的上下文是 default_t,httpd 无权读取
ls -Z /opt/app/web
# system_u:object_r:default_t:s0 index.html
步骤 3:semanage 永久修复(端口标签 + 文件上下文)
# 端口标签:把 8080 登记为 http_port_t
sudo semanage port -a -t http_port_t -p tcp 8080
# 文件上下文:注册 /opt/app/web 的默认类型,并用 restorecon 落地
sudo semanage fcontext -a -t httpd_sys_content_t "/opt/app/web(/.*)?"
sudo restorecon -Rv /opt/app/web
# Relabeled /opt/app/web (system_u:object_r:default_t:s0) -> system_u:object_r:httpd_sys_content_t:s0
# Relabeled /opt/app/web/index.html (system_u:object_r:default_t:s0) -> system_u:object_r:httpd_sys_content_t:s0
步骤 4:启动并验证
sudo systemctl start httpd
curl http://localhost:8080/
# <h1>Internal App</h1>
# 持久性验证:semanage 写入策略数据库,reboot 后端口标签与目录上下文都保留
8. 故障案例:httpd 无法读取 /data/web 目录
现象
# DocumentRoot 指向 /data/web 后,httpd 正常启动,但浏览器与 curl 都返回 403
curl http://localhost/
# 403 Forbidden
# 日志中常见:Permission denied: AH00035: access to / denied
排查流程
# 1. 先确认传统权限没问题
ls -ld /data/web && ls -lZ /data/web/index.html
# drwxr-xr-x 2 root root 24 ... /data/web
# -rw-r--r-- 1 root root 20 ... index.html ← 注意没有 -Z 之前的类型检查
# 2. 用 setenforce 0 快速验证是否 SELinux 在阻止
sudo setenforce 0
curl http://localhost/ # 立即返回 200 —— 确认是 SELinux 问题
sudo setenforce 1 # 立刻恢复,不要留着
# 3. ausearch 定位被拒绝的具体操作
sudo ausearch -m avc -ts recent | grep httpd | tail -5
# type=AVC msg=audit(...): avc: denied { getattr } for pid=... comm="httpd"
# path="/data/web/index.html" dev="sda1" ino=...
# scontext=system_u:system_r:httpd_t:s0
# tcontext=system_u:object_r:default_t:s0 tclass=file
# 关键信息:httpd_t 进程试图访问 default_t 类型的文件 → 类型不匹配
# 4. 修复:注册默认上下文并 restorecon 落地
sudo semanage fcontext -a -t httpd_sys_content_t "/data/web(/.*)?"
sudo restorecon -Rv /data/web
# Relabeled /data/web/index.html from default_t to httpd_sys_content_t
# 5. 验证
sudo systemctl restart httpd
curl http://localhost/
# 200 OK
9. 常用策略布尔值速查表
布尔值是 SELinux 最"人性化"的部分:不需要懂策略语言,一个开关解决一类问题。以下是三类服务最常涉及的布尔值,考前过一遍。
httpd(Web 服务)
| 布尔值 | 功能 | 默认 | 开启命令 |
|---|---|---|---|
| httpd_enable_homedirs | 允许 httpd 读取用户 home 目录 | off | setsebool -P httpd_enable_homedirs on |
| httpd_can_network_connect | 允许 httpd 发起对外 TCP 连接(反向代理场景) | off | setsebool -P httpd_can_network_connect on |
| httpd_can_network_connect_db | 允许 httpd 连接数据库端口 | off | setsebool -P httpd_can_network_connect_db on |
| httpd_graceful_shutdown | 允许 httpd 平滑关闭相关操作 | off | setsebool -P httpd_graceful_shutdown on |
| httpd_execmem | 允许 httpd 执行可写内存(部分 PHP 加速器需要) | off | setsebool -P httpd_execmem on |
| httpd_use_nfs | 允许 httpd 使用 NFS 挂载的内容 | off | setsebool -P httpd_use_nfs on |
ssh(远程登录)
| 布尔值 | 功能 | 默认 | 开启命令 |
|---|---|---|---|
| ssh_sysadm_login | 允许 sshd 处理系统管理员角色的登录 | off | setsebool -P ssh_sysadm_login on |
| ssh_chroot_rw_homedirs | 允许 chroot 后的用户写 home 目录(SFTP jail) | off | setsebool -P ssh_chroot_rw_homedirs on |
| use_nfs_home_dirs | 允许用户通过 NFS 挂载的 home 登录 | off | setsebool -P use_nfs_home_dirs on |
| use_samba_home_dirs | 允许用户通过 Samba 共享的 home 登录 | off | setsebool -P use_samba_home_dirs on |
samba(文件共享)
| 布尔值 | 功能 | 默认 | 开启命令 |
|---|---|---|---|
| samba_export_all_rw | 允许 Samba 导出所有可读写文件 | off | setsebool -P samba_export_all_rw on |
| samba_export_all_ro | 允许 Samba 导出所有只读文件 | off | setsebool -P samba_export_all_ro on |
| smbd_anon_write | 允许 smbd 写匿名用户可写目录 | off | setsebool -P smbd_anon_write on |
| samba_create_home_dirs | 允许 Samba 自动创建用户 home 目录 | off | setsebool -P samba_create_home_dirs on |
semanage boolean -l | grep 服务名 现查;重点是开启必须加 -P 才会持久化。
常见错误
| 常见错误 | 原因分析 | 解决方法 |
|---|---|---|
| chcon 修改的 context 重启后丢失 | chcon 是临时修改,restorecon 会覆盖 | 使用 semanage fcontext 添加持久规则 |
| semanage 命令报错 | 未安装 policycoreutils-python-utils | sudo dnf install policycoreutils-python-utils |
| 布尔值设置后不生效 | 未加 -P 参数,重启后恢复默认 | 使用 setsebool -P 永久生效 |
| 服务在 Permissive 模式正常,Enforcing 失败 | SELinux 策略阻止了服务操作 | 查看审计日志,修复 context 或布尔值 |
| 自定义策略模块不生效 | 未重新加载策略或策略有语法错误 | semodule -i mymod.pp && setenforce 1 |
实操练习
练习 1:为自定义 Web 目录设置 SELinux 上下文
将 Apache 文档根目录迁移到 /data/web,配置正确的 SELinux context。
# 创建目录并复制文件
sudo mkdir -p /data/web
sudo cp /var/www/html/index.html /data/web/
# 设置 SELinux 上下文(持久化)
sudo semanage fcontext -a -t httpd_sys_content_t "/data/web(/.*)?"
sudo restorecon -Rv /data/web/
# 验证
ls -Z /data/web/index.html
# 应显示 httpd_sys_content_t
# 测试 Apache 是否能正常访问
curl http://localhost/
练习 2:配置非标准端口的 Web 服务
让 Apache 监听 8080 端口,配置 SELinux 允许此操作。
# 修改 Apache 配置
echo "Listen 8080" | sudo tee /etc/httpd/conf.d/ports.conf
# 设置端口标签
sudo semanage port -a -t http_port_t -p tcp 8080
# 启动服务
sudo systemctl start httpd
# 验证
curl http://localhost:8080/
练习 3:排查 SELinux 阻止的文件访问
模拟 Apache 无法访问非标准目录的故障并修复。
# 创建目录(不设置 context)
sudo mkdir -p /srv/www
echo "test" | sudo tee /srv/www/index.html
# 修改 Apache 配置指向新目录(假设已修改 DocumentRoot)
# 启动 Apache(应失败或报错)
# 排查
sudo ausearch -m avc -ts recent
sudo sealert -a /var/log/audit/audit.log
# 修复
sudo semanage fcontext -a -t httpd_sys_content_t "/srv/www(/.*)?"
sudo restorecon -Rv /srv/www/
sudo systemctl restart httpd
练习 4:管理 SELinux 布尔值
查看所有 httpd 相关布尔值,开启需要的布尔值,并验证。
# 查看所有 httpd 布尔值
sudo semanage boolean -l | grep httpd
# 开启需要的布尔值
sudo setsebool -P httpd_enable_homedirs on
sudo setsebool -P httpd_can_network_connect on
# 验证
getsebool httpd_enable_homedirs
getsebool httpd_can_network_connect
模拟题
题目 1
系统的 Apache 服务器文档根目录已从 /var/www/html 迁移到 /home/web。请配置正确的 SELinux 上下文,确保 Apache 能正常读取新目录中的文件。
参考答案:sudo semanage fcontext -a -t httpd_sys_content_t "/home/web(/.*)?" → sudo restorecon -Rv /home/web → ls -Z /home/web 确认 httpd_sys_content_t → sudo systemctl restart httpd → curl http://localhost/ 验证。关键:不能只用 chcon(临时),必须用 semanage 写入持久化规则。
题目 2
系统处于 Enforcing 模式。管理员使用 chcon 修改了 /srv/web 下所有文件的 context 为 httpd_sys_content_t,服务恢复正常,但重启后故障复现。请解释原因并给出正确做法。
参考答案:chcon 是临时修改,不写入策略数据库;系统重启后 restorecon(或自动 relabel)会按默认映射把文件 context 恢复原状。正确做法:sudo semanage fcontext -a -t httpd_sys_content_t "/srv/web(/.*)?" 写入持久化规则,再 sudo restorecon -Rv /srv/web 落地。此后新建文件也会自动获得该类型。
题目 3
系统的 Nginx 服务器无法访问 /data/uploads 目录中的文件,SELinux 处于 Enforcing 模式。请排查问题并修复,要求记录排查过程。
参考答案:① sudo setenforce 0 → curl http://localhost/uploads/file 成功 → 确认是 SELinux 问题 → sudo setenforce 1 恢复;② sudo ausearch -m avc -ts recent | grep nginx 查看被拒绝操作,关键信息 tcontext=system_u:object_r:default_t:s0;③ 修复:sudo semanage fcontext -a -t httpd_sys_content_t "/data/uploads(/.*)?" → sudo restorecon -Rv /data/uploads → sudo systemctl restart nginx → curl http://localhost/uploads/file 验证。
题目 4
httpd 需要反向代理到内网 10.0.0.10:8080,但访问时报 502。传统权限与网络均正常。请写出完整的 SELinux 排查与修复过程。
参考答案:这是典型的"出站连接被拦":sudo setenforce 0 临时验证(恢复 200 即确认);sudo ausearch -m avc -ts recent | grep httpd 查看 connect 相关拒绝记录;修复:sudo setsebool -P httpd_can_network_connect on(若目标端口是数据库如 3306,用 httpd_can_network_connect_db)。最后 sudo setenforce 1 并重启 httpd 验证。
题目 5
把 httpd 的监听端口改为 8081 后服务无法启动。如何让 SELinux 放行?写出命令并说明与 fcontext 修复的区别。
参考答案:sudo semanage port -a -t http_port_t -p tcp 8081 为端口打标签,然后 sudo systemctl start httpd。区别:端口标签针对的是网络服务绑定行为(semanage port),fcontext 针对的是文件访问类型(semanage fcontext);二者都是持久化策略,但作用对象完全不同。验证:sudo semanage port -l | grep 8081。
题目 6
管理员想临时关闭 SELinux 排查问题。写出正确的临时关闭与恢复命令,并说明为什么禁用模式(disabled)不可取。
参考答案:临时关闭:sudo setenforce 0(Permissive,只记录不阻止);恢复:sudo setenforce 1。不要编辑 /etc/selinux/config 改成 disabled,因为:① 需要重启才生效;② 从 disabled 切回 enforcing 时必须对全盘重新打标签(重启时自动 relabel,耗时且可能失败);③ 考试中禁用 SELinux 直接扣分。Permissive 模式就足够确认问题归属。
题目 7
审计日志显示 httpd 尝试访问 /var/www/html/private/data.db 被拒绝,但该文件权限是 644。可能的 SELinux 原因有哪些?如何确定是哪一种?
参考答案:三种可能:① 文件 context 类型不对(如被 chcon 改成其他类型,需 restorecon);② 目录 context 不对(httpd 需要目录有 x 权限与正确类型 httpd_sys_content_t);③ 进程域被布尔值/自定义策略限制(较少见)。确定方法:ls -Z /var/www/html/private/data.db 检查类型;restorecon -v 看是否被修正;再看 ausearch -m avc 的 tcontext 是否与预期一致。修复按类型不符→restorecon/semanage,布尔值不符→setsebool 的顺序处理。
题目 8
通过 SFTP 登录的用户无法写入自己的 home 目录(chroot 场景),权限为 700 且属主正确。SELinux 需要开启哪个布尔值?写出命令。
参考答案:sudo setsebool -P ssh_chroot_rw_homedirs on。chroot 环境下 sshd 需要额外放行对 home 目录的写操作;同时确认 home 目录 context 为 ssh_home_t(ls -Zd ~user 检查),类型不对时 restorecon -Rv /home/用户 修正。
题目 9
管理员需要查看当前系统所有 httpd 相关布尔值及其默认状态,并确认某布尔值是否持久化。写出命令。
参考答案:查看:getsebool -a | grep httpd 或 sudo semanage boolean -l | grep httpd(后者带默认值与描述);确认持久化:布尔值文件在 /etc/selinux/targeted/booleans,cat /etc/selinux/targeted/booleans | grep httpd 显示持久值;或直接 getsebool httpd_enable_homedirs 看当前生效值。注意 setsebool 不带 -P 只改当前值,重启即回默认。
题目 10
FTP 服务需要允许匿名用户上传文件到 /var/ftp/pub/uploads 目录。请配置 SELinux 布尔值和文件上下文,确保 FTP 服务正常工作。
参考答案:配置布尔值:sudo setsebool -P ftpd_full_access on(允许 FTP 完全访问);sudo setsebool -P ftpd_anon_write on(允许匿名写入)。创建目录并设置上下文:sudo mkdir -p /var/ftp/pub/uploads;sudo semanage fcontext -a -t public_content_rw_t "/var/ftp/pub/uploads(/.*)?";sudo restorecon -Rv /var/ftp/pub/uploads。验证:ls -Z /var/ftp/pub/uploads 确认 public_content_rw_t;getsebool ftpd_full_access 确认 on。
题目 11
系统中 /srv/custom-web 目录存放自定义 Web 应用文件,Apache 无法读取。请排查 SELinux 问题,要求:① 确认是 SELinux 问题;② 查看被拒绝的操作;③ 持久化修复并验证。
参考答案:① sudo setenforce 0 → curl http://localhost/ 成功 → sudo setenforce 1 恢复 → 确认是 SELinux 问题。② sudo ausearch -m avc -ts recent | grep httpd | tail -5,关键信息 tcontext=default_t。③ 修复:sudo semanage fcontext -a -t httpd_sys_content_t "/srv/custom-web(/.*)?" → sudo restorecon -Rv /srv/custom-web → sudo systemctl restart httpd → curl http://localhost/ 验证 200 OK。关键:必须用 semanage 写入持久化规则,不能只用 chcon。
题目 12
系统运行 PostgreSQL 数据库,Apache 需要通过 PHP 连接本地 PostgreSQL(端口 5432)。请配置 SELinux 允许此操作,并说明需要开启的布尔值。
参考答案:需要开启 httpd_can_network_connect_db 布尔值,允许 httpd 连接数据库端口。命令:sudo setsebool -P httpd_can_network_connect_db on。验证:getsebool httpd_can_network_connect_db 确认 on。注意:如果 PostgreSQL 监听在非标准端口,还需确认端口标签正确:sudo semanage port -l | grep postgresql_port_t。如果需要 httpd 连接远程数据库(非本地),则使用 httpd_can_network_connect 而非 httpd_can_network_connect_db。
题目 13
管理员需要临时关闭 SELinux 进行调试,但又不想重启系统且不想丢失 SELinux 策略配置。请写出操作方案,并解释为什么 setenforce 0 比修改 config 文件更好。
参考答案:临时关闭:sudo setenforce 0(立即切换到 Permissive,重启后恢复 Enforcing);恢复:sudo setenforce 1。比修改 config 更好的原因:① setenforce 0 立即生效,不需要重启;② 重启后自动恢复到 Enforcing,不会改变系统永久配置;③ 修改 /etc/selinux/config 需要重启才生效,且从 disabled 切回 enforcing 需要全盘重新打标签(耗时且可能失败)。验证当前模式:getenforce;验证配置未修改:grep ^SELINUX= /etc/selinux/config 应仍为 enforcing。
完整配置案例 1:为自定义 Web 服务配置完整 SELinux 环境
任务背景:运维需要将自研监控系统部署在 9090 端口、/opt/monitor/web 目录,要求:① 配置文件上下文使 Apache 可读取新目录;② 配置端口标签使 Apache 可绑定 9090;③ 允许 Apache 连接本地 MySQL(3306 端口);④ 允许 Apache 读取用户 home 目录中的配置文件。
步骤 1:准备目录与配置文件
# 创建目录
sudo mkdir -p /opt/monitor/web
echo "<h1>Monitor Dashboard</h1>" | sudo tee /opt/monitor/web/index.html
# 创建 Apache 配置
echo "Listen 9090" | sudo tee /etc/httpd/conf.d/monitor.conf
echo "<VirtualHost *:9090>" | sudo tee -a /etc/httpd/conf.d/monitor.conf
echo " DocumentRoot /opt/monitor/web" | sudo tee -a /etc/httpd/conf.d/monitor.conf
echo "</VirtualHost>" | sudo tee -a /etc/httpd/conf.d/monitor.conf
步骤 2:配置端口标签(9090)
# 查看当前 http_port_t 标签
sudo semanage port -l | grep http_port_t
# http_port_t tcp 80, 81, 443, 488, 8008, 8009, 8443, 9000
# 添加 9090 端口标签
sudo semanage port -a -t http_port_t -p tcp 9090
# 验证
sudo semanage port -l | grep 9090
# http_port_t tcp 9090
步骤 3:配置文件上下文(/opt/monitor/web)
# 注册默认上下文
sudo semanage fcontext -a -t httpd_sys_content_t "/opt/monitor/web(/.*)?"
# 落地上下文
sudo restorecon -Rv /opt/monitor/web
# Relabeled /opt/monitor/web from default_t to httpd_sys_content_t
# Relabeled /opt/monitor/web/index.html from default_t to httpd_sys_content_t
# 验证
ls -Z /opt/monitor/web/
# system_u:object_r:httpd_sys_content_t:s0 index.html
步骤 4:配置布尔值
# 允许 httpd 连接本地 MySQL
sudo setsebool -P httpd_can_network_connect_db on
# 允许 httpd 读取用户 home 目录
sudo setsebool -P httpd_enable_homedirs on
# 验证
getsebool httpd_can_network_connect_db
# httpd_can_network_connect_db --> on
getsebool httpd_enable_homedirs
# httpd_enable_homedirs --> on
步骤 5:启动服务并验证
# 启动 Apache
sudo systemctl start httpd
sudo systemctl enable httpd
# 测试 Web 访问
curl http://localhost:9090/
# <h1>Monitor Dashboard</h1>
# 测试 MySQL 连接(假设 PHP 配置已就绪)
curl http://localhost:9090/db-test.php
# Database connected successfully
# 持久性验证:重启后所有 SELinux 配置应保留
sudo reboot
# 重启后
getenforce
# Enforcing
curl http://localhost:9090/
# <h1>Monitor Dashboard</h1>
完整配置案例 2:NFS 共享目录的 SELinux 配置
任务背景:NFS 服务器共享 /data/nfs-share 目录,客户端挂载到 /mnt/nfs-share,需要 Apache 读取该目录中的 Web 文件。配置 SELinux 使整个链路畅通。
步骤 1:服务端配置(NFS 共享)
# 创建共享目录
sudo mkdir -p /data/nfs-share
echo "NFS Content" | sudo tee /data/nfs-share/index.html
# 配置 exports
echo "/data/nfs-share 192.168.1.0/24(ro,sync,no_root_squash)" | sudo tee -a /etc/exports
sudo exportfs -ra
# 启动 NFS
sudo systemctl start nfs-server
sudo systemctl enable nfs-server
步骤 2:客户端挂载
# 挂载 NFS 共享
sudo mount -t nfs 192.168.1.100:/data/nfs-share /mnt/nfs-share
# 验证挂载
df -h /mnt/nfs-share
# 192.168.1.100:/data/nfs-share 10G 128M 9.9G 2% /mnt/nfs-share
步骤 3:配置 SELinux(关键步骤)
# 启用 NFS 访问布尔值
sudo setsebool -P httpd_use_nfs on
# 验证布尔值
getsebool httpd_use_nfs
# httpd_use_nfs --> on
# 检查挂载目录的上下文
ls -Zd /mnt/nfs-share
# system_u:object_r:nfs_t:s0 /mnt/nfs-share
# 注意:NFS 挂载的目录类型为 nfs_t,httpd 可以读取此类型
# 配置 Apache DocumentRoot 指向 NFS 挂载点
sudo vi /etc/httpd/conf.d/nfs.conf
# DocumentRoot "/mnt/nfs-share"
sudo systemctl restart httpd
curl http://localhost/
# NFS Content
httpd_use_nfs 布尔值获得对 nfs_t 类型的读取权限。如果关闭此布尔值,即使传统权限正确,httpd 也无法读取 NFS 文件。
最佳实践
- 排查 SELinux 问题时,先用
setenforce 0确认是否是 SELinux 问题,再用 sealert 获取修复建议 - 修改文件 context 优先使用
semanage fcontext+restorecon,而非chcon - 设置布尔值始终加
-P参数确保重启后生效 - 不要随意禁用 SELinux,考试中这是扣分项
- 熟悉
ausearch和sealert的输出格式,快速定位被拒绝的操作
验证 checklist
getenforce # 确认模式
ls -Z /var/www/html # 检查文件 context
getsebool httpd_enable_homedirs # 检查布尔值
sudo ausearch -m avc -ts recent # 检查最新审计事件
学习检查点
学完本章后,请检验自己是否掌握以下内容:
| 检查项 | 自测问题 | 验证方法 |
|---|---|---|
| 概念理解 | 能用自己的话解释 SELinux 的三种工作模式和上下文标签 | 尝试向他人讲解 |
| 命令操作 | 能不查文档完成 getenforce、setenforce、semanage 命令操作 | 在终端实际执行 |
| 原理掌握 | 能说出 SELinux 的强制访问控制和类型强制模型原理 | 画出流程图 |
| 故障排查 | 能独立排查 SELinux 阻止服务正常运行的问题 | 模拟故障并修复 |
| 最佳实践 | 能说明为什么不应该通过 setenforce 0 来"修复"问题 | 对比不同方案 |
本章总结
SELinux 是 RHCSA 最"反直觉"的考点,核心是理解"进程域-文件上下文"的配对关系。restorecon 与 semanage fcontext 是恢复/新增上下文的两把钥匙。排障三步:ausearch 找拒绝记录→audit2why 读原因→对症修复。考试中禁止 setenforce 0 一关了之。
延伸阅读
- 5.6:SELinux 与 AppArmor SELinux 与 AppArmor——强制访问控制
- 5.13:auditd 审计 auditd 审计系统