介绍
在本实验中,你将学习如何管理 SELinux 文件上下文,以确保 Apache Web 服务器等服务能够访问必要的文件。你将探索安全增强型 Linux(SELinux)如何将安全标签(称为上下文)应用于文件,以及即使在标准文件权限看起来正确的情况下,不匹配的上下文如何导致访问拒绝错误。这一动手实践旨在培养你在 Linux 环境中排除常见安全问题的实际技能。
在接下来的步骤中,你将安装 Apache,验证 SELinux 是否处于「强制」(enforcing)模式,并观察放置正确的网页的默认上下文。然后,你将通过把一个带有错误上下文的文件移动到 Web 根目录中,故意触发「禁止访问」(Forbidden)错误。为了解决这个问题,你将使用 chcon 命令对文件进行重新标注,这演示了修复 SELinux 上下文相关问题并恢复服务功能的基本方法。
安装 Apache 并验证 SELinux 处于强制模式
在这一步骤中,你将首先确保环境配置正确。这包括验证 Linux 内核中的关键安全模块 SELinux 是否运行在「强制」(enforcing)模式下。然后,你将安装 Apache Web 服务器,它将在整个实验中用于演示 SELinux 上下文的工作原理。
首先,让我们检查 SELinux 的状态。你可以使用 sestatus 命令获取详细概览,或者使用 getenforce 命令获取直接的答案。
运行 getenforce 查看当前模式:
getenforce
该命令应返回 Enforcing,这意味着 SELinux 正在积极保护你的系统。
Enforcing
如果返回 Permissive,则 SELinux 仅记录警告但不阻止操作。如果返回 Disabled,则 SELinux 已完全关闭。对于本实验,它必须是 Enforcing。你的实验环境已预配置为 Enforcing 模式。
接下来,你将安装 Apache Web 服务器,在 CentOS/RHEL 系统上其软件包名称为 httpd。使用 yum 软件包管理器进行安装。-y 标志会自动对任何确认提示回答「是」。
sudo yum -y install httpd
当 yum 解析依赖关系并安装软件包时,你会看到输出。安装成功后会显示「Complete!」消息。
...
Installed:
httpd-2.4.x-xx.el8.x86_64
...
Complete!
安装完成后,你需要启动 Apache 服务使其运行。使用 systemctl 来管理服务。
sudo systemctl start httpd
要确认 Apache 服务是否运行正常,请检查其状态:
sudo systemctl status httpd
输出应显示服务处于 active (running) 状态。
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
Active: active (running) since ...
...
按 q 退出状态视图并返回命令提示符。你的环境现在已为后续步骤准备就绪。
创建网页并验证其默认 SELinux 上下文
在这一步骤中,你将创建一个简单的网页,并使用刚刚安装的 Apache 服务器进行发布。这个过程将演示 SELinux 如何自动为在特定策略定义目录中创建的文件分配正确的安全上下文,从而允许服务无障碍地访问它们。
Apache 的默认 Web 内容目录是 /var/www/html。如果文件的权限和 SELinux 上下文正确,放置在这里的任何文件都应该可以通过 Web 浏览器访问。
让我们直接在 /var/www/html 内部创建一个简单的 index.html 文件。由于此目录归 root 用户所有,你必须使用 sudo 才能写入。标准的 sudo echo 命令配合重定向(>)将无法工作,因为重定向是由你当前的 Shell 处理的,而该 Shell 缺乏权限。为了解决这个问题,你可以使用 sudo sh -c '...' 在 root Shell 中运行命令。
执行以下命令创建文件:
sudo sh -c 'echo "Welcome to Apache on LabEx" > /var/www/html/index.html'
现在,让我们验证 Web 服务器是否可以访问并发布这个新页面。你可以使用 curl(一个用于通过 URL 传输数据的命令行工具)从 localhost 请求该页面。
curl http://localhost
你应该会在终端看到 index.html 文件的内容,这确认了 Apache 正在运行且可以读取该文件。
Welcome to Apache on LabEx
那么,为什么这一切能无缝协作呢?答案在于文件的 SELinux 上下文。当你创建一个文件时,SELinux 会根据父目录的策略为其分配一个上下文。让我们使用 ls -Z 命令检查刚刚创建的 index.html 文件的上下文。-Z 选项用于显示 SELinux 安全上下文。
ls -Z /var/www/html/index.html
输出将类似于:
system_u:object_r:httpd_sys_content_t:s0 /var/www/html/index.html
输出中最重要的部分是上下文标签:system_u:object_r:httpd_sys_content_t:s0。该标签由四部分组成:用户:角色:类型:级别。在本实验中,我们关注的是类型(type),即 httpd_sys_content_t。
Apache(httpd)的 SELinux 策略明确允许以 httpd_t 类型运行的进程访问带有 httpd_sys_content_t 类型标签的文件。因为你直接在 /var/www/html 中创建了该文件,它继承了正确的默认上下文,因此一切按预期工作。
通过移动带有错误上下文的文件触发 SELinux 拒绝
在这一步骤中,你将看到当一个带有错误 SELinux 上下文的文件被移动到 Apache Web 目录时会发生什么。这是一个常见的场景,如果你不了解 SELinux 上下文在 mv 等文件操作中的工作方式,可能会感到困惑。与直接在目录中创建文件(这会导致其继承父目录的默认上下文)不同,移动文件会保留其原始上下文。
首先,在当前工作目录 ~/project 中创建一个新的网页 page2.html。
echo "This is Page 2" > page2.html
现在,检查这个新文件的 SELinux 上下文。由于它是在你的用户项目目录中创建的,它将获得分配给用户文件的默认上下文。
ls -Z page2.html
输出将显示上下文类型为 user_home_t 或类似内容,这是用户主目录下文件的默认类型。
system_u:object_r:user_home_t:s0 page2.html
请注意类型是 user_home_t。这与 Apache 允许访问的 httpd_sys_content_t 不同。
接下来,使用 mv 命令将此文件移动到 Apache Web 根目录。你需要使用 sudo,因为目标目录 /var/www/html 归 root 所有。
sudo mv page2.html /var/www/html/
mv 命令会保留源文件的 SELinux 上下文。让我们通过检查文件在新位置的上下文来验证这一点。
ls -Z /var/www/html/page2.html
如你所见,上下文没有改变。尽管文件现在位于 /var/www/html 目录中,但它仍然是 user_home_t。
system_u:object_r:user_home_t:s0 /var/www/html/page2.html
现在,尝试使用 curl 访问这个新页面。由于上下文不匹配,SELinux 将阻止访问。
curl http://localhost/page2.html
你将收到来自服务器的「403 Forbidden」错误。这并不是传统的文件权限问题;而是 SELinux 在执行其安全策略,拒绝 httpd 进程读取带有 user_home_t 标签的文件。
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access /page2.html
on this server.</p>
</body></html>
这演示了一个经典的 SELinux 问题。在下一步中,你将学习如何通过更改文件的上下文来修复此问题。
使用 chcon 修正文件上下文并验证访问
在这一步骤中,你将通过手动更改 page2.html 文件的 SELinux 上下文来解决上一步中的「403 Forbidden」错误。你将使用 chcon(change context,更改上下文)命令,这是一个用于修改文件和目录安全上下文的强大工具。
chcon 命令允许你直接更改 SELinux 上下文的用户、角色、类型或级别。在本练习中,你只需要更改类型。Apache 可以读取的 Web 内容的正确类型是 httpd_sys_content_t。
为了解决该问题,你将使用带有 -t 标志的 chcon 命令来为 page2.html 指定新类型。由于文件位于 /var/www/html 中,你需要使用 sudo 来修改其上下文。
运行以下命令更新 page2.html 的 SELinux 类型:
sudo chcon -t httpd_sys_content_t /var/www/html/page2.html
执行完命令后,让我们验证上下文是否已更新。再次使用 ls -Z 检查文件的安全上下文。
ls -Z /var/www/html/page2.html
输出现在应显示类型已从 user_home_t 更改为 httpd_sys_content_t。
system_u:object_r:httpd_sys_content_t:s0 /var/www/html/page2.html
有了正确的 SELinux 上下文,Apache 现在应该能够访问并发布该文件了。让我们通过再次使用 curl 发起请求来测试。
curl http://localhost/page2.html
这一次,命令应该会成功执行,你会在终端看到网页的内容。
This is Page 2
你已成功诊断并解决了与 SELinux 相关的访问问题。你了解到移动文件会保留其原始上下文,并且可以使用 chcon 手动调整上下文以符合安全策略,从而授予 Apache 等服务的访问权限。需要注意的是,使用 chcon 所做的更改在完整的系统文件重新标注(relabeling)后可能不会保留;通常使用 restorecon 命令来应用策略定义的默认上下文。
总结
在本实验中,你学习了如何为 Apache Web 服务器管理 SELinux 文件上下文。你首先验证了 SELinux 处于「强制」(Enforcing)模式,然后安装并启动了 httpd 服务。你观察到直接在 Apache Web 根目录(/var/www/html)中创建的文件会自动分配正确的 httpd_sys_content_t 上下文,这是 Apache 正常访问和发布文件所必需的。
实验的核心部分演示了错误文件上下文带来的后果。通过将文件从用户主目录(带有 user_home_t 上下文)移动到 Web 根目录,你触发了 SELinux 拒绝访问,导致了「403 Forbidden」错误。随后,你学习了如何通过使用 chcon 命令手动将文件的上下文更改为正确的 httpd_sys_content_t 类型来解决此访问问题,成功恢复了访问,并强化了这样一个原则:在强制执行的 SELinux 策略下,正确的文件上下文对于服务的正常运行至关重要。



