Elastyczna siła Beanstalk wymusza https

12

Mam problemy z wymuszaniem HTTPS w witrynie wdrażanej za pomocą AWS Elastic Beanstalk.

Jest to aplikacja frontendowa wykorzystująca EmberJS. Od wielu dni chodzę w kółko, próbując dowiedzieć się, jak przekierować ruch HTTP na https. Używam Amazon Linux AMI na moim komputerze EC2.

Doszedłem do wniosku (wciąż nie jestem pewien, czy to prawda), że wymuszanie HTTPS nie obejmuje Elastic Beanstalk. Zezwalam zarówno na HTTP, jak i HTTPS przez moduł równoważenia obciążenia Elastic Beanstalk i próbuję przekierować na serwer.

To tutaj napotykam problemy. Znajduję wiele odpowiedzi na temat reguł przepisywania, bez mod_rewritektórych są one oparte na X-Forwarded-Protonagłówku, ale ten plik nie istnieje na moim komputerze EC2 zgodnie z wyszukiwaniem wyszukiwania.

Próbowałem również utworzyć plik konfiguracyjny w .ebextensionskatalogu, ale to też nie działało.

Najważniejsze, co próbuję zrobić, to skierować użytkowników do https, gdy próbują trafić na adres http. Wszelkie wskazówki lub sugestie są bardzo mile widziane, dzięki!

EDYCJA: Używam 64-bitowej wersji Debian jessie v1.4.1 z Pythonem 3.4 (wstępnie skonfigurowanym - dokerem)

awwester
źródło
Wydaje się, że Internet nie może zgodzić się na jedno, kompletne i działające rozwiązanie tego problemu. Mam nadzieję, że możesz uzyskać pomoc tutaj w moim poście . W końcu musiałem skakać przez obręcze, żeby to wymyślić.
ADTC

Odpowiedzi:

7

Myślę, że musisz określić, jakiego środowiska Elastic Beanstalk używasz (patrz: Obsługiwane platformy ), ponieważ inne środowisko ma inną konfigurację.

Zasadniczo musisz dostosować:

  • Elastyczny moduł równoważenia obciążenia :
    • Nasłuchuj na porcie 80 i proxy do portu 80 instancji EC2.
    • Nasłuchuj na porcie 443 i proxy do portu 443 instancji EC2.
  • Serwer internetowy / serwer proxy EC2 :
    • Nasłuchuj na porcie 80 i odpowiedz przekierowaniem do HTTPS.
    • Nasłuchuj na porcie 443 i obsłuż żądanie.

Aby go dostosować, możesz użyć CLI lub .ebextensions.

Możesz zaznaczyć opcję Włącz HTTPS i przekierowanie HTTP na AWS Elastic Beanstalk . Informuje o tym, jak skonfigurować elastyczny kontener Docker z pojedynczym dokowaniem do obsługi HTTPS i HTTP (przekierowanie do HTTPS). Możesz dostosować konfigurację do swoich potrzeb.

Edward Samuel
źródło
hej, świetny artykuł, właśnie próbuję tego.
awwester
jakieś pomysły na to, jak nie uwzględniać certyfikatów w tym pliku, wolałby raczej nie kontrolować tego źródła? Czy certyfikaty, które załadowaliśmy, są już gdzieś dostępne? Nie mogę ich znaleźć w systemie plików
awwester
Możesz umieścić plik certyfikatu SSL w S3. Aby umożliwić Elastic Beanstalk pobierania S3 prywatny obiekt, można przeczytać ten .
Edward Samuel
W przypadku certyfikatu ELB SSL można postępować zgodnie z dokumentacją AWS: Certyfikaty SSL do elastycznego równoważenia obciążenia . Następnie możesz uzyskać zasób certyfikatu SSL w arn:aws:iam::123456789012:server-certificate/YourSSLCertificateformacie.
Edward Samuel
Mam skonfigurowany certyfikat SSL i mam arn, który przejdzie do modułu równoważenia obciążenia 00 (właściwie wykonuję konfigurację modułu równoważenia obciążenia za pośrednictwem interfejsu użytkownika), ale wydaje się, że nie mogę uzyskać lokalizacji do umieszczenia na serwerze ustawienia ssl_certificate /opt/ssl/default-ssl.crt;Gdy otrzymam informacje o certyfikacie, daje mi to „ścieżkę”, ale jest to po prostu „/”
awwester
10

Można to również zrobić nieco łatwiej, bez dotykania modułu równoważenia obciążenia, za pomocą X-Forwarded-Protozestawu nagłówków ustawionego przez ELB. Oto, co skończyłem:

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
źródło
Zdecydowanie najłatwiejsze rozwiązanie. Nie mogę ci wystarczająco podziękować!
Chris Martin
Tak, jest to właściwy sposób w większości scenariuszy.
jlegler
3

Elastic Beanstalk nie obsługuje wielu portów z kontenera Single Docker, więc musisz obsłużyć to na poziomie proxy, jak sugerowano. Jednak instancja EC2 nie musi wiedzieć o certyfikacie, ponieważ można przerwać połączenie SSL w module równoważenia obciążenia.

W swoim .ebextensionskatalogu utwórz konfigurację serwera proxy nginx, która zawiera dwie konfiguracje serwera; jeden, który proxy http://docker(konfiguracja domyślna, port 80) i ten, który przekierowuje do https (wybrałem port 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'

Utwórz drugą konfigurację modułu równoważenia obciążenia EB i grup zabezpieczeń, który ustawia je w następujący sposób:

  • Instancja EC2 :
    • Zezwól na ruch na portach 80/8080 z modułu równoważenia obciążenia
    • Zezwól na ruch na porcie 22 z dowolnego miejsca (dla dostępu ssh, opcjonalnie)
  • Moduł równoważenia obciążenia :
    • Przekaż port 443 HTTPS na port 80 HTTP
    • Przekaż port 80 HTTP na port 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>"
        } ]
    }
  }
}

(Uwaga: nie zapomnij zastąpić SSLCertificateId i VpcId własnymi wartościami).

Każdy ruch na porcie 80 modułu równoważenia obciążenia (HTTP) trafi na port 8080 w instancji EC2, który przekierowuje do HTTPS. Ruch na porcie 443 w module równoważenia obciążenia (HTTPS) będzie obsługiwany przez port 80 w instancji EC2, która jest serwerem proxy dokera.

Michael de Hoog
źródło
0

Korzystam z Terraform, aby umożliwić przekierowanie HTTP na HTTPS na ElasticBeanstalk,

Właśnie dodałem dodatkową Regułę Listenera

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 = ["*.*"]
    }
  }
}
Denis Astahov
źródło