防止 Apache/PHP 来自 运行 影响另一个 vHost 的代码

Prevent Apache/PHP from running code that affects another vHost

情况

我的 /var/www/ 目录中有多个文件夹。

创建的用户可以控制特定目录.../var/www/app1 属于 app1:app1www-dataapp1 组的成员)。

这对我想要的效果很好。

问题

如果 app1 用户上传了一个 PHP 脚本来更改 app2 目录结构中某些内容的 file/folder 权限,Apache 进程(因为只有一个安装在服务器上)将非常乐意 运行 它,因为它具有访问 /var/www/app1 /var/www/app2 文件夹和文件。

编辑:

据我所知,类似 /var/www/app1/includes/hack.php:

<?php
chmod("/var/www/app2", 777);
?>

Apache 进程(属于 www-data)将 运行 执行此操作,因为它有权更改 /var/www/app1/var/www/app2 目录。用户app1然后就可以cd /var/www/app2rm -rf /var/www/app2等,这显然不好。

问题

如何避免 Apache 进程的这种交叉污染?我可以指示 Apache 仅 运行 PHP 影响驻留在相关 vHost 根目录及以下目录中的 files/folders 的脚本吗?

您应该向每个站点的 vhost 文件添加一个 open_basedir 指令。 open_basedir 指令限制站点可以访问的目录。

您可以阅读更多关于 open_basedir here

虽然 open_basedir 会有所帮助,但有几种方法可以绕过此限制。虽然您可以破坏 php 中的 lot 功能以关闭所有后门,但更好的解决方案是停止执行 php 作为具有以下权限的用户访问所有文件。为此,您需要为每个虚拟主机使用 php-fpm 和单独的进程 pool/uid/gid。

对于 php 执行,您仍然应该有一个单独的 uid,与拥有具有公共组的文件的 uid 允许对文件的默认只读访问。

您还需要有单独的会话数据存储目录。

一个更复杂的机制是在每个所有者的容器前面使用类似 Apache 流量服务器的东西,每个站点 运行 在它自己的 Apache 实例上 - 更好的隔离,但技术要求高且有点占用更多资源。

请记住,如果您使用的是 mariadb 或类似软件,DBMS 也可以读写任意文件(SELECT INTO OUTFILE.../LOAD DATA INFILE)

更新

与其维护单独的容器,不如通过将 php-fpm uid appX 的主目录设置为虚拟主机的基目录(应包含,不是,document_root - 见下文)并使用 apparmor 来限制对公共文件(例如 .so 库)和 @{HOME} 的访问。因此每个 /var/www/appX 可能包含:

 .htaccess
 .user.ini
 data/ (writeable by fpm-appX)
 html/ (the document root)
 include/
 sessions/ (writeable by fpm-appX)