วิธีจัดการ URL ที่สัมพันธ์กันอย่างถูกต้องด้วย reverse proxy


51

ฉันมีการตั้งค่าพร็อกซีย้อนกลับดังนี้ใน Apache:

เซิร์ฟเวอร์ A พร้อมที่อยู่ www.example.com/folder เป็น reverse proxy server

มันแมปไปที่: เซิร์ฟเวอร์ B พร้อมที่อยู่ test.madeupurl.com

งานประเภทนี้ แต่ปัญหาที่ฉันมีคือใน www.example.com/folder ลิงก์ที่เกี่ยวข้องทั้งหมดนั้นอยู่ในรูปแบบ www.example.com/css/examplefilename.css แทนที่จะเป็น www.example.com/folder/css/examplefilename CSS

ฉันจะแก้ไขได้อย่างไร

จนถึงตอนนี้พร็อกซีย้อนกลับของฉันมีสิ่งนี้บนเซิร์ฟเวอร์ A (www.example.com):

<Location /folder>
    ProxyPass  http://test.madeupurl.com
    ProxyPassReverse http://test.madeupurl.com
</Location>

โซลูชั่นใดด้านล่างที่คุณใช้ในคำตอบของ HBruijn หากคุณจำได้
Kimberly W

คำตอบ:


81

Apache ProxyPassRewrite ไม่ได้เขียนเนื้อหาการตอบสนองที่ได้รับจากhttp://test.example.comใหม่เพียงส่วนหัวเท่านั้น (เช่นเปลี่ยนเส้นทางไปยังหน้า 404 และอื่น ๆ )

ทางเลือกจำนวนมาก:

หนึ่ง ) เขียนแอปภายในเพื่อใช้เส้นทางสัมพัทธ์แทนสัมบูรณ์ เช่น../css/style.cssแทน/css/style.css

สอง ) ปรับใช้แอปภายในอีกครั้งในไดเรกทอรีย่อยเดียวกัน/folderแทนที่จะอยู่ในรูทของ test.example.com

สาม ) หนึ่งและสองไม่น่าจะเกิดขึ้น ... หากคุณโชคดีแอปภายในใช้เฉพาะไดเรกทอรีย่อยสองหรือสามอันและไม่ได้ใช้ในไซต์หลักของคุณเพียงเขียนบรรทัด ProxyPass:

# Expose Internal App to the internet.
ProxyPass /externalpath/  http://test.example.com/
ProxyPassReverse /externalpath/  http://test.example.com/
# Internal app uses a bunch of absolute paths. 
ProxyPass /css/  http://test.example.com/css/
ProxyPassReverse /css/  http://test.example.com/css/
ProxyPass /icons/  http://test.example.com/icons/
ProxyPassReverse /icons/  http://test.example.com/icons/

สี่ ) สร้างโดเมนย่อยแยกต่างหากสำหรับแอปภายในและย้อนกลับพร็อกซีทุกอย่าง

<VirtualHost *:80>
   ServerName app.example.com/
   # Expose Internal App to the internet.
   ProxyPass /  http://test.internal.example.com/
   ProxyPassReverse /  http://test.internal.example.com/
</VirtualHost>

ห้า ) บางครั้งนักพัฒนามี clueless อย่างสมบูรณ์และมีการใช้งานของพวกเขาไม่เพียง แต่สร้าง URL แน่นอน แต่ยังรวมถึงส่วนชื่อโฮสต์ใน URL ของพวกเขาและส่งผลให้รหัส HTML <img src=http://test.example.com/icons/logo.png>ลักษณะเช่นนี้:

A ) คุณสามารถใช้โซลูชันคอมโบของ DNS horizon ที่แบ่งและสถานการณ์สมมติ 4 ทั้งผู้ใช้ภายในและภายนอกใช้ test.example.com แต่ DNS ภายในของคุณชี้ไปยังที่อยู่ ip ของเซิร์ฟเวอร์ test.example.com โดยตรง สำหรับผู้ใช้ภายนอกระเบียนสาธารณะสำหรับ test.example.com จะชี้ไปยังที่อยู่ ip ของเว็บเซิร์ฟเวอร์สาธารณะ www.example.com แล้วคุณสามารถใช้โซลูชัน 4 ได้

B ) คุณสามารถรับ apache ไปที่ไม่เพียง แต่ร้องขอพร็อกซีเพื่อทดสอบ example.com แต่ยังเขียนเนื้อหาการตอบกลับก่อนที่มันจะถูกส่งไปยังผู้ใช้ของคุณ (โดยปกติพร็อกซีจะเขียนเฉพาะส่วนหัว / การตอบกลับ HTTP เท่านั้น) mod_substitute ใน apache 2.2 ฉันยังไม่ได้ทดสอบว่ามันใช้งานได้ดีกับ mod_proxy แต่อาจใช้งานได้ดังต่อไปนี้

<Location /folder/>
  ProxyPass http://test.example.com/
  ProxyPassReverse http://test.example.com/ 
  AddOutputFilterByType SUBSTITUTE text/html
  Substitute "s|test.example.com/|www.example.com/folder/|i" 
</Location>

4
คำตอบที่ดีวัวศักดิ์สิทธิ์ ยังไม่ได้ลองสิ่งเหล่านี้เลย แต่อยากจะบอกว่าขอบคุณสำหรับบทความนี้! ช่วยหนึ่งล้าน กำลังจะทดสอบแนวคิดเหล่านี้ออกมาในขณะนี้และจะรายงานกลับในไม่ช้า :)
ผู้ทำงานหนัก

โปรดคำถามด่วนสำหรับจุดที่ 2 ถ้าฉันเข้าใจว่าคุณถูกต้องคุณแนะนำให้ฉันปรับใช้ adpp อีกครั้งเพื่อ test.madeupurl.com/folder? สิ่งนี้จะต้องมีการเปลี่ยนแปลงใด ๆ กับไฟล์กำหนดค่า apache ของฉันหรือไม่? ดูเหมือนว่าวิธีแก้ปัญหาที่เร็วที่สุด
ผู้ทำงานหนัก

นอกจากนี้ขอโทษที่รบกวนคุณ แต่มีจุดที่ 1 เมื่อฉันลองสิ่งที่คุณแนะนำปัญหาที่ฉันอธิบายในคำถามของฉันยังคงมีอยู่ ตัวอย่างเช่นที่นี่ฉันใช้: <link rel = "stylesheet" type = "text / css" href = "../ css / custom.css" /> และสำหรับลิงค์ที่อยู่ในเบราว์เซอร์มันจะแสดงผลtest.madeupurl.com /css/bootstrap.cssมากกว่าtest.madeupurl.com/folder/css/bootstrap.css คุณช่วยแนะนำได้ไหมว่ามันจะมีประโยชน์มากที่สุด
ผู้ทำงานหนัก

บ่อยครั้งเมื่อคุณปรับใช้แอปพลิเคชันที่ติดตั้งใน DocumentRoot ไปยังไดเรกทอรีย่อยเช่น / โฟลเดอร์สไตล์ชีต, ไอคอน ฯลฯ จะถูกปรับใช้ใน / folder / css และ / โฟลเดอร์ / ไอคอน ฯลฯ จากนั้นลิงก์ในเอาต์พุต HTML จะกลายเป็นเหมือน<img src=/folder/icons/button.png>ใน เทิร์นจะถูกจับโดยProxyPass /folder/ http://test.madeupurl.com/folder/คำสั่ง
HBruijn

หน้า test.madeupurl.com/content/index.html ต้องการรวม test.madeupurl.com/css/custom.css ในสถานที่ที่คุณควรใช้ URL ที่เกี่ยวข้องและไม่ได้href="../css/custom.css" href="/css/custom.css"เมื่อผู้ใช้อินเทอร์เน็ตเรียกค้นหน้า URL จะเป็น www.example.com/folder/content/index.html URL สำหรับ CSS แล้วจะเป็น: www.example.com/folder/content/../css/custom.cssที่เป็นจริง ซึ่งจะถูกส่งต่อไปยังwww.example.com/folder/css/custom.css test.madeupurl.com/css/custom.css
HBruijn

8

เป็นส่วนเสริมของคำตอบของHBruijnหากคุณเลือกใช้โซลูชัน(3) "ProxyPass" คุณอาจต้องใช้mod_proxy_htmlเพื่อเขียน URL ใหม่ในหน้า HTML ของคุณ

cf เลย วิธีจัดการ URL ที่เกี่ยวข้องอย่างถูกต้องด้วย reverse proxyสำหรับตัวอย่าง

เป็นตัวอย่างที่ใช้นี่คือวิธีที่คุณสามารถกำหนดค่า Apache โดยใช้ProxyHTMLURLMapกฎเพื่อส่งต่อทุกอย่างที่your-domain-name.com/padไปยังอินสแตนซ์Etherpadของคุณที่ทำงานในเครื่องบนพอร์ต 9001:

<Location /pad> ProxyPass http://localhost:9001 retry=0 # retry=0 => avoid 503's when restarting etherpad-lite ProxyPassReverse http://localhost:9001 SetOutputFilter proxy-html ProxyHTMLURLMap http://localhost:9001 </Location> RewriteRule ^/pad$ /pad/ [R]


2
โปรดทราบว่า mod_proxy_html นั้นรวมอยู่ใน Apache 2.4 ขึ้นไปเท่านั้นโดยที่คำถามดั้งเดิมข้างต้นสำหรับ Apache 2.2
HBruijn

คำตอบของคุณไร้ที่ติ อย่างไรก็ตามฉันพบกรณีที่เนื้อหาไม่เป็น html มันเป็นไฟล์ pdf ใช้ ProxyHTMLURLMap ไม่ได้ผลสำหรับฉัน ข้อเสนอแนะอื่น ๆ ?
Mohamed Ennahdi El Idrissi

2
หากเนื้อหาของคุณเป็น PDF คุณไม่จำเป็นต้องเขียน URL ซ้ำ! หากคุณไม่ต้องการให้ผู้ใช้คลิกลิงก์ใน PDF เพื่อเข้าถึงหน้าอื่น ๆ ของเว็บไซต์ของคุณ แต่ฟังดูยุ่งยาก หากต้องการปิดใช้งานการเขียน URL ใหม่เพียงแค่ละเว้น 2 คำสั่งล่าสุด: SetOutputFilter& ProxyHTMLURLMap.
Lucas Cimon

คุณอาจต้องเพิ่มRequestHeader unset ยอมรับการเข้ารหัสเพื่อหลีกเลี่ยงข้อผิดพลาดในการเข้ารหัส
zar3bski

5

คุณสามารถใช้วิธีต่อไปนี้เพื่อสร้าง reverse proxy:
1. ติดตั้ง mod_proxy_html

    yum install mod_proxy_html
  1. โหลดโมดูล mod_proxy_html

    LoadModule proxy_html_module modules/mod_proxy_html.so
    
  2. และใช้การตั้งค่าต่อไปนี้

    ProxyRequests off  
    ProxyPass /folder/  http://test.madeupurl.com  
    ProxyHTMLURLMap http://test.madeupurl.com  /folder  
    
    <Location /folder/>  
        ProxyPassReverse /  
        ProxyHTMLEnable On  
        ProxyHTMLURLMap  /  /folder/  
        RequestHeader    unset  Accept-Encoding  
    </Location>  
    

หวังว่าความช่วยเหลือนี้

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