เขียน http ใหม่เพื่อ https ด้วย ngnix หลัง load balancer


13

ฉันกำลังใช้ load balancer ของ Rackspace ซึ่งทำให้ฉันสามารถตั้งค่าคีย์ ssl / pem ภายในแผงควบคุมของผู้ดูแลระบบได้ ทุกอย่างทำงานได้ดีฉันสามารถใช้ทั้งโปรโตคอล http และ https แต่ถ้าฉันพยายามเปลี่ยนเส้นทาง http เป็น https โดยใช้:

server{
  listen *:80;
  server_name mydomain.com www.mydomain.com; 
  rewrite ^ https://mydomain.com$request_uri? permanent;

... ฉันได้รับการวนรอบการเปลี่ยนเส้นทาง ฉันรู้ว่าฉันไม่ได้ฟังพอร์ต 443 แต่นั่นเป็นเพราะ load balancer จัดการสำหรับฉัน ฉันยังลองตัดคำสั่งเขียนใหม่อีกครั้งif ($scheme ~* http){เพื่อไม่เกิดประโยชน์

อีกส่วนหนึ่งของคำถามของฉันคือฉันต้องการลบ www จาก url ฉันสามารถทำสิ่งนี้ด้วยการเขียนซ้ำครั้งเดียวได้หรือไม่ ไม่ควรเขียนข้างต้นดูแลนี้เช่นกัน?

ขอบคุณสำหรับความช่วยเหลือของคุณ!


ตัวโหลดบาลานซ์ควรส่งสัญญาณบ่งชี้ถึงคุณว่าการเชื่อมต่อเป็น HTTPS หรือไม่ ถาม Rackspace (โอ้และคุณอาจไม่ต้องการกำจัด www ... )
Michael Hampton

น่าสนใจฉันจะดูว่า ทำไมคุณถึงคิดว่าฉันไม่ควรกำจัด www?
jwerre

คำตอบ:


14

sciurus ถูกต้องใน Cloud Load Balancer ของ Rackspace ที่ตั้ง X-Forwarded-Proto เป็น https เมื่อ SSL ถูก offloaded ที่ load balancer เพื่อหลีกเลี่ยงการวนรอบการเปลี่ยนเส้นทางใน nginx คุณควรจะสามารถเพิ่มสิ่งต่อไปนี้ในlocationส่วนในการกำหนดค่า vhost:

if ($http_x_forwarded_proto = "http") {
            rewrite  ^/(.*)$  https://mydomain.com/$1 permanent;
}

สิ่งนี้ควรหลีกเลี่ยงการวนรอบการเปลี่ยนเส้นทางแบบไม่สิ้นสุดในขณะที่เปลี่ยนเส้นทางคำขอที่ไม่ใช่ https ไปยัง https


18

ด้วยการใช้ตัวแปรเซิร์ฟเวอร์ในตัวของ nginx $request_uriและ$server_nameคุณสามารถทำได้โดยไม่ต้องใช้นิพจน์ทั่วไปเลย เพิ่มสิ่งต่อไปนี้ในlocationบล็อกของเซิร์ฟเวอร์ของคุณและคุณทำเสร็จแล้ว:

if ($http_x_forwarded_proto = "http") {
    return 301 https://$server_name$request_uri;
}

สิ่งนี้จะถือว่าโหลดบาลานเซอร์ของคุณกำลังส่ง$http_x_forwarded_protoส่วนหัวพร้อมกับคำขอไปยังอินสแตนซ์ของแบ็กเอนด์ ส่วนหัวที่พบบ่อยอื่น ๆ ได้แก่และก็เป็นเพียงแค่$http_x_forwarded_scheme$scheme

ข้อมูลเพิ่มเติมสามารถพบได้ในเอกสารประกอบข้อผิดพลาดของ nginx และข้อผิดพลาดทั่วไป : https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/#taxing-rewrites


5
ควรใช้ผลตอบแทนมากกว่าการเขียนใหม่อย่างแน่นอน upvoted
designermonkey

1
คุณสามารถใช้$hostแทน$server_name
Yossi

ไม่ทำงานกับ server_name _; ดังนั้นหนึ่งควรใช้ตัวแปรโฮสต์ $ ตามที่แนะนำ @Yossi
Razvan Grigore

1

ตัวโหลดบาลานซ์จะพูดกับคุณผ่าน http เสมอ สิ่งที่เกิดขึ้นคือ

  1. เบราว์เซอร์ทำการร้องขอไปยังพอร์ต 80 บนตัวโหลดบาลานซ์
  2. ตัวโหลดบาลานซ์สร้างการร้องขอไปยังพอร์ต 80 บนเว็บเซิร์ฟเวอร์ของคุณ
  3. เว็บเซิร์ฟเวอร์ของคุณส่งการเปลี่ยนเส้นทางไปยังผู้ใช้
  4. ผู้ใช้ทำการร้องขอไปยังพอร์ต 443 บนตัวโหลดบาลานซ์

ขั้นตอนที่ 2-4 ทำซ้ำจนกระทั่งเบราว์เซอร์ตรวจพบลูปการเปลี่ยนเส้นทางและเลิก

แก้ไข: หากต้องการแก้ไขปัญหานี้ให้ดำเนินการเขียนใหม่เฉพาะเมื่อส่วนหัว X-Forwarded-Proto ถูกตั้งค่าเป็น http ส่วนหัวนั้นเป็นวิธีที่ load balancer ของ Rackspace บอกเว็บเซิร์ฟเวอร์ของคุณถึงโปรโตคอลที่ได้รับการร้องขอ


ฉันเดาว่าจะอธิบายว่าทำไม $ server_protocol ส่งคืน HTTP เสมอ
jwerre

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