如何防止 ProxyPreserveHost 无限期重定向?
How can I prevent ProxyPreserveHost from redirecting indefinitely?
我正在尝试拥有两个子域,my.domain.com
和 foo.my.domain.com
,它们都重定向到我的 Apache2 服务器 (127.0.0.1/my/
) 的同一目录。
但是,我希望那里的脚本能够分辨请求来自哪个域。在我看来,有两种方法可以做到这一点:
- 使用 RewriteRule 在每个包含
.php
的请求末尾添加 ?foo=bar
,但这听起来很脏
- 使用 ProxyPreserveHost 向 PHP 脚本指示原始域是什么,这听起来更正常和理智。
但是,我第二次启用 ProxyPreserveHost 时遇到了无休止的 301 重定向循环。
这是虚拟主机配置:
My.Domain.com:
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName my.domain.com
ProxyPass / http://127.0.0.1/my/
ProxyPassReverse / http://127.0.0.1/my/
ProxyRequests Off
SSLCertificateFile /etc/letsencrypt/live/my.domain.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/my.domain.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>
Foo.My.Domain.Com:
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName foo.my.domain.com
ProxyPass / http://127.0.0.1/my/
ProxyPassReverse / http://127.0.0.1/my/
ProxyRequests Off
ProxyPreserveHost On # creates 301 loop!
SSLCertificateFile /etc/letsencrypt/live/my.domain.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/my.domain.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>
注意:我也尝试将 ProxyPassReverse / https://foo.my.domain.com/
放在第二个域 foo.domain.com
中,但它没有任何改变。
如何在不引起重定向循环的情况下保留主机?
如文档所述,设置 ProxyPreserveHost 会导致 apache 忽略 ProxyPass 指令并使用提供的主机名,因此您试图将请求转发到 foo.my.domain.com,从而导致无限重定向循环。我认为我不会将我的服务器设置为代理转发到本地主机,但鉴于你有,我建议的最简单的更改是摆脱 ProxyPreserveHost 语句并将 ProxyPass 更改为 http://127.0.0.1/myfoo
, 并添加一些代码来保留 foo 地址。
如果您想在 php 脚本中获取域,有更好的解决方案:
在 php 中:
echo $_SERVER['SERVER_NAME'];
echo $_SERVER['HTTP_HOST'];
在 appache 虚拟主机中:
UseCanonicalName off
这里建议:
更新
将此添加到您的 appache 虚拟主机:
RequestHeader set mydomain "my.domain.com"
另一个:
RequestHeader set mydomain "foo.my.domain.com"
然后像这样在 php 中检索它:
echo $_REQUEST["mydomain"];
如果它没有识别出 RequestHeader:
a2enmod headers
systemctl restart apache2.service // or whatever your appache service name is httpd
因为 RockOver 找到了解决方案
$_SERVER["HTTP_X_FORWARDED_HOST"];
将反映实际的 域名 并将在重定向期间保留。
找到了:
$_SERVER["HTTP_X_FORWARDED_HOST"]
包含主机名,所以 foo.my.domain.com
在我的例子中。最后我不需要 UseCanonicalName
也不需要 ProxyPreserveHost
。
我正在尝试拥有两个子域,my.domain.com
和 foo.my.domain.com
,它们都重定向到我的 Apache2 服务器 (127.0.0.1/my/
) 的同一目录。
但是,我希望那里的脚本能够分辨请求来自哪个域。在我看来,有两种方法可以做到这一点:
- 使用 RewriteRule 在每个包含
.php
的请求末尾添加?foo=bar
,但这听起来很脏 - 使用 ProxyPreserveHost 向 PHP 脚本指示原始域是什么,这听起来更正常和理智。
但是,我第二次启用 ProxyPreserveHost 时遇到了无休止的 301 重定向循环。 这是虚拟主机配置:
My.Domain.com:
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName my.domain.com
ProxyPass / http://127.0.0.1/my/
ProxyPassReverse / http://127.0.0.1/my/
ProxyRequests Off
SSLCertificateFile /etc/letsencrypt/live/my.domain.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/my.domain.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>
Foo.My.Domain.Com:
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName foo.my.domain.com
ProxyPass / http://127.0.0.1/my/
ProxyPassReverse / http://127.0.0.1/my/
ProxyRequests Off
ProxyPreserveHost On # creates 301 loop!
SSLCertificateFile /etc/letsencrypt/live/my.domain.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/my.domain.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>
注意:我也尝试将 ProxyPassReverse / https://foo.my.domain.com/
放在第二个域 foo.domain.com
中,但它没有任何改变。
如何在不引起重定向循环的情况下保留主机?
如文档所述,设置 ProxyPreserveHost 会导致 apache 忽略 ProxyPass 指令并使用提供的主机名,因此您试图将请求转发到 foo.my.domain.com,从而导致无限重定向循环。我认为我不会将我的服务器设置为代理转发到本地主机,但鉴于你有,我建议的最简单的更改是摆脱 ProxyPreserveHost 语句并将 ProxyPass 更改为 http://127.0.0.1/myfoo
, 并添加一些代码来保留 foo 地址。
如果您想在 php 脚本中获取域,有更好的解决方案:
在 php 中:
echo $_SERVER['SERVER_NAME'];
echo $_SERVER['HTTP_HOST'];
在 appache 虚拟主机中:
UseCanonicalName off
这里建议:
更新
将此添加到您的 appache 虚拟主机:
RequestHeader set mydomain "my.domain.com"
另一个:
RequestHeader set mydomain "foo.my.domain.com"
然后像这样在 php 中检索它:
echo $_REQUEST["mydomain"];
如果它没有识别出 RequestHeader:
a2enmod headers
systemctl restart apache2.service // or whatever your appache service name is httpd
因为 RockOver 找到了解决方案
$_SERVER["HTTP_X_FORWARDED_HOST"];
将反映实际的 域名 并将在重定向期间保留。
找到了:
$_SERVER["HTTP_X_FORWARDED_HOST"]
包含主机名,所以 foo.my.domain.com
在我的例子中。最后我不需要 UseCanonicalName
也不需要 ProxyPreserveHost
。