弹性Beanstalk力https


12

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

这是使用EmberJS的前端应用程序。我已经绕了很多天,试图弄清楚如何将HTTP流量重定向到https。我在我的EC2计算机上使用Amazon Linux AMI。

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

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

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

我想做的主要事情是让用户在尝试访问http地址时被定向到https。任何指针或建议都非常感谢,谢谢!

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


互联网似乎无法就此问题达成单一,完整且有效的解决方案。希望您能在我的帖子中得到一些帮助。最后,我不得不跳了圈才想到这个。
ADTC '11

Answers:


7

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

基本上,您需要自定义:

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

要自定义它,可以使用CLI或.ebextensions

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


嘿,很棒的文章,我正在尝试中。
2015年

关于如何不将证书包含在该文件中的任何想法,宁愿不将其保留在源代码管理中?我们加载的证书已经在某个地方可用吗?我似乎在文件系统上找不到它们
大约

您可以将SSL证书文件放在S3中。要允许Elastic Beanstalk下载私有S3对象,可以阅读this
爱德华·塞缪尔

对于ELB SSL证书,您可以遵循AWS文档:Elastic Load Balancing的SSL证书。然后,您可以获取arn:aws:iam::123456789012:server-certificate/YourSSLCertificate格式的SSL证书资源。
爱德华·塞缪尔

我已经设置了SSL证书,并且已经在00-load-balancer中使用了arn(我实际上是通过UI进行负载均衡器配置),但是似乎无法获得放置在服务器中的位置设置ssl_certificate /opt/ssl/default-ssl.crt;当我获得证书的信息时,它给了我一个“路径”,但它只是“ /”
2015年

10

通过使用X-Forwarded-ProtoELB设置的标头,也可以在不接触负载均衡器的情况下更轻松地完成此操作。这就是我最终要做的事情:

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

到目前为止,最简单的解决方案。感激不尽!
克里斯·马丁

是的,在大多数情况下这都是正确的方法。
jlegler

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实例(即Docker代理)上的端口80提供服务。


0

我使用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 = ["*.*"]
    }
  }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.