Schreiben Sie http in https mit ngnix hinter dem Load Balancer neu

11

Ich verwende einen Rackspace-Load-Balancer, mit dem ich meinen SSL-Schlüssel / PEM im Admin-Bereich einrichten kann. Alles funktioniert gut, ich kann sowohl http- als auch https-Protokolle verwenden. Aber wenn ich versuche, http zu https umzuleiten, indem ich:

server{
  listen *:80;
  server_name mydomain.com www.mydomain.com; 
  rewrite ^ https://mydomain.com$request_uri? permanent;

... Ich bekomme eine Umleitungsschleife. Mir ist klar, dass ich nicht auf Port 443 höre, aber das liegt daran, dass der Load Balancer das für mich erledigt hat. Ich habe auch versucht, das Umschreiben if ($scheme ~* http){ohne Erfolg einzupacken.

Der andere Teil meiner Frage ist, dass ich www aus der URL entfernen möchte. Kann ich dies mit einem einzigen Umschreiben tun? Sollte das obige Umschreiben nicht auch dafür sorgen?

Danke für Ihre Hilfe!

jwerre
quelle
Der Load Balancer sollte Ihnen einen Hinweis senden, ob die Verbindung HTTPS war. Fragen Sie Rackspace. (Oh, und Sie wollen wahrscheinlich nicht www loswerden ...)
Michael Hampton
Interessant, ich werde das untersuchen. Warum sollte ich www nicht loswerden?
Jwerre

Antworten:

14

sciurus ist insofern richtig, als die Cloud Load Balancers von Rackspace den X-Forwarded-Proto auf https setzen, wenn SSL am Load Balancer entladen wird. Um eine Umleitungsschleife in Nginx zu vermeiden, sollten Sie in der Lage sein, dem locationAbschnitt in der vhost-Konfiguration Folgendes hinzuzufügen:

if ($http_x_forwarded_proto = "http") {
            rewrite  ^/(.*)$  https://mydomain.com/$1 permanent;
}

Dies sollte die Endlosumleitungsschleife vermeiden, während Nicht-https-Anforderungen an https umgeleitet werden.

Slade
quelle
18

Durch die Verwendung von nginx ist integrierte Servervariablen $request_uriund $server_nameSie können dies tun , ohne reguläre Ausdrücke überhaupt verwendet wird . Fügen Sie dem locationBlock Ihres Servers Folgendes hinzu, und Sie sind fertig:

if ($http_x_forwarded_proto = "http") {
    return 301 https://$server_name$request_uri;
}

Dies setzt voraus, dass Ihr Load Balancer den $http_x_forwarded_protoHeader zusammen mit der Anforderung an Ihre Backend-Instanz (en) sendet . Andere gebräuchliche Überschriften sind $http_x_forwarded_schemeund auch nur $scheme.

Weitere Informationen finden Sie in der Dokumentation zu Nginx- Fallstricken und häufigen Fehlern : https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/#taxing-rewrites

Luke Peterson
quelle
5
Sollte auf jeden Fall return over rewrite verwenden. Upvoted.
Designermonkey
1
Sie können $hostanstelle von$server_name
Yossi
funktioniert nicht mit Servername _; Daher sollte man die Variable $ host verwenden, wie von @Yossi vorgeschlagen.
Razvan Grigore
0

Der Load Balancer spricht immer über http mit Ihnen. Was passiert ist

  1. Der Browser fordert Port 80 des Load Balancers an
  2. Der Load Balancer fordert Port 80 auf Ihrem Webserver an
  3. Ihr Webserver sendet eine Weiterleitung an den Benutzer
  4. Der Benutzer fordert Port 443 des Load Balancers an

Die Schritte 2 bis 4 werden so oft wiederholt, bis der Browser die Umleitungsschleife erkennt und aufgibt.

BEARBEITEN: Um dies zu beheben, führen Sie das Umschreiben nur durch, wenn der X-Forwarded-Proto-Header auf http gesetzt ist. In diesem Header teilt der Load Balancer von Rackspace Ihrem Webserver das Protokoll mit, über das er die Anforderung empfangen hat.

Sciurus
quelle
Ich denke, das würde erklären, warum $ server_protocol immer HTTP zurückgibt
jwerre
Sie haben also geantwortet, warum dies geschieht ... Vorschläge zur Behebung?
Jwerre