Apache ProxyPassReverse无法正确重写Location头

时间:2015-05-07 14:53:19

标签: apache mod-rewrite reverse-proxy mod-proxy mod-ssl

我正在配置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标头。它会返回http://example.com/login而不是https://example.com/login的位置。

我的配置中是否有某处需要告诉apache使用https进行ProxyPassReverse重写?

1 个答案:

答案 0 :(得分:1)

原来我错误地诊断了这一点。后端Web服务器(在这种情况下,碰巧是rails)实际上是明确指定了http URL。这是因为它使用传入的请求参数来构建其重定向URL。因此,由于ProxyPreserveHost已启用,因此主机正确,但不是协议。

要解决此问题,我将以下行添加到我的apache配置中:

RequestHeader set X-Forwarded-Proto "https"

这样,后端rails服务器知道原始请求是通过SSL的,并且它正确地生成了重定向URL。