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 导致的服务故障

前置知识

考试要点

考点权重典型题目
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

三种模式对比

模式配置值策略执行日志记录考试建议
Enforcingenforcing阻止违规操作记录到 audit.log考试默认模式,保持不变
Permissivepermissive仅警告,不阻止记录到 audit.log排查问题时临时使用
Disableddisabled完全关闭不记录不推荐:重启后需全盘重新打标签

核心机制: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_tWeb 服务器可读内容
httpd_sys_script_exec_tCGI 脚本
httpd_log_tWeb 服务器日志
ssh_home_tSSH 用户 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

故障排查流程图

  1. 服务启动失败 → 执行 setenforce 0 切换 Permissive
  2. 重试操作 → 如果成功,确认是 SELinux 问题
  3. 执行 ausearch -m avc -ts recent 查看被拒绝的操作
  4. 根据 sealert 建议选择修复方式:
    • 如果需要修改文件 context → chconrestorecon
    • 如果需要修改端口标签 → semanage port
    • 如果需要修改布尔值 → setsebool -P
    • 如果以上都不适用 → 生成自定义策略模块
  5. 切回 Enforcing:setenforce 1
  6. 验证服务正常运行

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
排障口诀:ausearch 找拒绝记录 → 读 scontext(进程域)与 tcontext(文件类型)→ 对症下药(fcontext/restorecon、port 标签、布尔值)。不要一上来就 setenforce 0,那是确认手段不是修复手段。

9. 常用策略布尔值速查表

布尔值是 SELinux 最"人性化"的部分:不需要懂策略语言,一个开关解决一类问题。以下是三类服务最常涉及的布尔值,考前过一遍。

httpd(Web 服务)

布尔值功能默认开启命令
httpd_enable_homedirs允许 httpd 读取用户 home 目录offsetsebool -P httpd_enable_homedirs on
httpd_can_network_connect允许 httpd 发起对外 TCP 连接(反向代理场景)offsetsebool -P httpd_can_network_connect on
httpd_can_network_connect_db允许 httpd 连接数据库端口offsetsebool -P httpd_can_network_connect_db on
httpd_graceful_shutdown允许 httpd 平滑关闭相关操作offsetsebool -P httpd_graceful_shutdown on
httpd_execmem允许 httpd 执行可写内存(部分 PHP 加速器需要)offsetsebool -P httpd_execmem on
httpd_use_nfs允许 httpd 使用 NFS 挂载的内容offsetsebool -P httpd_use_nfs on

ssh(远程登录)

布尔值功能默认开启命令
ssh_sysadm_login允许 sshd 处理系统管理员角色的登录offsetsebool -P ssh_sysadm_login on
ssh_chroot_rw_homedirs允许 chroot 后的用户写 home 目录(SFTP jail)offsetsebool -P ssh_chroot_rw_homedirs on
use_nfs_home_dirs允许用户通过 NFS 挂载的 home 登录offsetsebool -P use_nfs_home_dirs on
use_samba_home_dirs允许用户通过 Samba 共享的 home 登录offsetsebool -P use_samba_home_dirs on

samba(文件共享)

布尔值功能默认开启命令
samba_export_all_rw允许 Samba 导出所有可读写文件offsetsebool -P samba_export_all_rw on
samba_export_all_ro允许 Samba 导出所有只读文件offsetsebool -P samba_export_all_ro on
smbd_anon_write允许 smbd 写匿名用户可写目录offsetsebool -P smbd_anon_write on
samba_create_home_dirs允许 Samba 自动创建用户 home 目录offsetsebool -P samba_create_home_dirs on
记忆方法:布尔值名是"服务_能力_对象"三段式(httpd_can_network_connect = httpd 能否对外连接)。记不全也没关系,用 semanage boolean -l | grep 服务名 现查;重点是开启必须加 -P 才会持久化。

常见错误

常见错误原因分析解决方法
chcon 修改的 context 重启后丢失chcon 是临时修改,restorecon 会覆盖使用 semanage fcontext 添加持久规则
semanage 命令报错未安装 policycoreutils-python-utilssudo 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/webls -Z /home/web 确认 httpd_sys_content_t → sudo systemctl restart httpdcurl 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 0curl 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/uploadssudo systemctl restart nginxcurl 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_tls -Zd ~user 检查),类型不对时 restorecon -Rv /home/用户 修正。

题目 9

管理员需要查看当前系统所有 httpd 相关布尔值及其默认状态,并确认某布尔值是否持久化。写出命令。

参考答案:查看:getsebool -a | grep httpdsudo semanage boolean -l | grep httpd(后者带默认值与描述);确认持久化:布尔值文件在 /etc/selinux/targeted/booleanscat /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/uploadssudo 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 0curl 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-websudo systemctl restart httpdcurl 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>
完整配置检查清单:部署自定义 Web 服务时的 SELinux 检查项:① 端口标签(semanage port);② 文件上下文(semanage fcontext + restorecon);③ 布尔值(setsebool -P);④ 验证(getenforce、ls -Z、curl)。缺一不可。

完整配置案例 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
NFS + SELinux 要点:NFS 挂载目录的上下文类型为 nfs_t(由内核自动设置),httpd 需要通过 httpd_use_nfs 布尔值获得对 nfs_t 类型的读取权限。如果关闭此布尔值,即使传统权限正确,httpd 也无法读取 NFS 文件。

最佳实践

  • 排查 SELinux 问题时,先用 setenforce 0 确认是否是 SELinux 问题,再用 sealert 获取修复建议
  • 修改文件 context 优先使用 semanage fcontext + restorecon,而非 chcon
  • 设置布尔值始终加 -P 参数确保重启后生效
  • 不要随意禁用 SELinux,考试中这是扣分项
  • 熟悉 ausearchsealert 的输出格式,快速定位被拒绝的操作

验证 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 一关了之。

延伸阅读

↑ 回到顶部