Leiten Sie alle http-Anforderungen hinter Amazon ELB zu https um, ohne if zu verwenden

27

Derzeit habe ich eine ELB, die sowohl http://www.example.org als auch https://www.example.org bedient .

Ich möchte es so einrichten, dass jede Anfrage, die auf http://www.example.org verweist, auf https://www.example.org umgeleitet wird .

Die ELB sendet die https-Anforderungen als http-Anforderungen. Verwenden Sie dazu:

server {
      listen         80;
       server_name    www.example.org;
       rewrite        ^ https://$server_name$request_uri? permanent;
}

funktioniert nicht, da Anforderungen an https://www.example.org weiterhin an Port 80 unter nginx gesendet werden.

Ich weiß, es ist möglich, es als umzuschreiben

server {
      listen         80;
      server_name    www.example.org;
      if ($http_x_forwarded_proto != "https") {
          rewrite ^(.*)$ https://$server_name$1 permanent;
      }
}

Aber alles, was ich gelesen habe, ifsollte unbedingt in der Nginx-Konfiguration vermieden werden, und dies wäre für jede einzelne Anfrage. Dies bedeutet auch, dass ich eine spezielle separate Konfiguration für die Integritätsprüfung einrichten muss ( wie hier beschrieben : "... wenn Sie sich hinter einer ELB befinden, wobei die ELB als HTTPS-Endpunkt fungiert und nur HTTP-Datenverkehr an Ihren Server sendet, Sie brechen Sie die Fähigkeit, mit einer HTTP 200 OK-Antwort auf die Integritätsprüfung zu antworten, die der ELB benötigt ").

Ich denke darüber nach, den Login in den Code der Webanwendung und nicht in die Nginx-Konfiguration zu schreiben (und für die Zwecke dieser Frage nehmen wir an, dass es sich um eine Django-basierte Anwendung handelt), aber ich bin nicht sicher, ob dies mehr Aufwand bedeutet als die if in Konfiguration.

Jordan Reiter
quelle
Hallo, kannst du mir bitte sagen, wo du diesen Code ablegst?
YuAn Shaolin Maculelê Lai
@ YuAnShaolinMaculelêLai Sicher. Das sind Konfigurationsdateien für nginx, also habe ich den Code einfach in eine Datei in /etc/nginx/conf.d/ eingefügt. Normalerweise benenne ich die Datei domainname.conf, wobei "domainname" die Domain der betreffenden Website ist. Sie können der Datei einen beliebigen Namen geben, solange sie mit .conf endet.
Jordan Reiter
Vielen Dank. Ich habe versucht, eine neue Datei zu erstellen, gefolgt von .conf. Aber es hat bei mir nicht funktioniert. Dann habe ich den Code in die von AWS generierte Datei in /etc/nginx/conf.d/ eingefügt. Es funktioniert jetzt.
YuAn Shaolin Maculelê Lai

Antworten:

9

Wenn es so richtig funktioniert, fürchte dich nicht davor. http://wiki.nginx.org/IfIsEvil

Es ist wichtig zu beachten, dass das Verhalten von if nicht inkonsistent ist, da zwei identische Anforderungen nicht zufällig auf einer fehlschlagen und auf der anderen funktionieren, mit dem richtigen Testen und Verstehen von ifs, das verwendet werden kann . Die Empfehlung, andere Richtlinien zu verwenden, sofern verfügbar, gilt jedoch nach wie vor.

ceejayoz
quelle
Diese Seite sagt auch, dass "wenn Probleme bei der Verwendung im Standortkontext hat". Es scheint mir, dass Sie das tun können, was Sie tun müssen location {}, server {}stattdessen. (Aber bitte lassen Sie mich wissen, wenn dies falsch ist!)
Excalibur
15
  1. Richten Sie Ihr AWS-ELB ein, indem Sie ELB: 80 zu Instanz: 80 und ELB: 443 zu Instanz: 1443 zuordnen.
  2. Binden Sie Nginx, um Port 80 und 1443 abzuhören.
  3. Weiterleiten von Anforderungen, die an Port 80 ankommen, an Port 443.
  4. Die Integritätsprüfung sollte HTTP: 1443 lauten. Es lehnt HTTP: 80 ab, da 301 umleitet.

aws elb setup

NGINX-Setup

    server {
       listen         80;
       server_name    www.example.org;
       rewrite        ^ https://$server_name$request_uri? permanent;
    }

    server {
       listen         1443;
       server_name    www.example.org;
   } 
nu everest
quelle
Was ist mit den Einstellungen für die Gesundheitsprüfung? Könnten Sie bitte auch darauf näher eingehen?
samkhan13
Dies funktionierte nicht mit der auf http: 80 eingestellten Gesundheitsprüfung. Die Gesundheitsprüfung schlägt fehl.
samkhan13
2
Gesundheits-Check sollte sein HTTP:1443. Es lehnt das ab, HTTP:80weil das 301 umleitet.
Cbron
Dies funktionierte meistens für mich, aber die Zeile zum Umschreiben funktionierte nicht mit meiner Wildcard-Domain. Dieser andere Beitrag hat diesen Teil behoben
Ron
9

Diese Lösung verwendet bedingte Logik, aber wie die akzeptierte Antwort nahelegt, denke ich auch, dass dies in Ordnung ist. Ref: https://stackoverflow.com/questions/4833238/nginx-conf-redirect-multiple-conditions

Dazu müssen in den aws-Sicherheitseinstellungen für das Image keine zusätzlichen Ports geöffnet werden. Sie können ssl in der AWS LB beenden und den https-Verkehr an den http-Port 80 Ihrer Instanz weiterleiten.

In diesem Beispiel trifft der LB-Health-Check / Health auf Port 80, der zum App-Server weitergeleitet wird, sodass der Health-Check überprüft, ob sowohl Nginx als auch Ihre App atmen.

server {
  listen 80 default deferred;

  set $redirect_to_https 0;
  if ($http_x_forwarded_proto != 'https') {
    set $redirect_to_https 1;
  }
  if ($request_uri = '/health') {
    set $redirect_to_https 0;
  }
  if ($redirect_to_https = 1) {
    rewrite ^ https://www.example.com$request_uri? permanent;
  }
  ...
}
Jonny Mac
quelle
1
Es muss einen eleganteren Weg geben, dies zu tun
Edward
0

Sie können jetzt in den AWS Load Balancer-Einstellungen einen neuen Listener erstellen, der HTTP-Port 80 an HTTPS-Port 443 umleitet. Sie müssen also nicht mehr die Konfiguration von nginx / apache berühren.

Kenny Greulich
quelle
Leider wird es in Cloudformation
Aryeh Leib Taurog