在 RHEL 中使用 firewalld 和 SELinux 进行安全配置

Red Hat Enterprise LinuxBeginner
立即练习

介绍

在这个实验(Lab)中,你将学习如何在 Red Hat Enterprise Linux (RHEL) 上通过管理 SELinux 策略和防火墙规则来保护 Apache Web 服务器 (httpd)。你将通过一个实际的场景来操作,配置 httpd 监听一个非标准端口,并探索 SELinux 和防火墙系统如何管理此类配置的安全性。这个练习提供了在 RHEL 环境中进行常见安全管理任务的实践经验。

你将首先配置 httpd 服务在自定义端口上运行,并观察它在 SELinux 强制执行下的行为。你将使用 semanage 命令来理解和管理 SELinux 端口标签,确保适当的安全合规性。然后,你将使用 firewall-cmd 在系统的防火墙中打开这个自定义端口。最后,你将验证 Web 服务器是否可访问,确认你的安全配置已正确应用。

这是一个实验(Guided Lab),提供逐步指导来帮助你学习和实践。请仔细按照说明完成每个步骤,获得实际操作经验。根据历史数据,这是一个 初级 级别的实验,完成率为 97%。获得了学习者 98% 的好评率。

在自定义端口上配置 httpd 并理解 SELinux 上下文

在这一步,你将学习如何配置 Apache Web 服务器 (httpd) 在一个非标准端口上运行,并理解 SELinux 如何管理端口访问。我们将使用端口 8081,并探索 SELinux 端口管理,即使服务在某些配置中成功启动。

必要的软件包 (httpd, policycoreutils-python-utilsfirewalld) 已经在设置阶段安装完毕。policycoreutils-python-utils 软件包提供了 semanage 命令,你将在后面的步骤中使用它。

让我们从修改默认的 httpd 配置开始,使其监听一个非标准端口 8081httpd 的主配置文件位于 /etc/httpd/conf/httpd.conf。我们将使用 nano 编辑器来更改监听端口。

sudo nano /etc/httpd/conf/httpd.conf

nano 编辑器中,使用箭头键向下滚动并找到显示 Listen 80 的行。将此行更改为:

Listen 8081

要保存文件并退出 nano,请按 Ctrl+X,然后按 Y 确认更改,最后按 Enter 写入文件。

现在,配置已更改,让我们尝试启动 httpd 服务。在这个容器化环境中,systemctl 不可用。我们将直接启动 httpd 守护进程。

sudo /usr/sbin/httpd

你可能会看到关于服务器完全限定域名(fully qualified domain name)的警告消息,但这很正常,可以忽略。

AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using fe80::216:3eff:fe02:1a1e%eth0. Set the 'ServerName' directive globally to suppress this message

让我们通过检查 httpd 进程来验证服务是否正在运行。

ps aux | grep httpd

你应该看到多个 httpd 进程正在运行,这表明 Web 服务器已成功启动。

root        4813  0.0  0.2  23364  7736 ?        Ss   09:32   0:00 /usr/sbin/httpd
apache      4814  0.0  0.1  23020  5092 ?        S    09:32   0:00 /usr/sbin/httpd
apache      4815  0.0  0.4 1441064 14620 ?       Sl   09:32   0:00 /usr/sbin/httpd
apache      4816  0.0  0.5 1441064 18736 ?       Sl   09:32   0:00 /usr/sbin/httpd
apache      4837  0.0  0.4 1572200 16872 ?       Sl   09:32   0:00 /usr/sbin/httpd
labex       4996  0.0  0.0   6408  2176 pts/3    S+   09:32   0:00 grep --color=auto httpd

我们还检查 httpd 错误日志,看看启动期间发生了什么。

sudo tail /var/log/httpd/error_log

你应该看到正常的启动消息,表明服务器正在正常运行。

[Tue Jun 17 09:32:46.374275 2025] [core:notice] [pid 4812:tid 4812] SELinux policy enabled; httpd running as context system_u:system_r:unconfined_service_t:s0
[Tue Jun 17 09:32:46.377265 2025] [suexec:notice] [pid 4812:tid 4812] AH01232: suEXEC mechanism enabled (wrapper: /usr/sbin/suexec)
[Tue Jun 17 09:32:46.394284 2025] [lbmethod_heartbeat:notice] [pid 4813:tid 4813] AH02282: No slotmem from mod_heartmonitor
[Tue Jun 17 09:32:46.399433 2025] [mpm_event:notice] [pid 4813:tid 4813] AH00489: Apache/2.4.62 (Red Hat Enterprise Linux) configured -- resuming normal operations
[Tue Jun 17 09:32:46.399458 2025] [core:notice] [pid 4813:tid 4813] AH00094: Command line: '/usr/sbin/httpd'

有趣的是,httpd 服务在没有任何 SELinux 问题的的情况下启动了。让我们检查审计日志中是否有任何 SELinux 拒绝。

sudo grep AVC /var/log/audit/audit.log | grep httpd

如果没有结果,这意味着 SELinux 没有阻止 httpd 服务绑定到端口 8081。这可能是因为:

  1. 在某些配置中,端口 8081 默认可能已经允许用于 HTTP 服务
  2. httpd 进程可能在未受限的上下文中运行
  3. 端口 8081 可能已经在 SELinux 策略中定义

让我们检查当前的 SELinux 模式:

getenforce

你应该看到 SELinux 处于 "Enforcing" 模式,这意味着它正在积极地强制执行策略。httpd 成功启动的事实表明,端口 8081 可能已经具有适当的 SELinux 标签,或者服务正在未受限的上下文中运行,如日志消息所示。为了本次学习练习的目的,让我们继续下一步,在那里我们将探索 SELinux 端口管理并确保正确的配置。

使用 semanage 理解和管理 SELinux 端口标签

在这一步,你将学习如何使用 semanage 命令管理 SELinux 端口标签。即使 httpd 服务当前正在端口 8081 上运行,理解如何正确配置 SELinux 端口策略以确保安全性和合规性也很重要。你将探索当前的端口配置,并学习如何显式地将正确的 SELinux 类型分配给自定义端口。

首先,你需要找到 Web 服务器端口的正确 SELinux 类型。semanage port -l 命令列出 SELinux 知道的所有端口定义。我们可以将此输出通过管道传递给 grep 以查找与 http 相关的类型。

sudo semanage port -l | grep http

输出显示了几个端口类型。与标准 Web 服务器最相关的是 http_port_t

http_cache_port_t              tcp      8080, 8118, 8123, 10001-10010
http_cache_port_t              udp      3130
http_port_t                    tcp      80, 81, 443, 488, 8008, 8009, 8443, 9000
pegasus_http_port_t            tcp      5988
pegasus_https_port_t           tcp      5989

如你所见,http_port_t 被分配给标准 HTTP/HTTPS 端口,如 80443。SELinux 策略允许具有 httpd_t 类型(我们的 Web 服务器)的进程绑定到任何标记为 http_port_t 的端口。让我们检查端口 8081 是否已在此列表中。

请注意,端口 8081 当前未在 http_port_t 下列出。但是,在某些 RHEL 配置中,此端口可能已在 SELinux 策略中定义。让我们尝试使用 semanage port -a 命令显式添加它以实现正确的 SELinux 合规性。

  • -a 选项表示“添加(add)”。
  • -t http_port_t 选项指定要分配的类型。
  • -p tcp 选项指定协议。
sudo semanage port -a -t http_port_t -p tcp 8081

你可能会看到一条消息,指示“Port tcp/8081 already defined, modifying instead”,这意味着该端口已经配置。这解释了为什么 httpd 在上一步中成功启动。要验证当前配置,请再次列出 http_port_t 定义。

sudo semanage port -l | grep '^http_port_t'

你现在应该看到端口 8081 包含在列表中。

http_port_t                    tcp      8081, 80, 81, 443, 488, 8008, 8009, 8443, 9000

通过显式更新 SELinux 策略,端口 8081 现在被正式确认为 HTTP 端口。httpd 服务应该继续运行,没有任何问题,并且你已经确保了正确的 SELinux 合规性。

让我们验证该进程是否仍在运行:

ps aux | grep httpd

你应该继续看到多个 httpd 进程,这表明 Web 服务器正在使用正确的 SELinux 端口标签成功运行。

root        4813  0.0  0.2  23364  7736 ?        Ss   09:32   0:00 /usr/sbin/httpd
apache      4814  0.0  0.1  23020  5092 ?        S    09:32   0:00 /usr/sbin/httpd
apache      4815  0.0  0.4 1441064 14620 ?       Sl   09:32   0:00 /usr/sbin/httpd
apache      4816  0.0  0.5 1441064 18736 ?       Sl   09:32   0:00 /usr/sbin/httpd
apache      4837  0.0  0.4 1572200 16872 ?       Sl   09:32   0:00 /usr/sbin/httpd
labex       5215  0.0  0.0   6408  2176 pts/3    S+   09:33   0:00 grep --color=auto httpd

你已成功配置 SELinux 策略,以显式允许 httpd 服务在端口 8081 上运行,从而确保了正确的安全合规性。

使用 firewall-cmd 在防火墙中开放自定义端口

在这一步,你将配置系统的防火墙,以允许外部连接到你的 Web 服务器上的自定义端口 8081。尽管由于 SELinux 策略的更改,httpd 服务现在运行正常,但管理网络流量规则的 firewalld 服务默认情况下很可能阻止在此非标准端口上的传入请求。

firewalld 软件包已在设置阶段安装完毕。但是,我们需要首先启动 firewalld 服务。让我们检查当前状态,并在需要时启动它。

sudo firewall-cmd --list-all

如果你看到“FirewallD is not running”,我们需要启动 firewalld 守护进程。在这个容器环境中,我们直接启动 firewalld 守护进程。末尾的 & 在后台运行该进程。

sudo /usr/sbin/firewalld &

稍等片刻,让服务初始化,然后验证它是否正在运行:

sudo firewall-cmd --list-all

现在你应该看到默认区域(public)的当前防火墙配置。

让我们使用 curl 从命令行测试对 Web 服务器的访问。此命令尝试连接到端口 8081 上的 localhost

curl http://localhost:8081

你应该看到你的测试页面的 HTML 内容,这意味着 Web 服务器可以在本地访问。这是预期的,因为 firewalld 默认情况下通常允许 localhost 流量。

但是,对于外部访问和正确的安全配置,我们仍然需要为我们的自定义端口正确配置防火墙。虽然 localhost 连接通常无论防火墙规则如何都有效,但来自其他机器的外部连接如果没有正确的防火墙配置将被阻止。

首先,让我们检查默认区域(public)的当前规则:

public (active)
  target: default
  icmp-block-inversion: no
  interfaces: eth0 eth1
  sources:
  services: cockpit dhcpv6-client ssh
  ports:
  protocols:
  forward: yes
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

现在,添加一个新规则以允许端口 8081 上的 TCP 流量。在执行此命令之前,请确保 firewalld 正在运行。

  • --add-port=8081/tcp 指定要打开的端口和协议。
  • --permanent 确保规则在重启或防火墙重新加载后仍然存在。
sudo firewall-cmd --permanent --add-port=8081/tcp

如果你看到“FirewallD is not running”,请确保你在上一步中启动了 firewalld 守护进程,并稍等片刻让其初始化。

当 firewalld 正常运行时,该命令应返回 success

success

永久规则在重新加载之前不会应用于活动的防火墙配置。让我们重新加载防火墙以应用我们的新规则。

sudo firewall-cmd --reload

此命令也应返回 success

success

让我们通过再次列出规则来验证端口是否已打开。

sudo firewall-cmd --list-all

你现在应该在 ports: 部分看到 8081/tcp

public (active)
  target: default
  icmp-block-inversion: no
  interfaces: eth0 eth1
  sources:
  services: cockpit dhcpv6-client ssh
  ports: 8081/tcp
  protocols:
  forward: yes
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

你已成功配置防火墙。最后一步是测试你是否可以访问 Web 服务器。

验证标准和自定义 Web 服务器端口的访问

在最后一步,你将验证你所做的所有更改是否确保你的 Web 服务器已正确配置,以便进行本地和外部访问。你已经配置了 SELinux 策略并在防火墙中打开了必要的端口。现在,你将执行全面的测试以确认配置。

首先,让我们创建一个简单的测试页面,以便当我们连接时,我们得到一个自定义消息。httpd 的默认文档根目录是 /var/www/html。我们将在该目录中创建一个 index.html 文件。你需要 sudo 权限才能写入此位置。

echo "Success! Web server on custom port 8081 is working." | sudo tee /var/www/html/index.html

此命令将成功消息放入 index.html 文件中。这里使用 tee 命令是因为它允许我们使用管道写入需要 sudo 权限的文件。你应该看到消息回显到终端作为确认。

Success! Web server on custom port 8081 is working.

为了完成练习,让我们通过尝试访问标准 HTTP 端口 80 来演示对比。由于我们的服务器配置为仅侦听 8081,因此此请求应该失败。

curl http://localhost:80

正如预期的那样,连接被拒绝,因为没有服务在侦听该端口。

curl: (7) Failed to connect to localhost port 80: Connection refused

这证实了你的服务器仅在你配置的自定义端口上运行。通过这个实验,你已经学习了 RHEL 上服务的关键故障排除工作流程:

  1. 检查服务状态和日志。
  2. 调查审计日志中的 SELinux 拒绝。
  3. 使用 semanage 纠正 SELinux 策略。
  4. 使用 firewall-cmd 配置防火墙规则。
  5. 验证连接。

总结

在这个实验中,你学习了如何在自定义端口上配置 Web 服务器并管理 SELinux 安全策略。通过预先安装的 Apache Web 服务器(httpd)、policycoreutils-python-utilsfirewalld 软件包,你专注于理解 SELinux 端口管理和防火墙配置。你修改了 httpd.conf 文件,将 Web 服务器的监听端口更改为非标准端口 8081。

你发现 httpd 服务在自定义端口上成功启动,因为端口 8081 已经在 SELinux 策略中正确配置。这提供了一个探索 SELinux 端口管理并了解 semanage 如何工作以维护正确端口标签的机会。你还学习了使用 firewall-cmd 来管理防火墙规则,确保安全合规性和可访问性。即使 httpd 在未受限的上下文中运行,本实验也演示了为生产环境正确配置 SELinux 和防火墙的重要性。