使用 Apache2 和 mod_php 为 PHP 提供虚假请求 URL 和协议

使用 Apache2 和 mod_php 为 PHP 提供虚假请求 URL 和协议

我运行一个有多个用户的 Web 服务器。该机器为一群用户提供基于 Apache 的虚拟主机,这些用户可以提供静态内容或使用 PHP。没有其他形式的服务器端脚本可用。

典型请求的处理方式如下:

请求处理流程图

HTTPS 流量的 SSL 被 Pound 剥离,它充当反向代理并将请求转发到 Varnish,Varnish 也充当反向代理,最后将请求转发到 Apache。

当 HTTPS 流量到达 Apache 时,协议、端口和完整 URL 已从 更改为https://example.com:443/http://example.com:8443/这是 Apache 之前所有代理的结果。

有没有办法可以欺骗 PHP 脚本,让其认为请求来自原始 URL、端口和协议?无需修改 PHP 代码

这很重要,因为用户希望运行 Joomla、WordPress 和其他基于 PHP 的 CMS,这些 CMS 会检测 URL 并导致重定向、链接等问题。

我可能可以mod_php从源代码对其进行修补和构建,并针对我的具体情况进行必要的更改,但是有没有更好的方法可以为 PHP 脚本提供虚假的环境变量,也许通过 php.ini 中的某些设置?

答案1

我发现最简单的方法是删除mod_php并使用 CGI 脚本。这样你就可以php-cgi从页面加载时执行的 shell 脚本调用(PHP 解释器的 CGI 目标版本)。

下面是一个示例 bash 脚本,它根据标题设置SERVER_PORT和环境变量,然后调用:HTTPSX-Forwarded-Protophp-cgi

#!/bin/bash
# HTTPS fix (WARNING: THIS HEADER CAN BE FAKED BY THE CLIENT)
if [[ "$HTTP_X_FORWARDED_PROTO" == "https" ]]; then
        export SERVER_PORT=443
        export HTTPS="on"
else
        export SERVER_PORT=80
fi

php-cgi

当然,你必须小心,因为 X-Forwarded-Proto 标头可以由客户端发送,所以除非你在 Apache 和客户端之间有什么东西可以清理该标头,否则你不应该信任它!(你可能还想关闭 Apache 的防火墙,或者更好的是,让它只监听环回)

您需要做的就是让 Apache 对每个带有.php扩展名的文件使用此 bash 脚本(mod_cgimod_actions让您执行此操作)。

相关内容