ป้องกันไม่ให้ nginx เปลี่ยนเส้นทางปริมาณการใช้ข้อมูลจาก https ไปยัง http เมื่อใช้เป็น reverse proxy


16

นี่คือ 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;
    }
}

เซิร์ฟเวอร์เดียวกันต้องให้บริการทั้ง HTTP และ HTTPS อย่างไรก็ตามเมื่ออัปสตรีมปัญหาการเปลี่ยนเส้นทาง (ตัวอย่างเช่นหลังจากประมวลผลแบบฟอร์ม) คำขอ HTTPS ทั้งหมดจะถูกเปลี่ยนเส้นทางไปยัง HTTP สิ่งเดียวที่ฉันได้พบที่จะแก้ไขปัญหานี้คือการเปลี่ยนแปลงproxy_redirectต่อไปนี้:

proxy_redirect http:// https://;

ใช้งานได้อย่างยอดเยี่ยมสำหรับคำขอที่มาจาก HTTPS แต่หากมีการออกการเปลี่ยนเส้นทางผ่าน HTTP ก็จะเปลี่ยนเส้นทางนั้นไปยัง HTTPS ซึ่งเป็นปัญหา

ฉันหมดความพยายาม:

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

แต่ nginx บ่นproxy_redirectว่าไม่ได้รับอนุญาตที่นี่

ตัวเลือกอื่นที่ฉันคิดได้คือการกำหนดเซิร์ฟเวอร์สองเครื่องแยกกันและตั้งค่าไว้proxy_redirectใน SSL เดียว แต่จากนั้นฉันจะทำซ้ำส่วนที่เหลือของความเชื่อมั่น (มีserverคำสั่งมากมายที่ฉันไม่ได้ทำเพื่อความเรียบง่าย) ฉันรู้ว่าฉันยังสามารถใช้includeคำสั่งเพื่อแยกแยะความซ้ำซ้อน แต่ฉันต้องการเก็บไฟล์ conf เพียงไฟล์เดียวโดยไม่มีการอ้างอิงใด ๆ

ดังนั้นก่อนอื่นมีบางสิ่งที่ฉันขาดซึ่งจะลบล้างปัญหาโดยสิ้นเชิงหรือไม่? หรืออย่างที่สองถ้าไม่มีมีวิธีอื่น (นอกเหนือจากการรวมไฟล์ภายนอก) เพื่อแยกแยะข้อมูลการกำหนดค่าที่ซ้ำซ้อนเพื่อให้ฉันสามารถแยกเวอร์ชัน HTTP และ HTTPS ของการกำหนดค่าเซิร์ฟเวอร์ออกได้หรือไม่

คำตอบ:


29

ฉันได้แรงบันดาลใจมาบ้างแล้วลอง:

proxy_redirect http:// $scheme://;

ซึ่งดูเหมือนว่าจะทำเคล็ดลับ แต่นี่ก็ดูเหมือนว่าแฮ็คกับฉันดังนั้นฉันยังคงยินดีต้อนรับคำแนะนำใด ๆ เกี่ยวกับสิ่งที่ฉันอาจจะทำผิดหรือน้อยวิธีแฮ็คเพื่อให้ได้ผลลัพธ์เดียวกัน


แน่นอนว่าน่าจะเป็นวิธีที่ "เป็นทางการ" ที่จะทำ ... ดูwiki.nginx.org/SSL-Offloader
Hendy Irawan

ลิงก์ด้านบนไปยัง nginx wiki ไม่ทำงานอีกต่อไปตำแหน่งใหม่คือnginx.com/resources/wiki/start/topics/examples/SSL-Offloader
Paul Tobias

สิ่งนี้จะไม่ทำงานหากตำแหน่งของคุณไม่มีเครื่องหมายทับ
hdave

god fucking damn ทำไมซอฟต์แวร์ไม่สามารถคาดหวังว่าจะมีชีวิตอยู่หลังพร็อกซีย้อนกลับ (หรืออย่างน้อย goddamn เคารพ X-Forwarded-Scheme หรืออะไรก็ตาม? blet +
Axel Latvala

5

โซลูชันอื่น ๆ คือการระบุให้ upstream ไม่ว่าจะเป็นคำขอ HTTP หรือ HTTPS และให้มันเปลี่ยนเส้นทางตาม การเพิ่มสิ่งนี้ในการกำหนดค่า nginx จะตั้งค่าส่วนหัวสำหรับอัปสตรีมเพื่อตรวจสอบ

proxy_set_header    X-Scheme $scheme;

อ่าฉันเห็นแล้วว่าคุณมีการกำหนดค่าอยู่แล้ว
mgorven

อ๋อ แต่ฉันขอขอบคุณความพยายามที่จะช่วยอย่างไรก็ตาม
Chris Pratt

4
นี่ดูเหมือนจะเป็นเรื่องหัวบางส่วน ฉันคิดว่าX-Forwarded-Protoนั้นดีกว่า
vladkras
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.