Cegah nginx dari mengarahkan ulang lalu lintas dari https ke http ketika digunakan sebagai proxy terbalik

16

Inilah nginx vhost conf yang disingkat:

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

Server yang sama perlu melayani HTTP dan HTTPS, namun, ketika upstream mengeluarkan redirect (misalnya, setelah formulir diproses), semua permintaan HTTPS dialihkan ke HTTP. Satu-satunya hal yang saya temukan yang akan memperbaiki masalah ini berubah proxy_redirectmenjadi sebagai berikut:

proxy_redirect http:// https://;

Itu bekerja sangat baik untuk permintaan yang datang dari HTTPS, tetapi jika redirect dikeluarkan melalui HTTP, itu juga mengarahkan kembali ke HTTPS, yang merupakan masalah.

Karena putus asa, saya mencoba:

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

Tapi nginx mengeluh yang proxy_redirecttidak diizinkan di sini.

Satu-satunya pilihan lain yang bisa saya pikirkan adalah mendefinisikan dua server secara terpisah dan proxy_redirecthanya menetapkan pada satu SSL, tapi kemudian saya akan menduplikasi sisa dari conf (ada banyak dalam serverdirektif yang saya hilangkan demi kesederhanaan). Saya tahu saya juga bisa menggunakan includearahan untuk faktor redundansi, tapi saya benar-benar ingin menyimpan hanya satu file conf tanpa ketergantungan.

Jadi, pertama, apakah ada sesuatu yang saya lewatkan yang akan meniadakan masalah sepenuhnya? Atau, kedua, jika tidak, adakah cara lain (selain termasuk file eksternal) untuk memperhitungkan informasi konfigurasi yang berlebihan sehingga saya dapat memisahkan versi HTTP dan HTTPS dari konfigurasi server?

Chris Pratt
sumber

Jawaban:

29

Yah, saya mendapat sedikit inspirasi dan mencoba:

proxy_redirect http:// $scheme://;

Yang sepertinya melakukan trik. Namun, ini masih terasa membingungkan bagi saya, jadi saya tetap menerima petunjuk tentang apa pun yang mungkin saya lakukan salah atau kurang jalan untuk mencapai hasil yang sama.

Chris Pratt
sumber
Memang, itu tampaknya menjadi cara "resmi" untuk melakukannya ... lihat wiki.nginx.org/SSL-Offloader
Hendy Irawan
Tautan di atas ke nginx wiki tidak berfungsi lagi, lokasi baru adalah nginx.com/resources/wiki/start/topics/examples/SSL-Offloader
Paul Tobias
Ini tidak akan berfungsi jika lokasi Anda tidak memiliki garis miring
hdave
sialan, mengapa perangkat lunak tidak bisa hanya berharap untuk hidup di belakang proxy terbalik (atau setidaknya rasa hormat X-Forwarded-Skema atau apa pun? blet +
Axel Latvala
5

Solusi lainnya adalah menunjukkan ke hulu apakah permintaannya adalah HTTP atau HTTPS dan minta ia mengeluarkan redirect yang sesuai. Menambahkan ini di konfigurasi nginx akan mengatur header untuk upstream untuk diperiksa.

proxy_set_header    X-Scheme $scheme;
Mgorven
sumber
Ah, saya mengerti sekarang bahwa Anda sudah memiliki konfigurasi itu.
mgorven
Ya. Tapi saya menghargai upaya untuk membantu.
Chris Pratt
4
Ini tampaknya menjadi beberapa header triky. Saya pikir X-Forwarded-Proto lebih baik
vladkras