Frage Leiten Sie alle HTTP-Anfragen hinter Amazon ELB auf https um, ohne if zu verwenden


Zur Zeit habe ich eine ELB, die beide bedient http://www.beispiel.org und https://www.example.org.

Ich möchte es so einrichten, dass jede Anfrage darauf verweist http://www.beispiel.org ist Redirect zu https://www.example.org.

Der ELB sendet die https-Anfragen als http-Anfragen, also unter Verwendung von:

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

wird nicht funktionieren, weil Anfragen an https://www.example.org wird immer noch Port 80 auf Nginx gemacht.

Ich weiß, dass es möglich ist, es 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, sagte das if sollte innerhalb der nginx-Konfiguration um jeden Preis vermieden werden, und dies wäre für jede einzelne Anfrage. Es bedeutet auch, dass ich eine spezielle separate Konfiguration für den Gesundheitscheck einrichten muss (wie hier beschrieben: "... Wenn Sie sich hinter einem ELB befinden, bei dem der ELB als HTTPS-Endpunkt fungiert und nur HTTP-Datenverkehr an Ihren Server gesendet wird, besteht die Möglichkeit, mit einer HTTP 200 OK-Antwort für die vom ELB benötigte Integritätsprüfung zu antworten." .

Ich überlege, den Login in den Code der Webanwendung zu setzen und nicht in die nginx-Konfiguration (und für die Zwecke dieser Frage nehmen wir an, dass es eine Django-basierte Anwendung ist), aber ich bin mir nicht sicher, ob das mehr Aufwand wäre das if  in der Konfiguration.


24
2017-08-12 20:43


Ursprung


Hi, kannst du mir bitte sagen, wo du diesen Code ablegst? - YuAn Shaolin Maculelê Lai
@ YuAnShaolinMaculelêLai Sicher. Das sind Konfigurationsdateien für nginx, also lege ich den Code einfach in eine Datei in /etc/nginx/conf.d/. Ich nenne normalerweise die Datei domainname.conf, wobei "domainname" die Domäne der fraglichen Website ist. Sie können die Datei beliebig benennen, so lange sie mit .conf endet. - Jordan Reiter
Vielen Dank. Ich habe versucht, eine neue Datei zu erstellen, die auf .conf folgt. Aber es hat nicht für mich funktioniert. Dann lege ich den Code in die Datei, die von AWS in /etc/nginx/conf.d/ generiert wurde. Es funktioniert jetzt. - YuAn Shaolin Maculelê Lai


Antworten:


Wenn es so richtig funktioniert, habe keine Angst davor. http://wiki.nginx.org/IfIsEvil

Es ist wichtig zu beachten, dass das Verhalten von if nicht inkonsistent ist. Bei zwei identischen Anfragen wird es nicht zufällig bei einem fehlschlagen und bei dem anderen funktionieren, mit geeigneten Tests und Verständnis, wenn sie verwendet werden können. Der Ratschlag, andere Richtlinien zu verwenden, wenn sie verfügbar sind, gilt jedoch immer noch sehr.


8
2017-08-12 20:47



Diese Seite sagt auch, dass "wenn Probleme im Standortkontext auftreten". Es scheint mir, dass Sie tun können, was Sie tun müssen, außerhalb von location {}, im server {} stattdessen. (Aber lass es mich wissen, wenn das nicht stimmt!) - Excalibur


  1. Richten Sie Ihr AWS ELB Mapping ELB: 80 auf Instanz: 80 und ELB: 443 auf Instanz: 1443 ein.
  2. Binden Sie nginx an Port 80 und 1443.
  3. Weiterleiten von Anforderungen, die an Port 80 ankommen, an Port 443.
  4. Die Integritätsprüfung sollte HTTP: 1443 sein. Es lehnt das HTTP: 80 ab, weil die 301-Weiterleitung.

aws elb setup

NGINX-Einrichtung

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

    server {
       listen         1443;
       server_name    www.example.org;
   } 

15
2018-01-16 18:42



Was ist mit den Einstellungen für die Gesundheitsprüfung? Könnten Sie das bitte auch näher erläutern? - samkhan13
Dies funktionierte nicht mit der Helth-Prüfung, die auf http: 80 gesetzt wurde, die Gesundheitsprüfung schlägt fehl. - samkhan13
Gesundheitscheck sollte sein HTTP:1443. Es lehnt das ab HTTP:80 weil die 301 Redirect. - cbron
@cbron Ich habe deinen Kommentar dankend aufgenommen. - nu everest
Das funktionierte meistens für mich, aber die Neuschreibezeile funktionierte nicht mit meiner Wildcard-Domain. Dieser andere Beitrag hat diesen Teil repariert: serverfault.com/questions/447258/ ... - Ron


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

Außerdem müssen in den Sicherheitseinstellungen von aws für das Image keine zusätzlichen Ports geöffnet werden. Sie können ssl in AWS LB beenden und https-Verkehr auf http Port 80 Ihrer Instanz routen.

In diesem Beispiel trifft der LB-Gesundheitscheck / Gesundheit auf Port 80, der zum App-Server routet, so dass der Gesundheitscheck beide nginx validiert und Ihre App atmet.

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;
  }
  ...
}

9
2017-07-20 23:23



es muss einen eleganteren Weg geben, dies zu tun - Edward


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


0
2017-09-18 13:43