我有一个网站想要总是通过 https 提供服务。网站使用 Apache 实现负载平衡。
Apache 负载均衡器的基本配置如下:
<Proxy balancer://mycluster>
BalancerMember http://server1 route=server1
BalancerMember http://server2 route=server2
</Proxy>
请注意,所有 http要求也可以使用 mod rewrite 重写为 https 请求。
我想要做的事情是确保来自服务器 1 或服务器 2 的任何 http 302 Location 标头都被重写并作为 https 302 重定向标头发送。
例如
如果来自服务器 1 的响应具有以下内容作为标头:
Location: http://server1/test
我希望它被安全地重写为
Location: https://server1/test
这将避免将请求发送到客户端,然后客户端发送 http 请求(该请求会被重写为 https),并且还可以避免通过 http 发送响应的任何安全问题。
我怎样才能做到这一点?
答案1
您不能使用 mod_rewrite 执行此操作,因为它仅适用于请求。
此外,对位置进行操作并不是一个 100% 的解决方案(它会非常高),因为它不会捕获诸如 HTTP 元刷新之类的内容(现在不太常见...),或者使用客户端解决方案生成 URL 的实例(例如 Javascript、嵌入式内容)。
因此,您提出的愿望虽然有用,但必须仅被视为一种优化。
应用程序端也可能存在敏感性问题。在不了解应用程序的情况下,以下是一些需要考虑的潜在事项:
- cookie 生成和“secure”属性的使用
- 应用程序可能已经生成了 URL 并完成了某种加密签名(可能出于 SSO 或身份验证目的,而将其重写为 https 可能会使 URL 无效).... 实际上不太可能,但肯定是可能的。
不过,你也许可以使用 mod_header 来实现这一点,它可以操纵响应头。请参阅http://httpd.apache.org/docs/2.2/mod/mod_headers.html
Header edit Location ^http: https:
我根本没有测试过,请注意可以在edit
关键字前指定条件。
希望这对你有帮助,卡梅伦
答案2
虽然这不是这个问题的直接答案,但我用以下 Apache 配置更改来解决问题:
RequestHeader set X-Forwarded-Proto "https" env=HTTPS
使用此功能使得负载均衡器中的节点在传入上述标头时将其绝对http
URL 重写为URL。https
这是暗示这篇 ServerFault 帖子,最终在 Jetty 文档中提到了这一点,问题解决了!