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

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

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

我希望设置它,以便任何指向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;
}

无法工作,因为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在 nginx 配置中应不惜一切代价避免这种情况,并且这将针对每个请求。此外,这意味着我必须为健康检查设置一个特殊的单独配置(如这里所述:“…当您位于 ELB 后面时,ELB 充当 HTTPS 端点并且仅向您的服务器发送 HTTP 流量,您将无法使用 HTTP 200 OK 响应来响应 ELB 所需的健康检查”。

我正在考虑将登录信息放在 Web 应用程序的代码中,而不是 nginx 配置中(为了解决这个问题,我们假设它是一个基于 Django 的应用程序),但我不确定这是否会比配置if 中的开销更大。

答案1

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

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

答案2

  1. 设置您的 AWS ELB 映射 ELB:80 到实例:80,将 ELB:443 映射到实例:1443。
  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;
   } 

答案3

该解决方案使用条件逻辑,但正如接受的答案所暗示的那样,我也认为这是可以的。参考: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;
  }
  ...
}

答案4

您现在可以在 AWS 负载均衡器设置中创建一个新的监听器,将 HTTP 端口 80 重定向到 HTTPS 端口 443。因此,您不再需要触及 nginx/apache 配置。

相关内容