如何在Ngix服务器上的AWS中使用Https?

时间:2017-10-11 19:01:29

标签: ruby-on-rails ruby amazon-web-services nginx amazon-ec2

我无法在我的应用程序中使用HTTPS。 首先,我使用路由53上的A Type DNS和Elastic Ip和http工作,但是当我尝试使用https时,我尝试创建一个Load Balancer,并使用A类型的别名,发生503错误。

我做了:

1)在我的域名的DNS面板(registro.br)中添加了4个Amazon DNS: 2)在Amazon Certificate Manager中,我为我的域创建了一个证书;

3)在安全组 - 入站标签中,我包含了HTTPS(HTTPS - TCP - 443 - 0.0.0.0/0)

4)我创建了一个Classic Load Balancer并包含了2个列表器:

  • HTTP - 端口80
  • HTTPS - 端口443 |实例协议HTTP |实例端口80 |关联我的证书(第1步 - ACM亚马逊证书经理)

5)在Amazon Route 53 - Hosted Zones中,我在托管区域中添加了2条记录:

  1. CNAME www,其值为mydomain .com
  2. 键入A IPv4地址|别名是|别名目标:我的负载均衡器
  3. 在我看过的教程中(youtube + internet),只有上面的步骤才能在Amazon EC2上运行。但是,这些教程不适用于NGINX和Ruby On Rails。

    一些印刷品: Load Balancer Route 53

    我的环境:

    操作系统:Ubuntu 14.04.2 LTS ruby -v:ruby 2.2.2p95(2015-04-13修订版50295)[x86_64-linux] rails -v:Rails 4.2.3 nginx -v:nginx / 1.8.0

    来自AWS支持的电子邮件:

    我们看到503错误的原因是因为后端实例未通过ELB运行状况检查而ELB将实例标记为运行状况不佳。如果没有健康的实例,ELB将不会将请求转发到后端实例,并将返回HTTP 503错误代码。 (下面的健康主机计数指标链接)

    因此,现在我们必须验证健康检查失败的原因。一旦我们解决了这个问题,ELB就会将请求发送到你的后端nginx服务器。

    查看一些内部日志,我可以看到您的后端实例为来自负载均衡器节点的运行状况检查请求返回404错误。因此,我针对您的实例34.234.9.186运行了一些测试。

    我注意到autonomosapp.com.br目前指向IP 34.234.9.186。这是我发现的: 卷曲http:// ELASTIC IP /index.html - 响应404找不到错误(您也可以在浏览器上尝试此操作,您将看到404错误) 卷曲http:// autonomosapp。 COM。 br /index.html - 响应200 ok(成功响应)

    虽然这两个请求都指向相同的IP和端口,但输出不同。如果您在nginx配置文件中配置了虚拟主机以根据主机头返回不同的网页,则可能会发生这种情况。 ELB将健康检查请求发送到后端实例的私有IP地址,这些健康检查请求的URL看起来像http:// 172.31.95.37:80 // index.html。由于这些请求在主机头中没有“autonomosapp.com.br”,因此您的后端返回404错误。

    注意:172.31.95.37是您实例的私有IP地址。

    话虽这么说,你必须配置你的nginx服务器,它将为没有主机头的请求返回200ok。

    修改后,要验证是否已正确设置,请从同一VPC中的另一个Linux实例运行以下命令。

    命令:curl -Iv http:// 172.31.95.37:80 //index.html

    如果此命令返回200 ok,则运行状况检查更有可能成功。如果他们仍然失败,请回复我。

    更新:我尝试将nginx配置中启用的网站更改为“”,但错误仍然存​​在

3 个答案:

答案 0 :(得分:0)

我认为错误只是来自你的ELB配置,
如果你真的希望你的nginx在你的EC2上使用 443端口,你需要设置这种类型的监听器

HTTPS - 端口443 |实例协议HTTPS |实习港口443
而不是

  

HTTPS - 端口443 |实例协议HTTP |实例港口80 |

或者您只是将Nginx配置为仅在80端口上侦听,ELB将签名并将443重定向到80,并且所有内容都可以使用HTTPS。

答案 1 :(得分:0)

我解决了:

在nginx / sites-enabled中:

location /elb-health {
  return 200;
  access_log off;
}

将ELB运行状况检查更改为/ elb-heatlh,并将AWS ELB停止更改为返回503

答案 2 :(得分:0)

接受的答案存在一个问题,尽管运行状况检查会删除未运行Web服务器(在这种情况下为nginx)的实例,但无法识别在两者之间接口的uwsgi(或gunicorn或其他)的实例。 Web服务器和您的ruby(或我的django)应用程序正在运行。

这就是我所做的。

  • 首先,我没有建立一个特殊的安全组,假设 负载均衡器可以访问实例,然后进行运行状况检查 能够。事实证明这是一个安全的假设。这并不明显,AWS向后工作是将所有内容都防火墙,然后希望您创建安全组以允许在需要时进行访问。这是一种很好的安全性,但是如果不告诉您“运行状况检查”之类的源的IP地址,则会使故障排除感到困惑。
  • 然后我将ALLOWED_HOSTS设置为['*']。这在django中的作用是它允许从解析为访问服务器的IP的任何域名(包括原始IP)访问应用程序。我不知道AWS运行状况检查将为服务器使用内部IP还是外部IP,并且由于AWS以使用“弹性” IP为荣,所以我不知道任何一个接口IP是否都是静态的。这是非常安全的,因为AWS已经对您的实例进行了防火墙保护,使它们难以访问,无法使用。
  • 我将以下指令放入我的nginx / sites-enabled / conf文件中,该指令标识了'/ health /'端点,并且 not 重定向到https(如果存在)。同样,负载平衡器是唯一能够访问端口80上的实例的东西。
      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;
      }
    
  • 然后,我创建了端点'/ health /'和一个简单的http模板,该模板返回了一个不继承CSS或基本模板中任何内容的简单页面。它只是一个标题。以下是返回的页面,在我的/ etc / hosts中带有crowd88-prodb.py来解析IP。之所以可行,是因为我有一个用于实例的静态IP的安全组。 enter image description here
  • 现在,访问服务于我的Web应用程序的实例时,AWS端口80上的HTTP运行状况检查将返回200 OK,并且如果uwsgi中断或停止,将返回504网关错误,运行状况检查将识别出某些内容错误,然后从负载均衡器中删除该实例。

这与Rackspace相比要容易得多,Rackspace(除了不能像国际上快速提供服务的http请求一样)具有更好的接口来确定工作实例。 Rackspace实际上还具有在线聊天和电话号码以及票证生成服务。我什至无法使用AWS记录故障单,并且所有支持文档都没有提供有关运行状况检查的详细信息。让我感到困扰的另一件事是,经典负载均衡器上确实提供了一个运行状况检查。您无法将其关闭,也无法添加其他支票。考虑到我看到的所有仅针对全职员工的招聘广告都说明了AWS的知识,我认为澳大利亚行业需要考虑其他解决方案,例如Digital Ocean和Rackspace。如果您的站点在世界各地都有客户,那么AWS就是很好的选择,但是如果您的大部分流量都来自同一国家/地区,我认为AWS没有任何优势。