Cách xử lý các url tương đối chính xác với proxy ngược


51

Tôi có một thiết lập proxy ngược như sau trong Apache:

Máy chủ A có địa chỉ www.example.com/folder là máy chủ proxy ngược.

Nó ánh xạ tới: Máy chủ B có địa chỉ test.ADEupurl.com

Đây là loại công trình. Nhưng vấn đề tôi gặp phải là, trên www.example.com/folder, tất cả các liên kết tương đối đều có dạng www.example.com/css/examplefilename.css chứ không phải www.example.com/folder/css/examplefilename. css

Làm thế nào để tôi sửa lỗi này?

Cho đến nay proxy ngược của tôi có cái này trên Máy chủ A (www.example.com):

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

Những giải pháp nào dưới đây phù hợp với bạn trong câu trả lời của HBruijn, nếu bạn nhớ?
Kimberly W

Câu trả lời:


81

Apache ProxyPassRewrite không viết lại các nội dung phản hồi nhận được từ http://test.example.com , chỉ các tiêu đề (như chuyển hướng đến trang 404, v.v.).

Một số lựa chọn thay thế:

Một ) Viết lại ứng dụng nội bộ để sử dụng các đường dẫn tương đối thay vì tuyệt đối. tức là ../css/style.cssthay vì/css/style.css

Hai ) Triển khai ứng dụng nội bộ trong cùng một thư mục con /folderthay vì trong thư mục gốc của test.example.com.

Ba ) Một và hai thường không thể xảy ra ... Nếu bạn may mắn, ứng dụng nội bộ chỉ sử dụng hai hoặc ba thư mục con và những thư mục này không được sử dụng trên trang web chính của bạn , chỉ cần viết một loạt các dòng 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/

Bốn ) Tạo một tên miền phụ riêng cho ứng dụng nội bộ và chỉ cần đảo ngược mọi thứ proxy:

<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>

Năm ) Đôi khi các nhà phát triển hoàn toàn không biết gì và các ứng dụng của họ không chỉ tạo ra URL tuyệt đối mà thậm chí còn bao gồm cả phần tên máy chủ trong URL của họ và mã HTML kết quả trông như thế này : <img src=http://test.example.com/icons/logo.png>.

A ) Bạn có thể sử dụng giải pháp kết hợp của DNS và kịch bản phân chia chân trời 4. Cả người dùng nội bộ và bên ngoài đều sử dụng test.example.com, nhưng DNS nội bộ của bạn trỏ trực tiếp đến địa chỉ IP của máy chủ test.example.com. Đối với người dùng bên ngoài, bản ghi công khai cho test.example.com trỏ đến địa chỉ IP của máy chủ web công cộng của bạn www.example.com và sau đó bạn có thể sử dụng giải pháp 4.

B ) Bạn thực sự có thể nhận được apache để không chỉ yêu cầu proxy đến test.example.com, mà còn viết lại nội dung phản hồi trước khi nó được truyền tới người dùng của bạn. (Thông thường một proxy chỉ viết lại tiêu đề / phản hồi HTTP). mod_substolarship trong apache 2.2. Tôi đã không kiểm tra nếu nó kết hợp tốt với mod_proxy, nhưng có thể các công việc sau:

<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
Thánh bò trả lời tốt. Haven thậm chí đã không thử bất kỳ trong số này nhưng chỉ muốn nói cảm ơn cho bài viết! Giúp một triệu. Đi để kiểm tra một số ý tưởng này ngay bây giờ và sẽ báo cáo lại ngay :)
Nhân viên chăm chỉ

Xin hỏi nhanh, cho điểm 2 nếu tôi hiểu đúng về bạn, bạn đang đề nghị tôi triển khai lại adpp để test.ADEupurl.com/folder? Điều này sẽ yêu cầu bất kỳ thay đổi cho tập tin cấu hình apache của tôi? Đây có vẻ là giải pháp nhanh nhất
Hard worker

Ngoài ra, xin lỗi đã làm phiền bạn nhưng với điểm 1 khi tôi thử những gì bạn đề xuất vấn đề tôi mô tả trong câu hỏi của tôi vẫn tồn tại. Ví dụ ở đây tôi đã sử dụng: <link rel = "Stylesheet" type = "text / css" href = "../ css / custom.css" /> và đối với địa chỉ liên kết trong trình duyệt, nó sẽ xuất ra test.ADEupurl.com /css/bootstrap.css chứ không phải test.ADEupurl.com/folder/css/bootstrap.css . Bạn có gợi ý nào về việc này không, nó sẽ hữu ích nhất
làm việc chăm chỉ

Thông thường, khi bạn triển khai lại một ứng dụng đã được cài đặt trong DocumentRoot sang thư mục con như / thư mục, các biểu định kiểu, biểu tượng, v.v. sẽ được triển khai trong / thư mục / css và / thư mục / biểu tượng, v.v. Sau đó, các liên kết trong đầu ra HTML sẽ trở nên giống như <img src=/folder/icons/button.png>trong lần lượt sẽ bị bắt bởi ProxyPass /folder/ http://test.madeupurl.com/folder/chỉ thị.
HBruijn

Trang test.ADEupurl.com/content/index.html muốn bao gồm test.ADEupurl.com/css/custom.css. Ở vị trí đó bạn nên sử dụng URL tương đối href="../css/custom.css"và không href="/css/custom.css". Khi người dùng internet truy xuất trang, URL sẽ là www.example.com/folder/content/index.html. URL cho css sau đó sẽ là: www.example.com/folder/content/../css/custom.cssđó thực sự www.example.com/folder/css/custom.csssẽ được chuyển tiếp đến test.madeupurl.com/css/custom.css.
HBruijn

8

Để bổ sung cho câu trả lời của HBruijn , nếu bạn chọn giải pháp (3) "ProxyPass", bạn cũng có thể phải sử dụng mod_proxy_html để viết lại một số URL trong các trang HTML của mình.

xem Làm thế nào để xử lý các url tương đối chính xác với một proxy ngược cho một số ví dụ.

Như một ví dụ được áp dụng, đây là cách bạn có thể định cấu hình Apache bằng cách sử dụng ProxyHTMLURLMapquy tắc để chuyển tiếp mọi thứ tại your-domain-name.com/pad sang phiên bản Etherpad của bạn chạy cục bộ trên port 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
Xin lưu ý rằng mod_proxy_html chỉ được bao gồm từ Apache 2.4 trở lên, trong đó câu hỏi ban đầu ở trên là dành cho Apache 2.2
HBruijn

Câu trả lời của bạn là hoàn hảo. Tuy nhiên, tôi đã gặp một trường hợp nội dung không phải là html, nó là pdf. Sử dụng ProxyHTMLURLMap không hiệu quả với tôi. Bất cứ một đề nghị nào khác?
Mohamed Ennahdi El Idrissi

2
Nếu nội dung của bạn là PDF, bạn không cần phải viết lại URL trong đó! Trừ khi bạn muốn người dùng nhấp vào các liên kết trong PDF để truy cập các trang khác trên trang web của bạn, nhưng điều này nghe có vẻ khó khăn. Để tắt tính năng viết lại URL, chỉ cần bỏ qua 2 chỉ thị cuối cùng: SetOutputFilter& ProxyHTMLURLMap.
Lucas Cimon

Bạn có thể cần phải thêm Yêu cầu hủy đặt mã hóa Chấp nhận để tránh lỗi mã hóa
zar3bski

5

Bạn có thể sử dụng cách sau để tạo proxy ngược:
1. Cài đặt mod_proxy_html

    yum install mod_proxy_html
  1. Tải mô-đun mod_proxy_html

    LoadModule proxy_html_module modules/mod_proxy_html.so
    
  2. Và sử dụng cài đặt sau

    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>  
    

Hy vọng điều này giúp đỡ.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.