Эластичный бобовый стебель силы https

12

У меня проблемы с принудительным использованием HTTPS на сайте, который я развертываю через AWS Elastic Beanstalk.

Это интерфейсное приложение, использующее EmberJS. Я много дней ходил кругами, пытаясь понять, как перенаправить http-трафик на https. Я использую Amazon Linux AMI на моей машине EC2.

Я пришел к выводу (все еще не уверен, что это правильно), что не в Elastic Beanstalk я запускаю HTTPS. Я использую HTTP и HTTPS через балансировщик нагрузки Elastic Beanstalk и пытаюсь перенаправить на сервер.

Здесь я сталкиваюсь с проблемами. Я нахожу много ответов о правилах перезаписи, без mod_rewriteкоторых они основаны на X-Forwarded-Protoзаголовке, но этот файл не существует на моей машине EC2 в соответствии с поиском поиска.

Я также попытался создать файл конфигурации в .ebextensionsкаталоге, но это тоже не сработало.

Главное, что я пытаюсь сделать, - это чтобы пользователи обращались к https при попытке попасть на http-адрес. Любые указатели или предложения очень ценятся, спасибо!

РЕДАКТИРОВАТЬ: я использую 64-битный Debian jessie v1.4.1 под управлением Python 3.4 (Preconfigured - Docker)

awwester
источник
Кажется, что Интернет не может договориться об одном, полном и рабочем решении этой проблемы. Надеюсь, вы можете получить помощь здесь, в моем посте . Я должен был прыгать через обручи, чтобы придумать это, наконец.
ADTC

Ответы:

7

Я думаю, вам нужно указать, какую среду Elastic Beanstalk вы используете (см. Поддерживаемые платформы ), потому что разные среды имеют разную конфигурацию.

В основном вам нужно настроить:

  • Эластичный балансировщик нагрузки :
    • Прослушивание порта 80 и прокси его к порту 80 экземпляра EC2.
    • Прослушайте порт 443 и проксируйте его к порту 443 экземпляра EC2.
  • Веб-сервер EC2 / Прокси :
    • Прослушивание порта 80 и ответ перенаправлением на HTTPS.
    • Прослушайте порт 443 и обработайте запрос.

Чтобы настроить его, вы можете использовать CLI или .ebextensions.

Вы можете установить флажки Включить HTTPS и HTTP-Redirect на AWS Elastic Beanstalk . В нем рассказывается, как настроить Elastic Beanstalk Single Docker Container для обслуживания HTTPS и HTTP (перенаправление на HTTPS). Вы можете настроить конфиг как вам нужно.

Эдвард Самуэль
источник
Привет, отличная статья, я пытаюсь это сделать.
Август
Любые идеи о том, как не включать сертификаты в этот файл, не будет ли держать это в системе контроля версий? Сертификаты, которые мы загрузили, уже доступны где-нибудь? Я не могу найти их в файловой системе
awwester
Вы можете поместить свой файл сертификата SSL в S3. Чтобы разрешить Elastic Beanstalk загрузить частный объект S3, вы можете прочитать это .
Эдвард Сэмюэль,
Для получения сертификата ELB SSL вы можете использовать документацию AWS: SSL-сертификаты для эластичной балансировки нагрузки . А затем вы можете получить ресурс сертификата SSL в arn:aws:iam::123456789012:server-certificate/YourSSLCertificateформате.
Эдвард Сэмюэль
У меня настроен SSL-сертификат, и у меня есть арн, который будет идти в 00-балансировщик нагрузки (на самом деле я делаю конфигурацию балансировщика нагрузки через пользовательский интерфейс), но не могу получить местоположение для размещения на сервере настройки ssl_certificate /opt/ssl/default-ssl.crt;Когда я получаю информацию для сертификата, он дает мне «путь», но это просто «/»
awwester
10

Это также можно сделать несколько проще, не касаясь балансировщика нагрузки, используя X-Forwarded-Protoзаголовок, установленный ELB. Вот что я в итоге сделал:

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;
        }
      }
FX
источник
Безусловно самое простое решение. Не могу отблагодарить вас достаточно!
Крис Мартин
Да, это правильный путь в большинстве сценариев.
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 вашими значениями).

Любой трафик через порт 80 подсистемы балансировки нагрузки (HTTP) будет попадать на порт 8080 в экземпляре EC2, который перенаправляет на HTTPS. Трафик через порт 443 на балансировщике нагрузки (HTTPS) будет обслуживаться портом 80 на экземпляре EC2, который является прокси-сервером док-станции.

Майкл де Хуг
источник
0

Я использую Terraform для включения перенаправления HTTP на HTTPS на ElasticBeanstalk,

Я просто добавил дополнительное правило слушателя

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 = ["*.*"]
    }
  }
}
Денис Астахов
источник