简体   繁体   English

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

[英]How can I redirect http to https for Elastic Beanstalk running nginx?

I know there are a lot of SO questions on this exact topic.我知道在这个确切的主题上有很多 SO 问题。 However, none seem to work with the latest version of Elastic Beanstalk / Docker combination.但是,似乎没有一个适用于最新版本的 Elastic Beanstalk / Docker 组合。

I am running a Django/Python web app inside a Docker , which I then deploy to Elastic Beanstalk.我在Docker 中运行Django/Python Web 应用程序,然后将其部署到 Elastic Beanstalk。 I want http and https to be active, so I enabled both port 80 and 443 in the AWS EB configuration console.我希望 http 和 https 处于活动状态,因此我在AWS EB配置控制台中启用了端口80443 This works great.这很好用。 My site is accessible over both http and https.我的网站可以通过 http 和 https 访问。 However, this isn't really what I want.然而,这真的不是我想要的。 I want port 80 ( http ) automatically forward to port 443 ( https ).我希望端口80 ( http ) 自动转发到端口443 ( https )。

I've followed every piece of advice out there on SO and other forums to debug this, but I think the info out there is too old.我已经按照 SO 和其他论坛上的每一条建议来调试这个问题,但我认为那里的信息太旧了。 (Ie., this no longer works). (即, 不再有效)。

I have found where EB sets up its servers (in a file called: /etc/nginx/sites-enabled/elasticbeanstalk-nginx-docker-proxy.conf ), and it's contents are:我找到了 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;
  }
}

When I modify this file from listen 80;当我从listen 80;修改此文件时listen 80; to listen 443 ssl; listen 443 ssl; and the try to load my site on https , I get ERR_CONNECTION_REFUSED .并尝试在https上加载我的网站,我得到ERR_CONNECTION_REFUSED

Can someone point me in the correct direction to modify this config file to redirect from http to https ?有人可以指出我正确的方向来修改这个配置文件以从http重定向到https吗?

As of August 2018, for a Python (Flask) app placed in a Docker container with nginx placed in front and SSL certificate in AWS Certificate Manager.截至 2018 年 8 月,对于放置在Docker容器中的Python (Flask)应用程序, nginx放置在前面,并在 AWS Certificate Manager 中使用 SSL 证书。

After configuring the load balancer to listen on both ports 80 and 443 you can configure the redirection from http to https by creating one file. 将负载均衡器配置为侦听端口 80 和 443 后,您可以通过创建一个文件来配置从 http 到 https 的重定向。 In general, it will add one if statement into an nginx configuration for you:通常,它会为您在 nginx 配置中添加一个if语句:

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

TL;DR: This is done by the following file placed in .ebextensions directory which you create in the parent directory of your Beanstalk app project. TL;DR:这是通过放置在.ebextensions目录中的以下文件完成的,该目录是您在 Beanstalk 应用程序项目的父目录中创建的。 Give the file a chosen name, for eg force-https , but remember to use the .config extension.为文件指定一个选定的名称,例如force-https ,但请记住使用.config扩展名。 Don't forget to commit the new file if you're using git!如果您使用的是 git,请不要忘记提交新文件!

My app/.ebextensions/force-https.config file (YAML - indentation matters!):我的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;
          }
      }

Explanation: If you want the redirection to work for every new deployment and every new EC2 instance that will be started for your app, you need to modify the nginx configuration through Elastic Beanstalk .ebextensions directory.说明:如果您希望重定向适用于每个新部署以及将为您的应用程序启动的每个新 EC2 实例,您需要通过 Elastic Beanstalk .ebextensions目录修改 nginx 配置。 In theory, this change could be done directly in the app's EC2 instance's nginx configuration file (using ssh to connect to the machine), this however is not a good solution, because the changes will be lost when the instance is terminated or when you deploy a new version of the app.理论上,这个改动可以直接在应用的EC2实例的nginx配置文件中完成(使用ssh连接机器),但这不是一个好的解决方案,因为当实例终止或部署时,这些改动都会丢失应用程序的新版本。

The file where we intend to add the aforementioned if statement is placed in /etc/nginx/sites-available/elasticbeanstalk-nginx-docker-proxy.conf in the app's EC2 instance.我们打算添加上述if语句的/etc/nginx/sites-available/elasticbeanstalk-nginx-docker-proxy.conf位于应用程序 EC2 实例的/etc/nginx/sites-available/elasticbeanstalk-nginx-docker-proxy.conf中。 Our file with replacement instructions needs to be created in the .ebextensions directory that you create in the parent directory of your project.我们需要在您在项目父目录中创建的.ebextensions目录中创建带有替换说明的文件。 It needs to specify which files you want to overwrite ( files: in the code above).它需要指定要覆盖的files:files:在上面的代码中)。 Elastic Beanstalk will apply this .config file while deploying your app by overwriting the indicated nginx file in every new machine. Elastic Beanstalk 将在部署您的应用程序时通过覆盖每台新机器中指示的 nginx 文件来应用此.config文件。

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

SECURE_SSL_REDIRECT = True

I assumed you used Python 3.4 with uWSGI 2 (Docker) version 1.4.3 .我假设你使用Python 3.4 和 uWSGI 2 (Docker) version 1.4.3 As my answer in here , you need to coustumized your Elastic Beanstalk environment:正如我在此处的回答,您需要对 Elastic Beanstalk 环境进行 coustumized:

  • Elastic Load Balancer :弹性负载均衡器
    • Listen on port 80 and proxy it to EC2 instance port 80.侦听端口 80 并将其代理到 EC2 实例端口 80。
    • Listen on port 443 and proxy it to EC2 instance port 443.侦听端口 443 并将其代理到 EC2 实例端口 443。
  • EC2 Web Server/Proxy : EC2 Web 服务器/代理
    • Listen on port 80 and response with redirect to HTTPS.侦听端口 80 并响应重定向到 HTTPS。
    • Listen on port 443 and serve the request.侦听端口 443 并为请求提供服务。

I though EB Predefined Python 3.4 (Docker) and Single Docker Container is almost same, except in the Python thing.我虽然 EB Predefined Python 3.4 (Docker) 和 Single Docker Container 几乎相同,除了 Python 之外。 I've written a post in Enable HTTPS and HTTP-Redirect on AWS Elastic Beanstalk .在 AWS Elastic Beanstalk 上启用 HTTPS 和 HTTP 重定向中写了一篇文章。 You could read the guide there.你可以阅读那里的指南。 It tells you how to configure Elastic Beanstalk Single Docker Container serve HTTPS and HTTP (redirect to HTTPS).它告诉您如何配置 Elastic Beanstalk Single Docker Container 服务 HTTPS 和 HTTP(重定向到 HTTPS)。

If you got error (usually if you started it from Elastic Beanstalk sample on first landing page):如果出现错误(通常是从第一个登录页面上的 Elastic Beanstalk 示例启动它):

Updating security group named: sg-xxxxxxxx failed Reason: SecurityGroupEgress cannot be specified without VpcId更新名为:sg-xxxxxxxx 的安全组失败原因:没有 VpcId 无法指定 SecurityGroupEgress

You need to specify your VpcId inside AWSEBLoadBalancerSecurityGroup > Properties .您需要在AWSEBLoadBalancerSecurityGroup > Properties指定您的VpcId So, the config should be:所以,配置应该是:

...
"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"
      }
    ]
  }
},
...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM