Elastic Beanstalk 强制 https

Elastic Beanstalk 强制 https

我在通过 AWS Elastic Beanstalk 部署的站点强制使用 HTTPS 时遇到了问题。

这是一个使用 EmberJS 的前端应用程序。我花了很多天试图弄清楚如何将 http 流量重定向到 https。我在 EC2 机器上使用 Amazon Linux AMI。

我得出的结论是(仍然不确定这是否正确),我强制使用 HTTPS 的不是 Elastic Beanstalk。我允许 HTTP 和 HTTPS 通过我的 Elastic Beanstalk 负载均衡器,并尝试在服务器上进行重定向。

这是我遇到问题的地方。我找到了很多关于重写规则的答案,mod_rewrite这些答案都是基于X-Forwarded-ProtoHeader 的,但根据 find 搜索,该文件在我的 EC2 机器上不存在。

我也尝试在.ebextensions目录中创建一个配置文件,但是也不起作用。

我主要想做的是让用户在尝试访问 http 地址时直接转到 https。任何指示或建议都非常感谢,谢谢!

编辑:我正在使用运行 Python 3.4 的 64 位 Debian jessie v1.4.1(预配置 - Docker)

答案1

我认为您需要指定您使用的 Elastic Beanstalk 环境(请参阅:支持的平台),因为不同的环境有不同的配置。

基本上,您需要自定义:

  • 弹性负载均衡器
    • 监听端口 80 并将其代理到 EC2 实例端口 80。
    • 监听端口 443 并将其代理到 EC2 实例端口 443。
  • EC2 Web 服务器/代理
    • 监听端口 80 并重定向到 HTTPS 进行响应。
    • 监听端口 443 并处理请求。

要定制它,您可以使用 CLI 或.ebextensions

您可以查看在 AWS Elastic Beanstalk 上启用 HTTPS 和 HTTP 重定向。它告诉您如何配置 Elastic Beanstalk Single Docker Container 服务 HTTPS 和 HTTP(重定向到 HTTPS)。您可以根据需要调整配置。

答案2

通过使用 ELB 设置的标头,也可以更轻松地完成此操作,而无需触及负载均衡器X-Forwarded-Proto。以下是我最终做的事情:

files:
  "/etc/nginx/sites-available/elasticbeanstalk-nginx-docker-proxy.conf":
    mode: "00644"
    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;

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

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

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

答案3

Elastic Beanstalk 不支持单个 Docker 容器的多个端口,因此您需要按照建议在代理级别处理此问题。但是,您的 EC2 实例不需要知道您的证书,因为您可以在负载均衡器上终止 SSL 连接。

在您的.ebextensions目录中,为包含两个服务器配置的 nginx 代理创建一个配置;一个代理http://docker(默认配置,端口 80),另一个重定向到 https(我选择端口 8080)。

.ebextensions/01-nginx-proxy.config

files:
  "/etc/nginx/sites-available/000-default.conf":
    mode: "000644"
    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;

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

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

      server {
          listen 8080;

          location / {
              return 301 https://$host$request_uri;
          }
      }

commands:
   00_enable_site:
    command: 'rm -f /etc/nginx/sites-enabled/* && ln -s /etc/nginx/sites-available/000-default.conf /etc/nginx/sites-enabled/000-default.conf'

为 EB 负载均衡器和安全组创建第二个配置,并按如下方式设置它们:

  • EC2 实例
    • 允许来自负载均衡器的 80/8080 端口上的流量
    • 允许来自任何地方的端口 22 上的流量(用于 ssh 访问,可选)
  • 负载均衡器
    • 将端口 443 HTTPS 转发到端口 80 HTTP
    • 将端口 80 HTTP 转发到端口 8080 HTTP

.ebextensions/02-load-balancer.config

"Resources" : {
  "AWSEBSecurityGroup": {
    "Type" : "AWS::EC2::SecurityGroup",
    "Properties" : {
      "GroupDescription" : "Instance security group (22/80/8080 in)",
      "SecurityGroupIngress" : [ {
          "IpProtocol" : "tcp",
          "FromPort" : "80",
          "ToPort" : "80",
          "SourceSecurityGroupId" : { "Ref" : "AWSEBLoadBalancerSecurityGroup" }
        }, {
          "IpProtocol" : "tcp",
          "FromPort" : "8080",
          "ToPort" : "8080",
          "SourceSecurityGroupId" : { "Ref" : "AWSEBLoadBalancerSecurityGroup" }
        }, {
          "IpProtocol" : "tcp",
          "FromPort" : "22",
          "ToPort" : "22",
          "CidrIp" : "0.0.0.0/0"
        } ]
    }
  },
  "AWSEBLoadBalancerSecurityGroup": {
    "Type" : "AWS::EC2::SecurityGroup",
    "Properties" : {
      "GroupDescription" : "Load balancer security group (80/443 in, 80/8080 out)",
      "VpcId" : "<vpc_id>",
      "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" : "8080",
          "ToPort" : "8080",
          "CidrIp" : "0.0.0.0/0"
        } ]
    }
  },
  "AWSEBLoadBalancer" : {
    "Type" : "AWS::ElasticLoadBalancing::LoadBalancer",
    "Properties" : {
      "Listeners" : [ {
          "LoadBalancerPort" : "80",
          "InstancePort" : "8080",
          "Protocol" : "HTTP"
        }, {
          "LoadBalancerPort" : "443",
          "InstancePort" : "80",
          "Protocol" : "HTTPS",
          "SSLCertificateId" : "arn:aws:iam::<certificate_id>:<certificate_path>"
        } ]
    }
  }
}

(注意:不要忘记用您的值替换 SSLCertificateId 和 VpcId)。

负载均衡器 (HTTP) 端口 80 上的任何流量都将到达 EC2 实例上的端口 8080,该端口将重定向到 HTTPS。负载均衡器 (HTTPS) 端口 443 上的流量最终将由 EC2 实例上的端口 80(即 docker 代理)提供服务。

答案4

我正在使用 Terraform 在 ElasticBeanstalk 上启用 HTTP 到 HTTPS 重定向,

我刚刚添加了额外的监听器规则

data "aws_alb_listener" "http" { //Get ARN of Listener on Port-80
  load_balancer_arn = aws_elastic_beanstalk_environment.myapp.load_balancers[0]
  port              = 80
}


resource "aws_alb_listener_rule" "redirect_http_to_https" {
  listener_arn = data.aws_alb_listener.http.arn
  action {
    type = "redirect"
    redirect {
      port        = "443"
      protocol    = "HTTPS"
      status_code = "HTTP_301"
    }
  }
  condition {
    host_header {
      values = ["*.*"]
    }
  }
}

相关内容