Apache ProxyPassReverse 没有正确重写 Location header
Apache ProxyPassReverse not rewriting Location header properly
我正在配置 apache 以将 SSL 请求代理到本地后端服务器。下面是虚拟主机的相关部分:
<VirtualHost *:443>
...
SSLEngine on
SSLCertificateFile /path/to/server.crt
SSLCertificateKeyFile /path/to/server.key
RewriteEngine On
<Proxy balancer://unicornservers>
BalancerMember http://127.0.0.1:8080
</Proxy>
# Redirect all non-static requests to unicorn
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RewriteRule ^/(.*)$ balancer://unicornservers%{REQUEST_URI} [P,QSA,L]
ProxyPassReverse / balancer://unicornservers/
ProxyPreserveHost on
...
</VirtualHost>
当我使用 curl 访问服务器 (curl -vk https://example.com
) 时,后端服务器按预期执行重定向到 /login
。
问题是,apache 没有正确重写 Location
header。它 returns 的位置 http://example.com/login
而不是 https://example.com/login
.
我的配置中是否有某个地方需要告诉 apache 使用 https
进行 ProxyPassReverse
重写?
原来是我误诊了。后端网络服务器(在本例中,恰好是 rails)实际上明确指定了 http
URL。这是因为它使用传入的请求参数来构建其重定向 URL。因此,由于 ProxyPreserveHost
已启用,它使主机正确,但协议不正确。
为了修复它,我在我的 apache 配置中添加了以下行:
RequestHeader set X-Forwarded-Proto "https"
这样,后端 rails 服务器知道原始请求是通过 SSL 发出的,并且它会正确生成重定向 URL。
我正在配置 apache 以将 SSL 请求代理到本地后端服务器。下面是虚拟主机的相关部分:
<VirtualHost *:443>
...
SSLEngine on
SSLCertificateFile /path/to/server.crt
SSLCertificateKeyFile /path/to/server.key
RewriteEngine On
<Proxy balancer://unicornservers>
BalancerMember http://127.0.0.1:8080
</Proxy>
# Redirect all non-static requests to unicorn
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RewriteRule ^/(.*)$ balancer://unicornservers%{REQUEST_URI} [P,QSA,L]
ProxyPassReverse / balancer://unicornservers/
ProxyPreserveHost on
...
</VirtualHost>
当我使用 curl 访问服务器 (curl -vk https://example.com
) 时,后端服务器按预期执行重定向到 /login
。
问题是,apache 没有正确重写 Location
header。它 returns 的位置 http://example.com/login
而不是 https://example.com/login
.
我的配置中是否有某个地方需要告诉 apache 使用 https
进行 ProxyPassReverse
重写?
原来是我误诊了。后端网络服务器(在本例中,恰好是 rails)实际上明确指定了 http
URL。这是因为它使用传入的请求参数来构建其重定向 URL。因此,由于 ProxyPreserveHost
已启用,它使主机正确,但协议不正确。
为了修复它,我在我的 apache 配置中添加了以下行:
RequestHeader set X-Forwarded-Proto "https"
这样,后端 rails 服务器知道原始请求是通过 SSL 发出的,并且它会正确生成重定向 URL。