我想在共享主机环境中使用 Apache 设置 PHP-FPM。推荐方式就是使用mod_proxy_fcgi
。
每个客户都有自己的 FPM 池,在自己的系统用户下运行 PHP 进程。这提供了良好的隔离。我们假设用于访问其 FPM 池的 unix 套接字存储为/run/php-fpm/{user1,user2,...}.sock
。
Apache 以单个系统用户的身份为所有客户运行,假设www-data
。由于它的唯一任务是提供静态文件并将连接传递到 FPM,因此这基本上没问题。但是,所有 FPM unix 套接字都必须可供 访问www-data
。
.htaccess
文件是共享主机客户配置重定向、基本身份验证、缓存控制标头等内容的好方法。事实上,在我的设置中坚持使用 Apache 的唯一原因是我想要支持这些客户提供的配置文件。为了保护 Apache 免受恶意.htaccess
文件的攻击,AllowOverride
和AllowOverrideList
可以使用。我可以排除几个不应使用的指令,例如Action
和,SetHandler
它们允许您以 身份执行 cgi 脚本www-data
。
一个特别有用的指令RewriteRule
来自mod_rewrite
模块。许多应用程序使用它来美化 URL,例如使用/foo
而不是/index.php/foo
as URI。但也有[P]
旗帜这会导致请求由 处理mod_proxy
。如果文件RewriteRule
中允许.htaccess
,那么恶意用户 (user2) 可以执行类似
RewriteRule "/evil" "unix:/run/php-fpm/user1.sock|fcgi://localhost/home/user2/evil.php" [P]
这将/home/user2/evil.php
在 user1 的 FPM 池中执行一个恶意文件(由 user2 提供),即以 user1 系统用户的身份执行。因此,它可以访问 中的所有文件/home/user1
,例如,它可以从 wordpress 配置文件中转储数据库机密。唯一的要求是 user1(受害者)可以读取这个恶意文件,但这并不难,因为 user2(攻击者)只能使用 来读取chmod
他自己的主目录和恶意文件o+rx
。
问题是:有哪些可能的方法可以减轻这种攻击?
- 禁止
RewriteRule
(.htacces
实际上不是一个选择……) - 为每个客户运行单独的 Apache 进程,使用他们自己的系统用户(但:资源消耗并需要另一个反向代理来共享端口 80 + 443)
- 修补
mod_rewrite
源以删除该[P]
标志(这会使安全更新变得烦人) - 还有其他想法吗?
编辑:mod_rewrite 补丁(适用于 Debian 软件包版本2.4.25-3+deb9u7
)
--- a/modules/mappers/mod_rewrite.c
+++ b/modules/mappers/mod_rewrite.c
@@ -4928,6 +4928,11 @@ static int hook_fixup(request_rec *r)
if (l > 6 && strncmp(r->filename, "proxy:", 6) == 0) {
/* it should go on as an internal proxy request */
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ "attempt to make proxy request from mod_rewrite "
+ "in per directory context: %s", r->filename);
+ return HTTP_FORBIDDEN;
+
/* make sure the QUERY_STRING and
* PATH_INFO parts get incorporated
* (r->path_info was already appended by the
有趣的是,他们检查是否mod_proxy
可用在hook_uri2file
(处理服务器上下文中的 RewriteRules)中,但不在hook_fixup
(处理目录上下文中的 RewriteRules)。
[P]
我决定在请求传递到代理模块之前停止它,而不是删除该标志。因此,它还应该能够捕获您以某种方式设法重写文件名的情况。此外,它仍然允许您在服务器上下文中使用或,即直接在块中proxy:...
使用。[P]
proxy:
<VirtualHost>
但如上所述,自定义补丁在每次更新中都是令人厌烦的维护工作。因此,请告诉我是否有更好的解决方案,只需修改配置文件即可。大公司如何处理这个问题?希望答案不是“根本不可能”。