在负载均衡器后面使用ngnix将HTTP重写为https


13

我正在使用Rackspace负载平衡器,该平衡器使我可以在管理面板中设置ssl密钥/ pem。一切正常,我可以同时使用http和https协议。但是,如果我尝试使用以下方法将http重定向到https:

server{
  listen *:80;
  server_name mydomain.com www.mydomain.com; 
  rewrite ^ https://mydomain.com$request_uri? permanent;

...我得到一个重定向循环。我知道我没有监听端口443,但这是因为负载均衡器为我处理了该端口。我也尝试将重写包装if ($scheme ~* http){成无效。

我的问题的另一部分是,我想从网址中删除www,我可以一次重写吗?上面的改写是否也应该解决这个问题?

谢谢你的帮助!


负载平衡器应向您发送一些有关连接是否为HTTPS的指示。询问Rackspace。(哦,您可能不想摆脱www ...)
Michael Hampton

有趣的是,我会研究一下。为什么您认为我不应该摆脱www?
jwerre

Answers:


14

sciurus是正确的,因为当在负载平衡器上卸载SSL时,Rackspace的Cloud Load Balancer会将X-Forwarded-Proto设置为https。为了避免nginx中的重定向循环,您应该能够location在vhost配置的部分中添加以下内容:

if ($http_x_forwarded_proto = "http") {
            rewrite  ^/(.*)$  https://mydomain.com/$1 permanent;
}

在将非https请求重定向到https时,这应该避免无限重定向循环。


18

通过使用nginx的内置服务器变量$request_uri$server_name您可以完全不使用正则表达式来执行此操作。将以下内容添加到服务器的location块中,就可以完成:

if ($http_x_forwarded_proto = "http") {
    return 301 https://$server_name$request_uri;
}

假设您的负载平衡器正在将$http_x_forwarded_proto标头和请求一起发送到后端实例。其他常见标头包括$http_x_forwarded_scheme和也$scheme

可以在Nginx 陷阱和常见错误文档中找到更多信息:https : //www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/#taxing-rewrites


5
绝对应该使用return over rewrite。已投票。
designermonkey

1
您可以$host代替$server_name
Yossi

不适用于server_name _;因此,应按照@Yossi的建议使用$ host变量。
拉兹万·格里戈里

1

负载平衡器始终通过http与您对话。发生了什么事

  1. 浏览器向负载均衡器上的端口80发出请求
  2. 负载平衡器向您的Web服务器上的端口80发出请求
  3. 您的Web服务器将重定向发送给用户
  4. 用户向负载均衡器上的端口443发出请求

重复执行步骤2-4,直到浏览器检测到重定向循环并放弃。

编辑:要解决此问题,请仅在X-Forwarded-Proto标头设置为http时执行重写。该标头是Rackspace的负载平衡器如何告知Web服务器接收请求的协议。


我猜想这可以解释为什么$ server_protocol总是返回HTTP
jwerre

所以您回答了为什么会这样...有关如何解决的任何建议?
jwerre
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.