Як правильно обробити відносні URL-адреси за допомогою зворотного проксі


51

У мене в Apache встановлено зворотну установку проксі:

Сервер A з адресою www.example.com/folder - це зворотний проксі-сервер.

Він відображається на: Сервер 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, якщо ви пам’ятаєте?
Кімберлі Ш

Відповіді:


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>

П'ять ) Іноді розробники абсолютно неосвічені і мають свої програми не тільки генерувати абсолютний URL, але навіть включати ім'я хоста частина в їх URL, і отриманий HTML - код виглядає наступним чином : <img src=http://test.example.com/icons/logo.png>.

A ) Ви можете використовувати комбіноване рішення DNS з розділеним горизонтом та сценарій 4. І внутрішні, і зовнішні користувачі використовують test.example.com, але ваш внутрішній DNS вказує безпосередньо на ip-адресу сервера test.example.com. Для зовнішніх користувачів публічний запис для test.example.com вказує на ip-адресу вашого загальнодоступного веб-сервера www.example.com, і тоді ви можете використовувати рішення 4.

B ) Ви можете фактично отримати apache для не лише запитів проксі на test.example.com, але й переписати тіло відповідей до того, як воно буде передане вашим користувачам. (Зазвичай проксі лише переписує заголовки / відповіді HTTP). mod_substitute in 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 в підкаталог як / папку таблиці стилів, іконки і т.д. будуть розміщені в папці / / 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-сторінках.

пор. Як правильно поводитися з відносними URL-адресами із зворотним проксі-сервером для деяких прикладів.

Як приклад прикладу, ось як ви можете налаштувати 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 і новіших
версій

Ваша відповідь бездоганна. Однак я зустрічав випадок, коли вміст не html, а швидше pdf. Використання ProxyHTMLURLMap не працювало для мене. Будь-які інші пропозиції?
Мохаммед Еннаді Ель Ідріссі

2
Якщо ваш вміст у форматі PDF, вам не потрібно переписувати в нього URL-адреси! Якщо ви не хочете, щоб ваші користувачі переходили до посилань у PDF, щоб отримати доступ до інших сторінок вашого веб-сайту, але це звучить складно. Щоб відключити перезапис URL-адрес, просто опустіть останні 2 директиви: SetOutputFilter& ProxyHTMLURLMap.
Лукас Кімон

Можливо, вам потрібно буде додати RequestHeader unset Accept-Encoding, щоб уникнути помилок кодування
zar3bski

5

Для зворотного проксі можна скористатися наступним способом:
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>  
    

Сподіваюся, що це допоможе.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.