我目前正在https
我们的生产环境中实施,但我对这里的一件小事感到困惑。
SSL 在负载均衡器中终止,并且我们的堆栈中的流程基本上是这样的:
生产:浏览器 <- https
-> 负载均衡器 <- http
-> Apache <- http
-> 负载均衡器 <- http
-> Tomcat
测试:浏览器 <- https
-> nginx <- http
-> 负载均衡器 <- http
-> Tomcat
当我通过 HTTPS 访问我们的登录页面时:
请求标头
POST /login/form HTTP/1.1
Host: www.example.org
Connection: keep-alive
Content-Length: 74
Cache-Control: max-age=0
Origin: https://www.example.org
Content-Type: application/x-www-form-urlencoded
Referer: https://www.example.org/login
Accept-Encoding: gzip,deflate,sdch
Accept-Language: nb,en-US;q=0.8,en;q=0.6
响应标头
HTTP/1.1 302 Moved Temporarily
Server: nginx
Date: Fri, 17 Jan 2014 11:16:50 GMT
Content-Length: 0
Connection: keep-alive
Set-Cookie: FOO=example
Location: http://www.example.org/portal
Strict-Transport-Security: max-age=31536000
我和一位开发人员进行了交谈,他告诉我以下几点:
代码中有类似 request.sendRedirect("/portal") 的内容,Tomcat 会完成剩下的工作。
尽管堆栈略有不同,但我能够在测试环境中重现该问题。
我的问题:
- 为什么当浏览器最初发出请求时,我会
http
在 -header 中获得方案?Location
https
- 这是 Apache mod_rewrite/mod_proxy 还是 nginx 问题?
- 这是 Tomcat 的问题吗?
答案1
响应标头中会出现 http,因为到达 Apache 的请求是 HTTP - SSL 已在负载均衡器上被剥离。因此从 Apache 的角度来看,这只是一个 HTTP 请求。
您可以通过设置来解决此问题
ServerName https://www.example.org
在全局或虚拟主机配置中。这将覆盖默认的 http 方案,以便 Apache 将发送您想要的响应。服务器名称提到了这一点。
答案2
我遇到了类似的问题。在虚拟主机配置中添加以下内容应该可以解决问题。基本上它会将 http 请求编辑为 https
Header edit Location ^http://(.*)$ https://$1
答案3
http://nginx.org/docs/http/ngx_http_proxy_module.html#proxy_redirect
proxy_redirect default;
proxy_redirect http://www.example.org/ https://www.example.org/;