Umleiten des EC2 Elastic Load Balancer von HTTP zu HTTPS

104

Ich möchte die gesamte HTTP-Anfrage an die https-Anfrage auf ELB umleiten . Ich habe zwei EC2-Instanzen. Ich benutze Nginx für den Server. Ich habe versucht, die nginx conf-Dateien ohne Erfolg neu zu schreiben. Ich würde gerne einen Rat dazu bekommen.

Amit Badheka
quelle
1
Es scheint, dass sich das Internet nicht auf eine einzige, vollständige und funktionierende Lösung für dieses Problem einigen kann. Hoffentlich können Sie hier in meinem Beitrag Hilfe bekommen . Ich musste durch Reifen springen, um endlich darauf zu kommen.
ADTC
1
Diese ans hat die neueste Lösung, nicht die akzeptierte anser
AsifM

Antworten:

87

AWS Application Load Balancer unterstützen jetzt die native HTTP-zu-HTTPS-Umleitung.

Gehen Sie wie folgt vor, um dies in der Konsole zu aktivieren:

  1. Gehen Sie zu Ihrem Load Balancer in EC2 und klicken Sie auf "Listener".
  2. Wählen Sie in Ihrem HTTP-Listener "Regeln anzeigen / bearbeiten"
  3. Löschen Sie alle Regeln außer der Standardregel (unten).
  4. Standardregel bearbeiten: Wählen Sie als Aktion "Umleiten nach", lassen Sie alles als Standard und geben Sie "443" als Port ein.

Native Redirect-Listener-Regel

Dasselbe kann durch Verwendung der hier beschriebenen CLI erreicht werden .

Dies ist auch in Cloudformation möglich, wo Sie ein Listener-Objekt wie folgt einrichten müssen:

  HttpListener:
    Type: AWS::ElasticLoadBalancingV2::Listener
    Properties:
      LoadBalancerArn: !Ref LoadBalancer
      Port: 80
      Protocol: HTTP
      DefaultActions:
      - Type: redirect 
        RedirectConfig:
          Protocol: HTTPS
          StatusCode: HTTP_301
          Port: 443

Wenn Sie weiterhin klassische Load Balancer verwenden, wählen Sie eine der von den anderen beschriebenen NGINX-Konfigurationen.

Ulli
quelle
1
Sehr nützlich zu wissen, dass es jetzt einfacher ist. Dies wäre jedoch eine bessere Antwort mit mehr Informationen darüber, was konfiguriert werden soll, anstatt nur einem Link.
John Rees
1
@ JohnRees hat die Antwort entsprechend bearbeitet, hoffe das hilft
Ulli
Nett. Ich habe dich gestimmt, um dich auf Null zu bringen. Du verdienst mehr.
John Rees
2
@florian Sie scheinen einen Classic Load Balancer zu verwenden. Wechseln Sie zu Application Load Balancer, um diese Option zu erhalten
Ulli
Wie ordne ich den Application Load Balancer meiner Instanz zu? (da es keine instancesRegisterkarte gibt)
Florian
107

ELB setzt X-Forwarded-Proto Header. Sie können ihn verwenden, um festzustellen, ob die ursprüngliche Anforderung HTTP war, und dann zu HTTPS umleiten.

Sie können dies in Ihrem versuchen server conf :

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

Schauen Sie sich die ELB-Dokumente an .

Dmitry Mukhin
quelle
3
Wo macht man diese Konfiguration?
Ericpeters0n
2
@ ericpeters0n Das Snippet in der Antwort ist für die nginxKonfiguration, aber das Prinzip gilt für jeden Webserver.
Dmitry Mukhin
1
Wenn Sie Beanstalk mit Passagier-Standalone verwenden, folgen Sie diesem Link, um zu erfahren, wie Sie die Nginx-Konfiguration ändern können. qiita.com/tak_nishida/items/cf30a2d373744943b943
Yeonho
3
Stellen Sie sicher, dass Ihr Load Balancer über HTTP- und HTTPS-Listener verfügt.
Gavin Palmer
1
@Ronald, mit Server Conf in der Antwort meine ich Nginx Server auf Ec2-Instanzen, die hinter ELB ausgeführt werden.
Dmitry Mukhin
34

Ich hatte das gleiche Problem. In meiner Situation wurde HTTPS vollständig von ELB verwaltet und ich kannte meine Quelldomäne nicht im Voraus, sodass ich am Ende Folgendes tat:

server {
  listen 81;
  return 301 https://$host$request_uri;
}

server {
  listen 80;
  # regular server rules ...
}

Und dann natürlich das ELB 'https' auf den Instanzport 80 und dann die 'http'-Route auf den Instanzport 81 zeigen.

TylerFowler
quelle
3
Das ist Genie.
Andy Hayden
2
@CodyBugstein Dies ist Nginx-Konfiguration, wenn Sie eine haben
Timurso
@ Timurso wenn du eins hast was?
CodyBugstein
@CodyBugstein, wenn Sie Nginx vor Ihrer Anwendung haben (ich zum Beispiel nicht - es wird direkt an einen Container weitergeleitet, auf dem ExpressJS ausgeführt wird)
timurso
Wohin würde der Nginx gehen? In der ELB? In der EC2? Ist dies irgendwo in Elastic Beanstalk konfiguriert?
CodyBugstein
16

Der Amazon Elastic Load Balancer (ELB) unterstützt einen HTTP-Header namens X-FORWARDED-PROTO. Alle HTTPS-Anforderungen, die die ELB durchlaufen, haben den Wert X-FORWARDED-PROTO gleich "HTTPS". Für die HTTP-Anforderungen können Sie HTTPS erzwingen, indem Sie die folgende einfache Umschreiberegel hinzufügen. Bei mir funktioniert es gut!

Apache

Sie können Ihrer .htaccess-Datei folgende Zeilen hinzufügen:

RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI}

Wenn Sie vhost.conf zum Verwalten mehrerer Domänen auf demselben EC2-Webserver verwenden, können Sie der vhost.conf Folgendes hinzufügen (fügen Sie es der Domäne hinzu, für die Sie https verwenden möchten):

<VirtualHost *:80>
...
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI}
...
</VirtualHost>

IIS

Installieren Sie das IIS Url-Rewrite-Modul und fügen Sie über die Konfigurations-GUI die folgenden Einstellungen hinzu:

<rewrite xdt:Transform="Insert">
<rules>
<rule name="HTTPS rewrite behind ELB rule" stopProcessing="true">
<match url="^(.*)$" ignoreCase="false" />
<conditions>
<add input="{HTTP_X_FORWARDED_PROTO}" pattern="^http$" ignoreCase="false" />
</conditions>
<action type="Redirect" redirectType="Found" url="https://{SERVER_NAME}{URL}" />
</rule>
</rules>
</rewrite>

Lesen Sie hier mehr

Iman Sedighi
quelle
Wir hatten das Problem, dass unsere Instanz normalen HTTP-Verkehr umleitet, da der Header nicht einmal vorhanden war. Ich löse es, indem ich die Bedingung mache:RewriteCond %{HTTP:X-Forwarded-Proto} !(https|^$)
Natronit
Dies führt zu unendlichen Weiterleitungen. Ich verwende IIS mit Windows Server.
Es ist eine Falle
@ It'satrap: Wenn es für IIS nicht funktioniert hat, versuchen Sie das Skript unter dieser URL: stephen.genoprime.com/2012/01/01/aws-elb-ssl-with-iis.html
Iman Sedighi
4

Es ist möglicherweise nicht die Lösung, nach der Sie suchen, aber eine andere Option könnte darin bestehen, AWS CloudFront zusätzlich zu ELB zu verwenden. CloudFront bietet die Option, den gesamten eingehenden HTTP-Verkehr an HTTPS umzuleiten.

MojoJojo
quelle
4

Die oben genannten htaccess-Lösungen haben dazu geführt, dass die ELB-Integritätsprüfung fehlgeschlagen ist. Ich hatte einige Probleme, die Lösung zu finden, bis ich online einen Artikel entdeckte, in dem jemand die gleichen Probleme hatte wie ich. Seine Lösung bestand darin, dies stattdessen am Anfang der htaccess-Datei hinzuzufügen:

RewriteEngine on 
RewriteCond %{HTTP:X-Forwarded-Proto} ^http$
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

Um diese und andere lokale Anforderungen über HTTP zuzulassen, während externe Anforderungen über die ELB an HTTPS umgeleitet werden, passen Sie die Umschreibungsbedingung so an, dass sie mit http übereinstimmt, anstatt mit https.

Quelle: Umleiten von HTTP zu HTTPS mit AWS und ELB

Omikes
quelle
"Passen Sie die Umschreibungsbedingung so an, dass sie mit http übereinstimmt, anstatt mit einer negativen Übereinstimmung mit https". Dies ist der Teil, den ich zu beheben versuchte. Danke dir!
Merricat
3

Ich hatte ein seltsames Problem mit der Nginx- und ELB-Konfiguration. Mein Setup umfasste 3 verschiedene Dienste in einem Nginx hinter ELB. Und ich hatte ein Problem mit gemischten Inhalten: Wenn Ihre Anfrage an ELB https ist, aber nur innerhalb von ELB http, und der Server mithilfe von http einen relativen Pfad zu statisch erstellt, schlägt der Browser mit dem Problem mit gemischten Inhalten fehl. Und ich muss eine Lösung für beide http / https-Arbeiten ohne Weiterleitungen erstellen.

Hier befindet sich die Konfiguration in nginx/conf.d/ Ordner:

# Required for http/https switching
map $http_x_forwarded_port $switch {
  default   off;
  "80"    off;
  "443"   on;
}

Dies bedeutet, dass wir wissen, was ein echtes Client-Protokoll ist. Wie Sie sehen können, werden wir es haben$switch var haben. Und in diesem Moment verwenden Sie dies an allen Orten, an denen Sie es benötigen:

location ~ /softwareapi/index.php {
  fastcgi_param HTTPS $switch;
  .. other settings here ..
}

Mit der HTTPS-Einstellung erkennt die PHP-Anwendung automatisch das richtige Protokoll und erstellt sorgfältig einen relativen Pfad, um Probleme mit gemischten Inhalten zu vermeiden.

Freundliche Grüße.

Oleg Mykolaichenko
quelle
3

Basierend auf der Antwort von @ Ulli Wenn Sie es mit Terraform konfigurieren möchten, finden Sie hier ein Beispiel>

resource "aws_alb_listener" "web" {
  load_balancer_arn = "${aws_alb.web.arn}"

  port              = "80"
  protocol          = "HTTP"

  default_action {
    type = "redirect"

    redirect {
      port        = "443"
      protocol    = "HTTPS"
      status_code = "HTTP_301"
    }
  }
}

Quelle

Mathieu Lescaudron
quelle
-2

Erstellen Sie eine Datei .ebextensions/00_forward_http_to_https.configmit folgendem Inhalt:

files: 
  /tmp/deployment/http_redirect.sh:
    mode: "000755"
    content: |
      APP_URL=`/opt/elasticbeanstalk/bin/get-config environment --output yaml | grep -oP 'APP_URL: \K([^\s)\"](?!ttp:))+'`
      sed -ie 's@$proxy_add_x_forwarded_for;@$proxy_add_x_forwarded_for;\n        if ($http_x_forwarded_proto = 'http') { return 301 https://'"$APP_URL"'$request_uri; }@' /tmp/deployment/config/#etc#nginx#conf.d#00_elastic_beanstalk_proxy.conf

container_commands:
  http_redirect:
    command: "/tmp/deployment/http_redirect.sh"

Stellen Sie sicher, dass Sie die Umgebungsvariable APP_URL zuvor in der AWS-Verwaltungskonsole festgelegt haben.

Andres
quelle
Wie kann ich dies tun, wenn TCP-Verbindungen mit ELB ausgeglichen werden?
Boom
1
Ich sehe nicht, wo Ihre Antwort zu der Frage passt ... Sie sprechen von elastischem Bohnenstiel und die Frage handelt von Nginx in einem EC2.
Jvarandas