Impedisci a nginx di reindirizzare il traffico da https a http quando utilizzato come proxy inverso


16

Ecco la mia conf abbreviata nginx vhost:

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

Lo stesso server deve servire sia HTTP che HTTPS, tuttavia, quando l'upstream emette un reindirizzamento (ad esempio, dopo l'elaborazione di un modulo), tutte le richieste HTTPS vengono reindirizzate a HTTP. L'unica cosa che ho scoperto che risolverà questo problema sta cambiando proxy_redirectnel modo seguente:

proxy_redirect http:// https://;

Funziona meravigliosamente per le richieste provenienti da HTTPS, ma se un reindirizzamento viene emesso su HTTP, lo reindirizza anche a HTTPS, il che è un problema.

Per disperazione, ho provato:

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

Ma nginx si lamenta che proxy_redirectnon è consentito qui.

L'unica altra opzione che mi viene in mente è quella di definire i due server separatamente e impostare proxy_redirectsolo su quello SSL, ma poi avrei duplicato il resto della conf (c'è molto nella serverdirettiva che ho omesso per motivi di semplicità). So che potrei anche usare una includedirettiva per scomporre la ridondanza, ma voglio davvero mantenere solo un file conf senza dipendenze.

Quindi, in primo luogo, c'è qualcosa che mi manca che annullerà del tutto il problema? Oppure, in caso contrario, esiste un altro modo (oltre a includere un file esterno) di fattorizzare le informazioni di configurazione ridondanti in modo da poter separare le versioni HTTP e HTTPS della configurazione del server?

Risposte:


29

Bene, ho avuto un po 'di ispirazione e ho provato:

proxy_redirect http:// $scheme://;

Il che sembra fare il trucco. Questo mi sembra comunque confuso, quindi accolgo con favore qualsiasi consiglio su qualsiasi cosa io possa fare in modo sbagliato o meno confuso per ottenere lo stesso risultato.


In effetti, quello sembra essere il modo "ufficiale" per farlo ... vedi wiki.nginx.org/SSL-Offloader
Hendy Irawan,

Il link sopra alla wiki di nginx non funziona più, la nuova posizione è nginx.com/resources/wiki/start/topics/examples/SSL-Offloader
Paul Tobias

Questo non funzionerà se la tua posizione non ha una barra finale
hdave

Dio dannatamente dannazione, perché il software non può aspettarsi di vivere dietro un proxy inverso (o almeno dannatamente rispettare X-Forwarded-Scheme o qualunque altra cosa? blet +
Axel Latvala

5

L'altra soluzione è indicare all'upstream se la richiesta è HTTP o HTTPS e far sì che emetta il reindirizzamento corrispondente. L'aggiunta di questo nella configurazione di nginx imposterà un'intestazione per l'ispezione dell'upstream.

proxy_set_header    X-Scheme $scheme;

Ah, vedo ora che hai già quella configurazione.
mgorven

Sì. Ma apprezzo il tentativo di aiutare, comunque.
Chris Pratt,

4
Questa sembra essere un'intestazione triky. Penso che X-Forwarded-Proto sia migliore
vladkras il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.