Verhindern, dass Nginx Datenverkehr von https zu http umleitet, wenn es als Reverse-Proxy verwendet wird


16

Hier ist meine abgekürzte Nginx Vhost Conf:

upstream gunicorn {
    server 127.0.0.1:8080 fail_timeout=0;
}

server {
    listen 80;
    listen 443 ssl;
    server_name domain.com ~^.+\.domain\.com$;

    location / {
        try_files $uri @proxy;
    }

    location @proxy {
        proxy_pass_header Server;
        proxy_redirect off;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Scheme $scheme;
        proxy_connect_timeout 10;
        proxy_read_timeout 120;
        proxy_pass http://gunicorn;
    }
}

Der gleiche Server muss sowohl HTTP als auch HTTPS bedienen. Wenn der Upstream jedoch eine Umleitung ausgibt (z. B. nachdem ein Formular verarbeitet wurde), werden alle HTTPS-Anforderungen an HTTP umgeleitet. Das Einzige, was ich gefunden habe, um dieses Problem zu beheben, ist proxy_redirectfolgende Änderung :

proxy_redirect http:// https://;

Das funktioniert wunderbar für Anfragen, die von HTTPS kommen, aber wenn eine Umleitung über HTTP erfolgt, wird dies auch an HTTPS weitergeleitet, was ein Problem darstellt.

Aus Verzweiflung versuchte ich:

if ($scheme = 'https') {
    proxy_redirect http:// https://;
}

Aber Nginx beschwert sich, dass proxy_redirectdas hier nicht erlaubt ist.

Die einzige andere Option, die ich mir proxy_redirectvorstellen kann, besteht darin, die beiden Server separat zu definieren und nur auf den SSL- Server zu setzen , aber dann hätte ich den Rest der conf dupliziert (es gibt eine Menge in der serverDirektive, die ich der Einfachheit halber weggelassen habe). Ich weiß, ich könnte auch eine includeDirektive verwenden, um die Redundanz auszugleichen, aber ich möchte wirklich nur eine conf-Datei ohne Abhängigkeiten behalten.

Gibt es also etwas, das ich vermisse, um das Problem vollständig zu beseitigen? Oder, wenn nicht, gibt es eine andere Möglichkeit (abgesehen von einer externen Datei), die redundanten Konfigurationsinformationen herauszufiltern, damit ich die HTTP- und HTTPS-Versionen der Serverkonfiguration trennen kann?

Antworten:


29

Nun, ich habe ein bisschen Inspiration bekommen und versucht:

proxy_redirect http:// $scheme://;

Welches scheint den Trick zu tun. Dies scheint mir jedoch immer noch hacky zu sein. Daher begrüße ich nach wie vor jede Anleitung für alles, was ich falsch oder weniger hacky mache, um das gleiche Ergebnis zu erzielen.


In der Tat scheint dies der "offizielle" Weg zu sein ... siehe wiki.nginx.org/SSL-Offloader
Hendy Irawan

Der obige Link zum nginx-Wiki funktioniert nicht mehr, der neue Speicherort ist nginx.com/resources/wiki/start/topics/examples/SSL-Offloader
Paul Tobias

Dies funktioniert nicht, wenn Ihr Standort keinen
abschließenden

Gott verdammt verdammt, warum erwarten Software ist nicht nur hinter einem Reverse - Proxy zu leben (oder atleast goddamn Respekt X-Forwarded-Schema oder was auch immer blet +?
Axel Latvala

5

Die andere Lösung besteht darin, dem Upstream anzuzeigen, ob die Anforderung HTTP oder HTTPS ist, und die entsprechende Umleitung ausgeben zu lassen. Wenn Sie dies in der nginx-Konfiguration hinzufügen, wird ein Header festgelegt, den der Upstream überprüfen soll.

proxy_set_header    X-Scheme $scheme;

Ah, ich sehe jetzt, dass Sie diese Konfiguration bereits haben.
mgorven

Ja. Trotzdem schätze ich den Versuch zu helfen.
Chris Pratt

4
Dies scheint ein heikler Header zu sein. Ich denke, X-Forwarded-Proto ist besser
vladkras
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.