การเปลี่ยนเส้นทางผ่าน nginx proxy ไม่สนใจพอร์ต


34

ดังนั้นฉันจึงตั้งค่าเส้นทางเสมือนเมื่อชี้ไปที่แอป node.js ใน nginx conf ของฉัน ส่วนที่เกี่ยวข้องมีลักษณะดังนี้:

location /app {
  rewrite /app/(.*) /$1 break;
  proxy_pass http://localhost:3000;
  proxy_redirect off;
  proxy_set_header Host $host;
  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

ใช้งานได้ดียกเว้นว่าเมื่อแอป node.js ของฉัน (แอปด่วน) เรียกการเปลี่ยนเส้นทาง

ตัวอย่างเช่นกล่อง dev กำลังรัน nginx บนพอร์ต 8080 และ URL ของรูทของแอปโหนดดูเหมือนว่า:

http: // localhost: 8080 / แอป

เมื่อฉันเรียกการเปลี่ยนเส้นทางไปยัง '/ app' จากโหนดการเปลี่ยนเส้นทางที่แท้จริงจะไปที่:

http: // localhost / แอป


ต่อไปนี้เป็นคำตอบที่แนะนำให้ใช้: proxy_set_header Host $ http_host; แต่ไม่มีใครบอกว่าสามารถทำให้เกิดช่องโหว่ได้ (การโจมตีส่วนหัวของโฮสต์) ตัวอย่างการโจมตีที่นี่และข้อมูลเพิ่มเติมที่นี่

คำตอบ:


14

ปัญหาคือแอปพลิเคชัน Node.js ไม่ได้ทำการเปลี่ยนเส้นทางอย่างถูกต้อง คุณอาจจะสามารถใช้proxy_redirectในการแก้ไขใน nginx:

proxy_redirect http://localhost/ http://localhost:8080/;

47

ฉันแค่ต้องแก้ปัญหาเดียวกับที่เจนกินส์วิ่งตาม nginx สิ่งที่ฉันทำคือการรวมพอร์ตเซิร์ฟเวอร์ไว้ในHostส่วนหัวที่ถูกส่งไปยังเจนกินส์:

proxy_set_header Host $host:$server_port;

หวังว่าจะช่วย


3
การเล่นชนิดหนึ่ง ดังที่ @mgorven บอกว่าโหนดกำลังตั้งค่าการเปลี่ยนเส้นทางที่ไม่ดีเนื่องจาก nginx กำลังส่งต่อโฮสต์อย่างไม่ดี
Eric

5

ฉันลองใช้วิธีแก้ไขปัญหาข้างต้น แต่พวกเขาทั้งหมดล้มเหลวเมื่อใดก็ตามที่แอปพลิเคชันโหนดออก URL แบบเต็มในส่วนหัวของตำแหน่งเช่น " http://nodeapp.com:8080/new/location "

ดังนั้นฉันจึงตัดสินใจใช้ $ http_host เพื่อผ่านโฮสต์และพอร์ต และใช้การจับคู่ ~ ^ เพื่อเขียน URL ใหม่ทั้งหมด

  proxy_pass http://10.0.0.3:8080;

  proxy_set_header X-Real-IP $remote_addr;
  proxy_set_header Host $http_host;

  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

  proxy_redirect default;
  proxy_redirect ~^(https?://[^:]+):\d+(?<relpath>/.+)$ http://10.0.0.3:8000$relpath;

ในกรณีของเราเซิร์ฟเวอร์โหนดทำงานบน 8080 และพร็อกซี nginx ของเรากำลังทำงานอยู่ที่ 8000 ซึ่งหมายความว่าทุก URL ที่ผ่านการรับรองโดยสมบูรณ์ในส่วนหัวของตำแหน่งจะต้องถูกเขียนใหม่ หวังว่านี่จะช่วยให้ใครบางคน !!


4

ตามการสนทนาในคำถามนี้การแก้ปัญหาที่เหมาะสมคือการปรับHostคำสั่งส่วนหัวของพร็อกซี่

เปลี่ยนสิ่งนี้:

proxy_set_header Host $host;

สำหรับสิ่งนี้:

proxy_set_header Host $http_host;

$http_hostเก็บค่าตามที่ระบุในส่วนหัว HTTP HOST ซึ่งรวมถึงพอร์ต การเปลี่ยนเส้นทางควรเลือกพอร์ตที่กำหนดเองโดยไม่ต้องปรับแต่งเพิ่มเติมเพื่อตั้งค่าของ OP

คำตอบเหล่านี้ (ตั๋วเดียวกัน) ให้รายละเอียดเพิ่มเติม:

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