Score:2

Apache ที่อยู่เบื้องหลัง nginx reverse proxy ตั้งค่าส่วนหัวของโฮสต์ที่ถูกต้อง

ธง nl

ฉันใช้งานแอปพลิเคชันโดยใช้ Apache ในคอนเทนเนอร์ Docker ฉันมี nginx ที่ทำหน้าที่เป็น reverse proxy ซึ่งทำงานในคอนเทนเนอร์ Docker อื่นซึ่งมี Apache เป็นอัปสตรีม ฉันกำลังใช้ proxy_pass คำสั่งนี้

Apache ทำงานใน URL https://example-8gnm1aqrns-lz.a.run.app Nginx ทำงานใน URL http://example.com

สิ่งทั้งหมดกำลังทำงานบน Google Cloud Run และปัญหาคือ Google Cloud Run กำหนด URL ทุกบริการและใช้ เจ้าภาพ ส่วนหัวเพื่อแยกความแตกต่างระหว่างแอปพลิเคชัน ดังนั้นฉันจึงถูกบังคับให้ส่งส่วนหัว โฮสต์: example-8gnm1aqrns-lz.a.run.app เมื่อเชื่อมต่อกับอัปสตรีมโดยใช้ nginx ดังนั้นคำขอจึงกำหนดเส้นทางได้อย่างถูกต้อง

สิ่งนี้ทำให้เกิดปัญหากับแอปพลิเคชันของฉันเพราะคิดว่ากำลังทำงานใน URL https://example-8gnm1aqrns-lz.a.run.app และไม่ http://example.com.

เป็นไปได้หรือไม่ที่จะใช้การกำหนดค่า Apache .htaccess เพื่อเขียนทับไฟล์ เจ้าภาพ ส่วนหัวขึ้นอยู่กับ X-ส่งต่อโฮสต์ ส่งโดย nginx?

Score:2
ธง co

แทนที่จะให้ Apache ทำงานขานั้น ให้ NGINX ทำก่อนที่จะส่งต่อข้อมูลไปยัง Apache ด้วยการตั้งค่าส่วนหัวของโฮสต์ที่ Apache คาดหวังว่าเป็นส่วนหนึ่งของการส่งต่อ proxy_pass พร้อมตัวเลือกการกำหนดค่าเพิ่มเติม

NGINX มีตัวแปรต่อไปนี้สำหรับ proxy_set_header เพื่อเพิ่มสิ่งที่ส่งผ่านไปยังพร็อกซีในแบ็กเอนด์ คุณจะได้สิ่งนี้:

...

ที่ตั้ง / {
    proxy_pass http://10.20.30.40;
    proxy_set_header โฮสต์ example.com;
}
...

ในการกำหนดค่า NGINX ของคุณสำหรับ reverse proxy จากนั้น Apache จะไม่สนใจ X-Forwarded-Host เพราะคุณต้องตั้งค่าส่วนหัวของ Host แทน ซึ่ง Apache ควร จัดลำดับความสำคัญของการให้บริการ

นี้ ควร แก้ไขสิ่งต่างๆ - ฉันใช้ระบบ NGINX หลายระบบด้วยวิธีนี้เมื่อโดเมนที่เข้าถึงโดยเบราว์เซอร์แตกต่างจากโฮสต์ที่ตอบสนองของแบ็กเอนด์ - และจนถึงตอนนี้มันใช้งานได้กับแบ็กเอนด์ Django, แบ็กเอนด์ PHP, Apache หรือแม้แต่เซิร์ฟเวอร์ Python HTTP ที่ฉันใช้เพื่อทดสอบสิ่งต่างๆ . และความเข้าใจของฉันเกี่ยวกับ Apache คือมันจะจัดลำดับความสำคัญของส่วนหัวของโฮสต์มากกว่า X-Forwarded-Host

John Hanley avatar
cn flag
ฉันอาจจะผิด. หากคุณส่งคำขอจากบริการ Cloud Run หนึ่งไปยังอีกบริการหนึ่ง ส่วนหัวของโฮสต์ต้องตรงกับบริการที่กำลังเรียกใช้ มิฉะนั้น คุณจะได้รับ 404 นี่คือตัวอย่างที่ Cloud Run Custom Domains และโซลูชันของคุณสามารถแก้ปัญหาได้
co flag
@JohnHanley Ahh ใช่ คุณอาจพูดถูก แต่ถ้า OP คาดหวังว่า endpoint จะให้บริการ example.com และรับ URL อื่น ๆ พวกเขาต้องการตัวฟังทั่วไปที่ตรงกับโดเมนที่เป็นไปได้ทั้งหมดที่นี่ Cloud Run Custom Domains ฉันคิดว่าจะทำงานได้ดีขึ้นสำหรับ OP (ฟังดูเหมือนเป็นคำตอบที่ไม่เหมือนใคร)
John Hanley avatar
cn flag
ฉันคิดว่าโซลูชันของคุณเป็นครึ่งที่ถูกต้องในการเริ่มต้น จากนั้น OP จะสามารถตรวจสอบ Cloud Run Custom Domains เป็นต้น เพื่อให้ตรรกะของโดเมนใช้งานได้ ฉันไม่เข้าใจว่าเขาใช้ชื่อโดเมนเป็นแบ็คเอนด์
co flag
@JohnHanley ถ้าเซิร์ฟเวอร์ $BACKEND ใช้งาน 50 โดเมนแยกกันและให้บริการเนื้อหาตามส่วนหัวของโฮสต์ (ซึ่งเป็นวิธีการทำงานของ VirtualHosts และฟิลด์ชื่อเซิร์ฟเวอร์ / ServerAlias ​​ใน Apache) จำเป็นต้องมีส่วนหัวของโฮสต์เพื่อระบุวิธีเชื่อมต่อและกับสิ่งที่ โฮสต์ที่จะผ่านเพื่อให้เนื้อหาได้รับการบริการอย่างถูกต้อง นั่นเป็นวิธีการที่ NGINX กำหนดว่าโซนใดที่จะให้บริการ โดยบังเอิญ - การจับคู่ฟิลด์ server_name (regex, wildcard ฯลฯ) จะกำหนดว่าเซิร์ฟเวอร์/ไซต์ใดที่จะให้บริการสำหรับคำขอที่กำหนด
John Hanley avatar
cn flag
อย่างไรก็ตาม นั่นไม่ใช่วิธีการทำงานของ Cloud Run ส่วนหัวของโฮสต์กำหนดบริการที่ Google Cloud GFE กำหนดเส้นทางคำขอ หากแบ็กเอนด์จัดการ 50 โดเมน บริการ Cloud Run จะต้องการโดเมนที่กำหนดเอง 50 โดเมนเนื่องจากโดเมนที่กำหนดเองแต่ละรายการจะต้องมีการแมปโดเมน ฉันไม่แน่ใจว่ารองรับด้วยซ้ำ (โควต้าจำกัด) แบ็กเอนด์จะต้องใช้วิธีอื่นเพื่อรองรับการระบุประเภทนั้น ส่วนหัวที่กำหนดเองอาจใช้งานได้ อย่างไรก็ตาม นี่เป็นตัวอย่างหนึ่งของการขัดเกลางานออกแบบในบริการที่อาจไม่เหมาะกับสถาปัตยกรรม
co flag
@JohnHanley ฉันคิดว่าทั้งหมดที่ฉันต้องรู้ก็คือตำแหน่งของ NGINX ถ้าฉันอ่าน OP ถูกต้อง example.com -> NGINX -> Google Cloud Run ดังนั้น ส่วนหัวของโฮสต์สำหรับบล็อกตำแหน่งที่ตั้งและ proxy_pass จะต้องตั้งค่าโฮสต์เป็น URL เฉพาะของ GCR สำหรับคำขอ สมมติว่า NGINX นั่งอยู่ที่ example.com จริงๆ
fairport avatar
nl flag
ขออภัย คำตอบนี้ใช้ไม่ได้เพราะฉันไม่สามารถเชื่อมต่อกับคอนเทนเนอร์ Apache โดยใช้ที่อยู่ IP ฉันต้องใช้โดเมนที่มีส่วนหัวของโฮสต์เพื่อให้ Google รู้วิธีกำหนดเส้นทางคำขอไปยังเซิร์ฟเวอร์ที่ถูกต้อง ฉันต้องการแก้ไขส่วนหัวของโฮสต์ใน Apache เพื่อให้แอปพลิเคชันสร้างเส้นทางได้อย่างถูกต้อง ส่วนหัวของโฮสต์ที่ถูกต้องอยู่ใน X-Forwarded-Host หรือฉันสามารถใช้ตัวแปรสภาพแวดล้อมเพื่อกำหนดได้เช่นกัน
co flag
@fairport ฉันไม่แน่ใจว่ามีฟังก์ชันใน Apache เพื่อเขียนส่วนหัว X-Forwarded-Host ใหม่ ฉันกำลังมองหา แต่ไม่เห็นฟังก์ชันดังกล่าว ฉันคิดว่าหากแอปของคุณไม่ทำงานตามที่ Google คาดไว้ คุณต้องสร้างใหม่/ปรับโครงสร้างแอปใหม่โดยคำนึงถึงข้อกำหนดของ Google แทนการพยายามแฮ็กแอปให้เข้าที่ ซึ่งสมเหตุสมผลเกี่ยวกับ GCR เพราะพวกเขากำลังจัดโครงสร้างในลักษณะที่เฉพาะเจาะจงมาก (ฉันอาจลบคำตอบของฉันในบางจุดหลังจากที่คุณอ่านความคิดเห็นนี้)
fairport avatar
nl flag
ใช่ ฉันกำลังดูเอกสารประกอบของคำสั่ง Apache RequestHeader และดูว่าฉันสามารถแทนที่ส่วนหัวของโฮสต์โดยใช้ตัวแปรสภาพแวดล้อมได้หรือไม่ อีกวิธีในการแก้ไขปัญหานี้อาจเป็นการตั้งค่าเครือข่าย VPC ซึ่งวิธีนี้จะทำให้บริการ Cloud Run ควรมีที่อยู่ IP แบบคงที่ที่ฉันสามารถใช้แทน URL ได้ วิธีสุดท้ายที่ฉันสามารถคิดได้ว่ากำลังแก้ไขแอปพลิเคชันหรือไม่ ดังนั้นมันจะแทนที่ส่วนหัวของโฮสต์โดยใช้ X-Forwarded-Host หรือตัวแปรสภาพแวดล้อม แต่ดูเหมือนว่าจะเป็นการแฮ็กฉันจะตอบคำถามของตัวเองหากพบวิธีที่ดีในการแก้ปัญหานี้
Score:1
ธง nl

ฉันแก้ไขปัญหานี้โดยกำหนดตัวแปรสภาพแวดล้อมใหม่ที่เรียกว่า APP_HOST ในแผงควบคุม Google Cloud Run และตั้งค่าเป็น ตัวอย่าง.คอม.

จากนั้นฉันเพิ่มการกำหนดค่าต่อไปนี้ในไฟล์ .htaccess ไฟล์ในรูทเอกสาร:

<IfModule mod_env.c>
    PassEnv APP_HOST
</IfModule>

<IfModule mod_headers.c>
    RequestHeader set Host %{APP_HOST}e env=APP_HOST
</IfModule>

สิ่งนี้ทำให้ฉันสามารถแทนที่ เจ้าภาพ ส่วนหัวจาก ตัวอย่าง-8gnm1aqrns-lz.a.run.app ถึง ตัวอย่าง.คอม ขึ้นอยู่กับตัวแปรสภาพแวดล้อม APP_HOST.

แน่นอนว่าฉันสามารถฮาร์ดโค้ดชื่อโฮสต์ได้ แต่ฉันคิดว่าการใช้ตัวแปรสภาพแวดล้อมช่วยให้คุณมีความยืดหยุ่นมากขึ้นหากคุณต้องการใช้ชื่อเดียวกัน .htaccess ไฟล์ในบริบทที่แตกต่างกัน เช่น บนเซิร์ฟเวอร์ชั่วคราว

แก้ไข

นี่คือวิธีที่คุณสามารถแก้ไขได้โดยใช้ X-ส่งต่อโฮสต์ตัวอย่างเช่น หากคุณใช้งานโฮสต์เสมือนและคุณต้องการไซต์เพื่อให้สามารถเข้าถึงได้จากหลายโดเมน

<IfModule mod_setenvif.c>
    SetEnvIf X-Forwarded-Host (.*) REAL_HOST_HEADER=$1
    <IfModule mod_headers.c>
        RequestHeader set Host "%{REAL_HOST_HEADER}e"
    </IfModule>
</IfModule>

สิ่งนี้จะคว้าส่วนหัวจาก X-ส่งต่อโฮสต์ และตั้งค่า เจ้าภาพ ส่วนหัวตามค่า

โพสต์คำตอบ

คนส่วนใหญ่ไม่เข้าใจว่าการถามคำถามมากมายจะปลดล็อกการเรียนรู้และปรับปรุงความสัมพันธ์ระหว่างบุคคล ตัวอย่างเช่น ในการศึกษาของ Alison แม้ว่าผู้คนจะจำได้อย่างแม่นยำว่ามีคำถามกี่ข้อที่ถูกถามในการสนทนา แต่พวกเขาไม่เข้าใจความเชื่อมโยงระหว่างคำถามและความชอบ จากการศึกษาทั้ง 4 เรื่องที่ผู้เข้าร่วมมีส่วนร่วมในการสนทนาด้วยตนเองหรืออ่านบันทึกการสนทนาของผู้อื่น ผู้คนมักไม่ตระหนักว่าการถามคำถามจะมีอิทธิพลหรือมีอิทธิพลต่อระดับมิตรภาพระหว่างผู้สนทนา