Elastische Bohnenstielkraft https

12

Ich habe Probleme beim Erzwingen von HTTPS mit einer Site, die ich über AWS Elastic Beanstalk bereitstelle.

Es ist eine Frontend-Anwendung mit EmberJS. Ich bin seit vielen Tagen im Kreis herumgegangen und habe versucht, herauszufinden, wie man http-Verkehr zu https umleitet. Ich verwende Amazon Linux AMI auf meinem EC2-Computer.

Ich bin zu dem Schluss gekommen (immer noch nicht sicher, ob dies richtig ist), dass es nicht innerhalb von Elastic Beanstalk liegt, dass ich HTTPS erzwinge. Ich erlaube HTTP und HTTPS über meinen Elastic Beanstalk Load Balancer und versuche, auf dem Server eine Umleitung durchzuführen.

Hier stoße ich auf Probleme. Ich finde viele Antworten zu Umschreiberegeln, mod_rewritedie nicht auf dem X-Forwarded-ProtoHeader basieren , aber diese Datei existiert laut einer Suchabfrage nicht auf meinem EC2-Computer.

Ich habe auch versucht, eine Konfigurationsdatei im .ebextensionsVerzeichnis zu erstellen , aber das hat auch nicht funktioniert.

Das Wichtigste, was ich versuche, ist, dass Benutzer zu https geleitet werden, wenn sie versuchen, die http-Adresse zu erreichen. Alle Hinweise oder Vorschläge sind sehr dankbar, danke!

BEARBEITEN: Ich verwende 64-Bit-Debian-Jessie v1.4.1, auf dem Python 3.4 (vorkonfiguriert - Docker) ausgeführt wird.

awwester
quelle
Es scheint, dass das Internet sich nicht auf eine einzige, vollständige und funktionierende Lösung für dieses Problem einigen kann. Hoffentlich können Sie hier in meinem Beitrag etwas Hilfe bekommen . Ich musste endlich durch die Reifen springen, um das zu finden.
ADTC

Antworten:

7

Ich denke, Sie müssen angeben, welche Elastic Beanstalk-Umgebung Sie verwenden (siehe: Unterstützte Plattformen ), da unterschiedliche Umgebungen unterschiedliche Konfigurationen haben.

Grundsätzlich müssen Sie Folgendes anpassen:

  • Elastic Load Balancer :
    • Lauschen Sie dem Port 80 und übertragen Sie ihn als Proxy an den EC2-Instanz-Port 80.
    • Lauschen Sie dem Port 443 und übertragen Sie ihn als Proxy an den EC2-Instanz-Port 443.
  • EC2 Web Server / Proxy :
    • Lauschen Sie auf Port 80 und antworten Sie mit einer Weiterleitung an HTTPS.
    • Lauschen Sie Port 443 und bedienen Sie die Anfrage.

Zum Anpassen können Sie CLI oder verwenden .ebextensions.

Sie können HTTPS und HTTP-Redirect in AWS Elastic Beanstalk aktivieren . Hier erfahren Sie, wie Sie Elastic Beanstalk Single Docker Container für HTTPS und HTTP konfigurieren (Weiterleitung an HTTPS). Sie können die Konfiguration nach Bedarf anpassen.

Edward Samuel
quelle
Hey, toller Artikel, ich versuche es gerade.
Awwester
Irgendwelche Ideen, wie man die Zertifikate nicht in diese Datei einbindet, lieber nicht in der Quellcodeverwaltung belassen soll? Sind die Zertifikate, die wir geladen haben, bereits irgendwo verfügbar? Ich kann sie anscheinend nicht im Dateisystem finden
awwester
Sie können Ihre SSL-Zertifikatdatei in S3 ablegen. Elastic Beanstalk Download privaten S3 - Objekt zu ermöglichen, können Sie lesen diese .
Edward Samuel
Für das ELB-SSL-Zertifikat können Sie der AWS-Dokumentation folgen: SSL-Zertifikate für Elastic Load Balancing . Anschließend können Sie die SSL-Zertifikatsressource im arn:aws:iam::123456789012:server-certificate/YourSSLCertificateFormat abrufen.
Edward Samuel
Ich habe das SSL-Zertifikat eingerichtet und ich habe die ARN, die in 00-Load-Balancer gehen würde (ich mache eigentlich die Load-Balancer-Konfiguration über die Benutzeroberfläche), aber kann nicht scheinen, den Ort in den Server zu bringen Einstellungen ssl_certificate /opt/ssl/default-ssl.crt;Wenn ich die Informationen für das Zertifikat erhalte, erhalte ich einen "Pfad", aber es ist nur "/"
awwester
10

Dies ist auch etwas einfacher möglich, ohne den Load Balancer zu berühren, indem der X-Forwarded-Protovon ELB festgelegte Header verwendet wird. Folgendes habe ich letztendlich getan:

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
quelle
Mit Abstand die einfachste Lösung. Ich kann dir nicht genug danken!
Chris Martin
Ja, das ist in den meisten Szenarien der richtige Weg.
Jlegler
3

Elastic Beanstalk unterstützt nicht mehrere Ports von einem einzelnen Docker-Container, daher müssen Sie dies wie empfohlen auf Proxy-Ebene tun. Ihre EC2-Instanz muss jedoch nichts über Ihr Zertifikat wissen, da Sie die SSL-Verbindung am Load Balancer beenden können.

.ebextensionsErstellen Sie in Ihrem Verzeichnis eine Konfiguration für den Nginx-Proxy, die zwei Serverkonfigurationen enthält. einer, der Proxys http://docker(die Standardkonfiguration, Port 80) und einer, der zu https umleitet (ich habe Port 8080 gewählt).

.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'

Erstellen Sie eine zweite Konfiguration für den EB-Load-Balancer und die Sicherheitsgruppen, die diese wie folgt einrichten:

  • EC2-Instanz :
    • Ermöglichen Sie den Datenverkehr auf den Ports 80/8080 von Load Balancer
    • Zulassen von Datenverkehr auf Port 22 von überall (für SSH-Zugriff optional)
  • Load Balancer :
    • Leiten Sie Port 443 HTTPS an Port 80 HTTP weiter
    • Leiten Sie Port 80 HTTP an Port 8080 HTTP weiter

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

(Hinweis: Vergessen Sie nicht, SSLCertificateId und VpcId durch Ihre Werte zu ersetzen.)

Jeglicher Datenverkehr auf Port 80 des Lastenausgleichs (HTTP) trifft auf Port 8080 der EC2-Instanz, die zu HTTPS umleitet. Der Datenverkehr auf Port 443 des Load Balancer (HTTPS) wird über Port 80 der EC2-Instanz, dem Docker-Proxy, bedient.

Michael de Hoog
quelle
0

Ich verwende Terraform, um die HTTP-zu-HTTPS-Umleitung auf ElasticBeanstalk zu aktivieren.

Ich habe gerade eine zusätzliche Listener-Regel hinzugefügt

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
quelle