如何使用 SELinux 来限制 PHP 脚本?

如何使用 SELinux 来限制 PHP 脚本?

我想在我的 SL6.4(RHEL 6.4 重建)Web 服务器上划分不同的 PHP 应用程序,以便它们无法访问彼此的数据。SELinux 似乎可以做到这一点,但我不确定细节。我的问题分为两部分:

  1. SElinux 如何通过 mod_php 管理在 Apache 进程中运行的 PHP 脚本?进程在运行 PHP 脚本时是否会以某种方式进入脚本上下文,还是只有当脚本通过 CGI 或 FastCGI 在进程外运行时才有效?如果它转换到脚本上下文来运行 PHP 脚本,那么什么可以阻止 PHP 错误触发转换回主 httpd 上下文?如果我需要替代的 PHP 部署方法,那就最好知道了。
  2. 我如何分离脚本/应用程序,以便 TinyTinyRSS 等无法访问 OpenCloud 拥有的内容?看来我应该能够通过关闭httpd_unified并提供单独的httpd_ttrss_*httpd_opencloud_*上下文集(与httpd_user_foo和并行)来做到这httpd_sys_foo一点。考虑到我可以使用的应用程序数量,我甚至可能只需使用 sys/user 区分而无需新上下文就足够了。但我没有找到太多关于关闭的确切含义httpd_unified或如何设置不同 HTTP 上下文的文档。特别是对于通过运行的 PHP 脚本mod_php

我可以创建新的 SELinux 策略模块,但希望有一些文档指出我需要让新策略做什么以及如何使其与 SELinux 目标策略很好地集成。

如果尝试仅使用 SELinux 进行这种分离是徒劳的,并且我需要在不同的上下文中启动单独的 httpds,或者甚至可能是 LXC 容器,那么这也是一个有用的答案。

答案1

实现这种分离程度的最佳方法是不使用类型转换,而是使用类别/MCS 转换。这有点像svirtlibvirt KVM 中的实现。

好的,您需要做的第一件事是下载一个名为的 httpd 模块mod_selinux。它在 Fedora 存储库中已经存在了相当长一段时间,但不幸的是从未真正进入 EL6 系统。

无论如何,您都可以从 Fedora 源重建软件包。我在 Fedora 机器上执行了此操作,但您可以从镜像中下载相同的软件包。我使用 F16 作为基础,因为它可以运行httpd-2.2

yumdownloader --source mod_selinux --releaserver=16
...
mod_selinux-2.2.2454-3.fc15.src.rpm                        |  23 kB   00:00

然后下载后,在您的 EL6 盒子上重建。

rpmbuild --rebuild mod_selinux-2.2.2454-3.fc15.src.rpm
...
Wrote: /home/build/rpmbuild/RPMS/x86_64/mod_selinux-2.2.2454-3.el6.x86_64.rpm

最后安装模块。

rpm -i /home/build/rpmbuild/RPMS/x86_64/mod_selinux-2.2.2454-3.el6.x86_64.rpm

RPM 安装了httpd您需要的模块以及httpd运行所需的策略。

该模块的文件安装在 中/etc/httpd/conf.d/mod_selinux.conf

此过程的第一阶段是增加主 httpd 进程运行的类别数量,以便它可以生成跨越正确范围的子线程。在文件中更改:

selinuxServerDomain     *:s0

selinuxServerDomain     *:s0-s0:c0.c1023

现在,您必须为 apache 中的每个虚拟主机分配一个类别。这可以通过添加一行(如下例中名为 )来完成selinuxDomainVal

<VirtualHost *:80>
    DocumentRoot /var/www/vhosts/host1
    ServerName host1.virtual
    selinuxDomainVal *:s0:c0
</VirtualHost>

<VirtualHost *:80>
    DocumentRoot /var/www/vhosts/host2
    ServerName host2.virtual
    selinuxDomainVal *:s0:c1
</VirtualHost>

接下来,在每个主机的文档根目录中,将其文档根目录重新标记为相同的类别与 httpd 配置中所标记的类别相同。

chcon -R -l s0:c0 /var/www/vhosts/host1
chcon -R -l s0:c1 /var/www/vhosts/host2

如果您希望在进行系统重新贴标时标签能够得到尊重,那么您最好也更新本地策略!

semanage fcontext -a -t httpd_sys_content_t -r s0-s0:c0 '/var/www/vhosts/host1(/.*)?'
semanage fcontext -a -t httpd_sys_content_t -r s0-s0:c1 '/var/www/vhosts/host2(/.*)?'

就是这样!现在不可能离开你的文档根目录并去探索其他目录了。

答案2

我知道这个问题已经 7 年了,但是上面 @MatthewIfe 的回答很有用,但需要一些额外的步骤。我们使用的是 CentOS8,它仍然不包含mod_selinux开箱即用功能,因此上面的答案非常适合安装它。

然而,在安装后,经过正确的设置后,apache 未能通过 AVC 测试,无法启动。 、 和 中的错误信息/var/log/httpd/error.log没有/var/log/messages多大/var/log/audit/audit.log帮助。

最后,我不得不安装两个额外的实用程序来帮我排除 selinux AVC 错误,这意味着我必须创建一个自定义策略来允许服务httpd访问setcurrentselinux 中的命令。

您可以在这里找到解决方案:在 CentOS8 上使用 SELinux 上下文进行 Apache vhost 权限分离

希望这可以帮助其他遇到此问题的人。

相关内容