将Amazon ELB后面的所有http请求重定向到https,而不使用if


27

目前,我有一个同时为http://www.example.orghttps://www.example.org提供服务的ELB 。

我想进行设置,以便任何指向http://www.example.org的请求都重定向到https://www.example.org

ELB将https请求作为http请求发送,因此使用:

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

将不会起作用,因为仍然会向nginx上的端口80 发出对https://www.example.org的请求。

我知道有可能将其重写为

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

但是我读过的所有内容都表明,if应在nginx配置中不惜一切代价避免这种情况,这将针对每个单个请求。另外,这意味着我必须为运行状况检查设置一个特殊的单独配置(如此处所述:“ ...当您位于ELB后面时,ELB充当HTTPS终结点,并且仅向服务器发送HTTP流量,您中断对ELB所需的运行状况检查使用HTTP 200 OK响应进行响应的能力”)。

我正在考虑将登录名放在Web应用程序的代码中,而不是nginx配置中(出于这个问题的目的,我们假设它是基于Django的应用程序),但是我不确定这是否会比在if 配置中。


嗨,您能告诉我您将这些代码放在哪里吗?
俞少林MaculelêLai

@YuAnShaolinMaculelêLai好的。这些是nginx的配置文件,因此我只是将代码放在/etc/nginx/conf.d/中的文件中。我通常将文件命名为domainname.conf,其中“ domainname”是所讨论网站的域。您可以为文件命名,只要它以.conf结尾即可。
Jordan Reiter

非常感谢你。我试图在.conf之后创建一个新文件。但这对我没有用。然后,将代码放在从AWS生成的文件中的/etc/nginx/conf.d/中。现在可以使用了。
俞少林MaculelêLai

Answers:


9

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

重要的是要注意,if的行为不是不一致的,给定两个相同的请求,它不会在一个请求上随机失败而在另一个请求上起作用,并且经过适当的测试和理解是否可以使用。但是,仍然建议使用其他可用的其他指令。


该页面还说“如果在位置上下文中使用时如果有问题”。在我看来,你可以做你需要做的以外什么location {},在server {}代替。(但请让我知道这是否不正确!)
Excalibur

15
  1. 设置将ELB:80映射到instance:80和将ELB:443映射到instance:1443的AWS ELB。
  2. 绑定nginx以监听端口80和1443。
  3. 将到达端口80的请求转发到端口443。
  4. 健康检查应为HTTP:1443。它拒绝HTTP:80,因为301重定向。

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;
   } 

健康检查设置如何?您能否也详细说明一下。
samkhan13年

在将健康检查设置为http:80时,此方法不起作用,运行状况检查失败。
samkhan13,2015年

2
应该进行健康检查HTTP:1443。它拒绝,HTTP:80因为301重定向。
cbron

这大部分对我有用,但是重写行对我的通配符域不起作用。此其他帖子修复了该部分:serverfault.com/questions/447258/…–
罗恩(Ron)

9

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

另外,这不需要在AWS安全设置中打开映像的任何其他端口。您可以在AWS LB中终止ssl,并将https流量路由到实例上的http端口80。

在此示例中,LB运行状况检查在路由到应用程序服务器的端口80上击中/ health,因此运行状况检查可验证nginx和您的应用程序是否在呼吸。

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;
  }
  ...
}

1
一定有一种更优雅的方法可以做到
爱德华(Edward)

0

现在,您可以在AWS Load Balancer设置中创建一个新的侦听器,该侦听器会将HTTP端口80重定向到HTTPS端口443。因此,您无需再触摸nginx / apache配置。


不幸的是,Cloudformation尚未支持它
Aryeh Leib
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.