如何将http重定向到运行nginx的Elastic Beanstalk的https?

时间:2015-04-30 00:37:29

标签: http docker nginx https elastic-beanstalk

我知道在这个确切的主题上有很多SO问题。但是,似乎没有一个适用于最新版本的Elastic Beanstalk / Docker组合。

我在 Docker 中运行 Django / Python Web应用程序,然后将其部署到Elastic Beanstalk。我希望http和https处于活动状态,因此我在 AWS EB 配置控制台中启用了 80 443 端口。这非常有效。我的网站可通过http和https访问。但是,这并不是我想要的。我希望端口 80 http )自动转发到端口 443 https )。

我已经在SO和其他论坛上关注了每一条建议来调试这个,但我认为那里的信息太旧了。 (即this不再有效。)

我找到了EB设置其服务器的位置(在名为/etc/nginx/sites-enabled/elasticbeanstalk-nginx-docker-proxy.conf的文件中),其内容为:

map $http_upgrade $connection_upgrade {
  default  "upgrade";
  ""       "";
}

server {
  listen 80;
  location / {
    proxy_pass          http://docker;
    proxy_http_version  1.1;
    proxy_set_header    Connection       $connection_upgrade;
    proxy_set_header    Upgrade          $http_upgrade;
    proxy_set_header    Host             $host;
    proxy_set_header    X-Real-IP        $remote_addr;
    proxy_set_header    X-Forwarded-For  $proxy_add_x_forwarded_for;
  }
}

当我将此文件从listen 80;修改为listen 443 ssl;并尝试在 https 上加载我的网站时,我得到ERR_CONNECTION_REFUSED

有人能指出我正确的方向修改此配置文件以从 http 重定向到 https 吗?

3 个答案:

答案 0 :(得分:1)

我假设您使用了Python 3.4 with uWSGI 2 (Docker) version 1.4.3。正如我在here中的回答,您需要完善您的Elastic Beanstalk环境:

  • 弹性负载均衡器
    • 侦听端口80并将其代理到EC2实例端口80。
    • 侦听端口443并将其代理到EC2实例端口443。
  • EC2网络服务器/代理
    • 侦听端口80并通过重定向到HTTPS进行响应。
    • 收听端口443并提供请求。

我虽然EB Predefined Python 3.4(Docker)和Single Docker Container几乎相同,但在Python中除外。我在Enable HTTPS and HTTP-Redirect on AWS Elastic Beanstalk写了一篇文章。你可以在那里阅读指南。它告诉您如何配置Elastic Beanstalk单Docker容器服务HTTPS和HTTP(重定向到HTTPS)。

如果您收到错误(通常是在第一个登录页面上从Elastic Beanstalk示例启动它):

  

更新名为:sg-xxxxxxxx的安全组失败原因:如果没有VpcId,则无法指定SecurityGroupEgress

您需要在VpcId内指定AWSEBLoadBalancerSecurityGroup > Properties。所以,配置应该是:

...
"AWSEBLoadBalancerSecurityGroup": {
  "Type": "AWS::EC2::SecurityGroup",
  "Properties": {
    "GroupDescription": "Allow HTTP and HTTPS",
    "VpcId": "vpc-xxxxxxxx",
    "SecurityGroupIngress": [
      {
        "IpProtocol": "tcp",
        "FromPort": 80,
        "ToPort": 80,
        "CidrIp": "0.0.0.0/0"
      },
      {
        "IpProtocol": "tcp",
        "FromPort": 443,
        "ToPort": 443,
        "CidrIp": "0.0.0.0/0"
      }
    ],
    "SecurityGroupEgress": [
      {
        "IpProtocol": "tcp",
        "FromPort": 80,
        "ToPort": 80,
        "CidrIp": "0.0.0.0/0"
      },
      {
        "IpProtocol": "tcp",
        "FromPort": 443,
        "ToPort": 443,
        "CidrIp": "0.0.0.0/0"
      }
    ]
  }
},
...

答案 1 :(得分:1)

截至2018年8月,对于放置在 Docker 容器中且 nginx 位于前面且SSL证书位于其中的 Python(Flask)应用程序AWS Certificate Manager。

configuring the load balancer上监听端口80和443之后,您可以通过创建一个文件来配置从http到https的重定向。通常,它将为您在nginx配置中添加一个if语句:

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

TL; DR:这是通过放置在.ebextensions目录中的以下文件来完成的,该文件是在Beanstalk应用程序项目的父目录中创建的。为文件指定一个选定的名称,例如force-https,但请记住使用 .config 扩展名。如果您使用的是git,请不要忘记提交新文件!

我的app/.ebextensions/force-https.config文件(YAML-缩进很重要!):

files:

  "/etc/nginx/sites-available/elasticbeanstalk-nginx-docker-proxy.conf" :
    mode: "000755"
    owner: root
    group: root
    content: |
      map $http_upgrade $connection_upgrade {
          default        "upgrade";
          ""            "";
      }

      server {
          listen 80;

          gzip on;
              gzip_comp_level 4;
              gzip_types text/html text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;

          if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})T(\d{2})") {
              set $year $1;
              set $month $2;
              set $day $3;
              set $hour $4;
          }
          access_log /var/log/nginx/healthd/application.log.$year-$month-$day-$hour healthd;

          access_log    /var/log/nginx/access.log;

          location / {
              if ($http_x_forwarded_proto = 'http') {
                  return 301 https://$host$request_uri;
              }
              proxy_pass            http://docker;
              proxy_http_version    1.1;

              proxy_set_header    Connection            $connection_upgrade;
              proxy_set_header    Upgrade                $http_upgrade;
              proxy_set_header    Host                $host;
              proxy_set_header    X-Real-IP            $remote_addr;
              proxy_set_header    X-Forwarded-For        $proxy_add_x_forwarded_for;
          }
      }

说明::如果您希望重定向适用于将为您的应用启动的每个新部署以及每个新的EC2实例,则需要通过Elastic Beanstalk {{1} } 目录。从理论上讲,可以直接在应用程序的EC2实例的nginx配置文件中完成此更改(使用.ebextensions连接到计算机),但这不是一个好的解决方案,因为在实例终止时更改将丢失或部署新版本的应用程序时。

我们要在其中添加上述ssh语句的文件位于应用程序EC2实例的if中。我们需要在您的项目的父目录中创建的/etc/nginx/sites-available/elasticbeanstalk-nginx-docker-proxy.conf目录中创建带有替换说明的文件。它需要指定要覆盖的文件(上面的代码中的.ebextensions)。在部署应用程序时,Elastic Beanstalk将通过在每台新计算机上覆盖指示的nginx文件来应用此files:文件。

答案 2 :(得分:0)

您是否尝试过在settings.py中进行配置,并让django处理该过程。

SECURE_SSL_REDIRECT = True