将所有http请求redirect到Amazon ELB,而不使用if

目前我有一个ELB服务于http://www.example.org和https://www.example.org 。

我想设置它,所以任何指向http://www.example.org的请求都会redirect到https://www.example.org 。

ELB将http请求作为http请求发送,所以使用:

server { listen 80; server_name www.example.org; rewrite ^ https://$server_name$request_uri? permanent; } 

将无法工作,因为对https://www.example.org的请求仍将在nginx上的80端口。

我知道有可能把它改写成

 server { listen 80; server_name www.example.org; if ($http_x_forwarded_proto != "https") { rewrite ^(.*)$ https://$server_name$1 permanent; } } 

但是我读过的所有内容都表示, if在nginxconfiguration中应该不惜一切代价来避免这种情况发生,那么每个请求都应该这样做。 此外,这意味着我必须为运行状况检查设置一个特殊的单独configuration( 如下所述 :“…当您在ELB后面,ELB充当HTTPS端点并仅向您的服务器发送HTTPstream量时,打破对ELB需要的健康检查的响应HTTP 200 OK响应的能力“)。

我正在考虑把login到networking应用程序的代码,而不是nginxconfiguration(为了这个问题的目的,让我们假设它是一个基于Django的应用程序),但我不确定是否会更多的开销if在configuration。

如果它正确地工作,不要害怕它。 http://wiki.nginx.org/IfIsEvil

重要的是要注意,if的行为不是不一致的,在两个相同的请求下,它不会随机地失败并且在另一个上工作, 通过适当的testing和理解ifs可以被使用 。 不过,使用其他指令的build议仍然非常适用。

  1. 将您的AWS ELB映射ELB:80设置为实例:80,将ELB:443设置为实例:1443。
  2. 绑定nginx在端口80和1443上收听。
  3. 将到达端口80的请求转发到端口443。
  4. 健康检查应该是HTTP:1443。 它拒绝HTTP:80,因为301redirect。

aws elb设置

NGINX设置

  server { listen 80; server_name www.example.org; rewrite ^ https://$server_name$request_uri? permanent; } server { listen 1443; server_name www.example.org; } 

这个解决scheme使用条件逻辑,但正如接受的答案所暗示的,我也认为这是可以的。 参考: https : //stackoverflow.com/questions/4833238/nginx-conf-redirect-multiple-conditions

而且,这不需要在图像的aws安全设置中打开任何附加的端口。 您可以终止AWS LB中的ssl,并将httpsstream量路由到您实例上的http端口80。

在这个例子中,LB运行状况检查命令/端口80上的健康状态被发送到应用服务器,所以健康检查validationnginx和你的应用正在呼吸。

 server { listen 80 default deferred; set $redirect_to_https 0; if ($http_x_forwarded_proto != 'https') { set $redirect_to_https 1; } if ($request_uri = '/health') { set $redirect_to_https 0; } if ($redirect_to_https = 1) { rewrite ^ https://www.example.com$request_uri? permanent; } ... }