Ngăn nginx chuyển hướng lưu lượng truy cập từ https sang http khi được sử dụng làm proxy ngược


16

Đây là viết tắt của tôi 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;
    }
}

Tuy nhiên, cùng một máy chủ cần phục vụ cả HTTP và HTTPS, khi ngược dòng phát sinh chuyển hướng (ví dụ: sau khi một biểu mẫu được xử lý), tất cả các yêu cầu HTTPS đều được chuyển hướng đến HTTP. Điều duy nhất tôi thấy rằng sẽ khắc phục vấn đề này là thay đổi proxy_redirectnhư sau:

proxy_redirect http:// https://;

Điều đó hoạt động tuyệt vời cho các yêu cầu đến từ HTTPS, nhưng nếu chuyển hướng được phát hành qua HTTP, nó cũng chuyển hướng điều đó đến HTTPS, đó là một vấn đề.

Trong tuyệt vọng, tôi đã cố gắng:

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

Nhưng nginx phàn nàn rằng proxy_redirectkhông được phép ở đây.

Tùy chọn duy nhất khác mà tôi có thể nghĩ đến là xác định riêng hai máy chủ và proxy_redirectchỉ đặt trên máy chủ SSL, nhưng sau đó tôi sẽ sao chép phần còn lại của conf (có rất nhiều trong serverchỉ thị mà tôi đã bỏ qua vì đơn giản). Tôi biết tôi cũng có thể sử dụng một includechỉ thị để loại bỏ sự dư thừa, nhưng tôi thực sự muốn giữ chỉ một tệp conf mà không có bất kỳ sự phụ thuộc nào.

Vì vậy, trước tiên, có điều gì tôi đang thiếu sẽ phủ nhận vấn đề hoàn toàn không? Hoặc, thứ hai, nếu không, có cách nào khác (ngoài việc bao gồm một tệp bên ngoài) để xác định thông tin cấu hình dự phòng để tôi có thể tách ra các phiên bản HTTP và HTTPS của cấu hình máy chủ không?

Câu trả lời:


29

Vâng, tôi đã có một chút cảm hứng và cố gắng:

proxy_redirect http:// $scheme://;

Mà dường như để làm các thủ thuật. Tuy nhiên, điều này vẫn có vẻ khó xử đối với tôi, vì vậy tôi vẫn hoan nghênh mọi hướng dẫn về bất cứ điều gì tôi có thể làm sai hoặc ít cách hack để đạt được kết quả tương tự.


Thật vậy, đó dường như là cách "chính thức" để làm điều đó ... xem wiki.nginx.org/SSL- Offerloader
Hendy

Liên kết trên đến nginx wiki không hoạt động nữa, vị trí mới là nginx.com/resource/wiki/start/topics/examples/SSL- Offerloader
Paul Tobias

Điều này sẽ không hoạt động nếu vị trí của bạn không có dấu gạch chéo
hdave

chúa chết tiệt, tại sao phần mềm không thể mong đợi được sống sau một proxy ngược (hoặc ít nhất là tôn trọng X-Forwarded-Scheme hoặc bất cứ điều gì? blet +
Axel Latvala

5

Giải pháp khác là chỉ ra cho thượng nguồn xem yêu cầu là HTTP hay HTTPS và yêu cầu đó có chuyển hướng theo không. Thêm phần này vào cấu hình nginx sẽ đặt tiêu đề cho dòng ngược để kiểm tra.

proxy_set_header    X-Scheme $scheme;

Ah, tôi thấy bây giờ bạn đã có cấu hình đó.
mgorven

Vâng. Nhưng tôi đánh giá cao nỗ lực để giúp đỡ, dù sao.
Chris Pratt

4
Đây có vẻ là một số tiêu đề triky. Tôi nghĩ X-Forwarded-Proto tốt hơn
vladkras
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.