Назад | Перейти на главную страницу

ProxyPass для конкретного vhost с mod_rewrite

У меня есть веб-сервер, который он настроил для динамического сервера разных корней документов для разных доменов.

<VirtualHost *:80>
    <IfModule mod_rewrite.c>
        # Stage sites :: www.[document root].server.company.com => /home/www/[document root]
        RewriteCond   %{HTTP_HOST}          ^www\.[^.]+\.server\.company\.com$
        RewriteRule   ^(.+)                 %{HTTP_HOST}$1          [C]
        RewriteRule   ^www\.([^.]+)\.server\.company\.com(.*) /home/www/$1/$2  [L]
    </IfModule>
</VirtualHost>

Это делает так, что www.foo.server.company.com будет служить корнем документа server.company.com:/home/www/foo/

Для одного из этих сайтов мне нужно добавить ProxyPass, но я хочу, чтобы он применялся только к этому сайту. Я пробовал что-то вроде

<VirtualHost *:80>
    <Directory /home/www/foo>
        UseCanonicalName Off
        ProxyPreserveHost On
        ProxyRequests Off
        ProxyPass /services http://www-test.foo.com/services
        ProxyPassReverse /services http://www-test.foo.com/services
    </Directory>
</VirtualHost>

Но потом я получаю эти ошибки

ProxyPreserveHost здесь запрещен

ProxyPass | ProxyPassMatch не может иметь путь, если он определен в местоположении.

Как я могу настроить ProxyPass для одного виртуального хоста?

Просто переместите ProxyPass вне <Directory> блок - если он находится в этом контексте, ожидается, что он применяется к этому точному контексту (вместо /services вы хотите подать заявку).

Собственно, с этим блоком вы вообще ничего не делаете, похоже?

<VirtualHost *:80>
    UseCanonicalName Off
    ProxyPreserveHost On
    ProxyRequests Off
    ProxyPass /services http://www-test.foo.com/services
    ProxyPassReverse /services http://www-test.foo.com/services
    # and if you do need to serve from /home/www/foo...
    DocumentRoot /home/www/foo
    <Directory /home/www/foo>
        Order allow,deny
        Allow from all
    </Directory>
</VirtualHost>

редактировать: Пропустил, что на самом деле это не виртуальные хосты - ваш пример, когда это просто каталог в блоке виртуального хоста, заставил меня подумать, что они были отдельными.

В таком случае...

ProxyPreserveHost On
# If it's not already:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.foo
RewriteRule ^/services(.*) http://www-test.foo.com/services$1 [P,L]
ProxyPassReverse /services http://www-test.foo.com/services

Используйте новый VirtualHost

Если вы добавите новый VirtualHost над текущим и укажите домен в ServerName, вы можете проксировать этот конкретный домен.

Возможно, вам потребуется добавить NameVirtualHost если вы используете Apache до версии 2.3.11.

<VirtualHost *:80>
        ServerName www.targetdomain.com
        ProxyPreserveHost On
        ProxyPass /services http://www-test.foo.com/services
        ProxyPassReverse /services http://www-test.foo.com/services

    <IfModule mod_rewrite.c>
        # Stage sites :: www.[document root].server.company.com => /home/www/[document root]
        RewriteCond   %{HTTP_HOST}          ^www\.[^.]+\.server\.company\.com$
        RewriteRule   ^(.+)                 %{HTTP_HOST}$1          [C]
        RewriteRule   ^www\.([^.]+)\.server\.company\.com(.*) /home/www/$1/$2  [L]
    </IfModule>
</VirtualHost>

Я рекомендую установить ProxyRequests Off на уровне сервера.

Когда Apache пытается сопоставить доменные имена, он делает это на основе первого совпадения. Первое совпадение (VirtualHost, ServerName или ServerAlias) в файле конфигурации будет использоваться для маршрутизации трафика. Для подстановочных знаков нет специальной обработки, поэтому любые объявления имени сервера должны появляться перед виртуальным хостом с подстановочными знаками.

ProxyPreserveHost разрешено только в контексте Сервера и VirtualHost. Поэтому, если вы должны использовать эту директиву, вам нужно будет поместить ее в новый VirtualHost.