Перезапись URL в Apache в обратном прокси

12

Я развертываю Apache перед приложением, размещенным в Karaf (Apache и Karaf находятся на разных серверах). Я хочу, чтобы Apache работал как обратный прокси-сервер, а также скрывал часть URL.

URL-адрес для получения страницы входа в приложение непосредственно с сервера приложений http://app-server:8181/jellyfish. Страницы обслуживаются экземпляром Jetty, работающим в Karaf. Конечно, это поведение обычно блокируется брандмауэром для всего, кроме обратного прокси-сервера.

Если брандмауэр выключен, если вы нажмете этот URL, Jetty загрузит страницу входа. Адресная строка браузера корректно меняется на http://app-server:8181/jellyfish/login?0и все работает.

Я хочу, чтобы http://web-server(то есть из корня) сопоставлялся с Jetty на сервере приложений с jellyfishподавленным именем app ( ). Например, браузер будет отображаться http://web-server/login?0в адресной строке, и все последующие URL-адреса и контент будут обслуживаться с доменом веб-сервера и без jellyfishпомех.

Я могу заставить Apache работать как простой обратный прокси, используя следующий конфиг (фрагмент):

ProxyPass /jellyfish http://app-server:8181/jellyfish
ProxyPassReverse / http://app-server:8181/

... но для этого требуется, чтобы URL-адрес браузера содержал jellyfishи переход к корневому URL-адресу ( http://web-server) выдает 404 Not Found.

Я потратил много времени, пытаясь использовать mod_rewriteс и без его [P]флага, чтобы обойти это, но безуспешно. Затем я попробовал эту ProxyPassMatchдирективу, но, похоже, я тоже не могу понять, что это правильно.

Вот текущий конфигурационный файл, загруженный /etc/apache2/sites-available/на веб-сервере. Обратите внимание, что существует локально размещенный каталог изображений. Я также сохранил защиту от эксплойтов mod_rewrite и подавляю пару mod_securityправил, дающих ложные срабатывания.

<VirtualHost *:80>
    ServerAdmin admin@drummer-server
    ServerName drummer-server

    ErrorLog ${APACHE_LOG_DIR}/error.log
    LogLevel warn

    CustomLog ${APACHE_LOG_DIR}/access.log combined

    Alias /images/ "/var/www/images/"

    RewriteEngine On
    RewriteCond  %{REQUEST_URI}  !^$
    RewriteCond  %{REQUEST_URI}  !^/
    RewriteRule  .*              -    [R=400,L]

    ProxyPass /images !

    ProxyPassMatch ^/(.*) http://granny-server:8181/jellyfish/$1
    ProxyPassReverse / http://granny-server:8181/jellyfish

    ProxyPreserveHost On

    SecRuleRemoveById 981059 981060

    <Directory "/var/www/images">
        Options Indexes MultiViews FollowSymLinks
        AllowOverride None
        Order allow,deny
        Allow from all
    </Directory>

</VirtualHost>

Если я перехожу к http://web-server, меня перенаправляют на, http://web-server/jellyfish/homeно это дает 404 с жалобой на попытку доступа /jellyfish/jellyfish/home- NB адресная строка браузера не содержит двойной /jellyfish.

HTTP ERROR 404

Problem accessing /jellyfish/jellyfish/home. Reason:

    Not Found

И, если я иду в http://web-server/login, я перенаправлен на, http://web-server/jellyfish/login?0но это дает 404, с жалобой на попытку доступа /jellyfish/jellyfish/login.

HTTP ERROR 404

Problem accessing /jellyfish/jellyfish/login. Reason:

    Not Found

Итак, я предполагаю, что я как-то прохожу правила дважды. Я также немного удивлен, откуда взялся homeбит URL в первом примере.

Может кто-нибудь указать мне правильное направление, пожалуйста?

Спасибо J.

Джереми Гуч
источник
Я достиг некоторого прогресса в этом, и теперь заменил ProxyPassMatchна эквивалентное использование mod_rewrite, которое решает проблему удаления jellyfishиз URL. Сейчас я смотрю на число 404, которые затем всплывают в отношении базовых элементов, таких как компоненты Wicket, требуемые для Karaf. Вот фрагмент кода:# proxy to the Jellyfish server (ignoring images) RewriteCond %{REQUEST_URI} !^/(images)(.*)$ RewriteRule ^(/.*)$ http://app-server:8181/jellyfish$1 [P] ProxyPassReverse / http://app-server:8181/jellyfish/
Джереми Гуч

Ответы:

10

Вот как я заставил это работать. Помимо изменений в соответствии с моим комментарием к моему первоначальному вопросу, мне нужно было исключить .jsи .cssиз правила, добавившего косую черту.

<VirtualHost *:80>
    ServerAdmin admin@localhost
    ServerName mydomain.com
    ServerAlias www.mydomain.com

    ErrorLog ${APACHE_LOG_DIR}/error.log
    LogLevel warn

    CustomLog ${APACHE_LOG_DIR}/access.log combined

    RewriteLog ${APACHE_LOG_DIR}/rewrite.log
    RewriteLogLevel 9

    Alias /images/ "/var/www/images/"

    RewriteEngine On

    # rewrite rule to prevent proxy exploit
    RewriteCond  %{REQUEST_URI}  !^$
    RewriteCond  %{REQUEST_URI}  !^/
    RewriteRule  .*              -    [R=400,L]

    # consolidate non-www requests onto the www subdomain
    RewriteCond  %{HTTP_HOST}    ^yourdomain\.com$
    RewriteRule  ^(.*)           http://www.yourdomain.com/$1  [R=301,L]

    # Add a trailing slash to the URL (ignoring images, CSS and JavaScript)
    RewriteCond  %{REQUEST_URI}  !^/(images)(.*)$
    RewriteCond  %{REQUEST_URI}  !^/(.*)(.js|.css)$
    RewriteCond  %{REQUEST_URI}  !(.*)/$
    RewriteRule  ^(.*)$          http://%{HTTP_HOST}$1/ [R=301,L]

    # proxy to the Jellyfish server (ignoring images)
    RewriteCond  %{REQUEST_URI}  !^/(images)(.*)$
    RewriteRule  ^(/.*)$         http://app-server:8181/jellyfish$1  [P]
    ProxyPassReverse  /          http://app-server:8181/jellyfish/

    # suppress mod_security rules that were giving false positives
    SecRuleRemoveById 981059 981060

    <Directory "/var/www/images">
            Options Indexes MultiViews FollowSymLinks
            AllowOverride None
            Order allow,deny
            Allow from all
    </Directory>

</VirtualHost>
Джереми Гуч
источник
1

Ты пробовала:

ProxyPassMatch ^/(.*) http://granny-server:8181/$1
ProxyPassReverse / http://granny-server:8181

Или еще проще:

ProxyPass / http://granny-server:8181/
ProxyPassReverse / http://granny-server:8181/

Я написал , как я справляюсь с Apache обратный прокси и Tomcat здесь , если вы хотите сравнить / контраст , что вы установили с тем, что я использую.

Вы можете добавить это, чтобы добавить косую черту в URL:

# Settings for adding a trailing slash to the URL
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/$
RewriteRule ^(.*)$ http://%{HTTP_HOST}$1/ [R=301,L]
JakeGould
источник
Большое спасибо за ответ. К сожалению, это только решает прямую часть проблемы с проксированием. Недостаток, который мне не хватает, - это как убрать слово «медуза» из видимости в адресной строке браузера клиента, чтобы http://web-serverмолча получать прокси http://app-server:8181/jellyfishобратно и обратно.
Джереми Гуч