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

Правило исключения прокси-сервера Apache игнорируется

Я слишком долго ломал голову над этим.

У меня есть то, что я считаю простой конфигурацией с использованием правил proxypass для Apache, я хочу предоставить список исключений, прежде чем использовать правило 'catchall' для перенаправления всего трафика на локальный сервер узла.

Настройка следующая:

ProxyPass        /contact-us !
ProxyPass        / http://localhost:3000/
ProxyPassReverse / http://localhost:3000/

Результатом вышеуказанной конфигурации является то, что /contact-us отправляется на узел (localhost:3000), насколько я понимаю документацию, ее следует игнорировать. Если я установлю пункт назначения для /contact-us тогда запрос обрабатывается правильно и возвращается прокси-контент.

Я что-то упускаю? Добавляет ли общий (/) к набору правил изменить поведение?

Изменить: добавлен остаток файла для справки

<IfModule mod_ssl.c>
<VirtualHost *:443>
    ServerName  dev.site.com
    ServerAdmin admin@dev.site.com

    ProxyPass        /contact-us !
    ProxyPass        / http://localhost:3000/
    ProxyPassReverse / http://localhost:3000/

    DocumentRoot /var/www/site/public
    <Directory /var/www/site/public>
        Options Indexes FollowSymLinks MultiViews
        AllowOverride All
        Require all granted
    </Directory>

    <IfModule mod_headers.c>
        SetEnvIf Origin "^http(s)?://(.+\.)?(dev\.site\.com)$"  origin_is=$0

        Header always set Access-Control-Allow-Origin %{origin_is}e env=origin_is
        Header always set Access-Control-Allow-Credentials true env=origin_is
    </IfModule>

    ErrorLog ${APACHE_LOG_DIR}/dev.site.com-error.log
    CustomLog ${APACHE_LOG_DIR}/dev.site.com-access.log combined

    SSLCertificateFile /etc/letsencrypt/live/dev.site.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/dev.site.com/privkey.pem
    Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>

Основываясь на небольшом комментарии в документации для Apache (только 2.4.26 и выше), можно использовать no-proxy переменная среды для исключений прокси.

Однако это становится уродливым, когда вам нужно внутреннее переписать для обслуживания вашей исключенной страницы, потому что тогда исключения ProxyPass и просто установка no-proxy переменная на основе REQUEST_URI не имеет никакого эффекта, потому что REQUEST_URI изменяется после внутренней перезаписи, и ProxyPass оценивается снова, а переменная среды видна только как REDIRECT_no-proxy не как no-proxy.

Здесь мы можем использовать небольшую уловку, и это сработает:

RewriteEngine on
RewriteRule ^/contact-us$ - [E=no-proxy:1]
RewriteCond %{ENV:REDIRECT_no-proxy} .+
RewriteRule .* - [E=no-proxy:1]

Если вы поместите это в раздел виртуального хоста, он будет работать. Если вы поместите его в раздел Directory, этого не произойдет, потому что ProxyPass уже задействован.

Я нашел свою проблему, и вы были правы, @HBruijn.

Я запускаю фреймворк Laravel на виртуальном хосте, что означает, что запросы направляются на /index.php для маршрутизации, поэтому после успешного выполнения первого правила (/contact-us !) запрос был переписан на /index.php который затем проксировался в правиле catch all.

Мне удалось добавить правило исключения для (/index.php), а также следующий запрос Fpm (см. журнал ниже) для решения моей проблемы. Это решение может подойти не всем.

Я смог разгадать это благодаря этому комментарию @yunzen - https://serverfault.com/a/895673, добавляя LogLevel error proxy:trace5 Я смог увидеть следующее:

[Mon Mar 04 04:39:56.876129 2019] [proxy:trace2] [pid 5564] mod_proxy.c(683): [client 220.244.99.86:51059] AH03461: attempting to match URI path '/contact-us' against prefix '/index.php' for proxying
[Mon Mar 04 04:39:56.876170 2019] [proxy:trace2] [pid 5564] mod_proxy.c(683): [client 220.244.99.86:51059] AH03461: attempting to match URI path '/contact-us' against prefix '/contact-us' for proxying
[Mon Mar 04 04:39:56.876174 2019] [proxy:trace1] [pid 5564] mod_proxy.c(736): [client 220.244.99.86:51059] AH03463: proxying is explicitly disabled for URI path '/contact-us'; declining
[Mon Mar 04 04:39:56.876880 2019] [proxy:trace2] [pid 5564] mod_proxy.c(683): [client 220.244.99.86:51059] AH03461: attempting to match URI path '/index.php' against prefix '/index.php' for proxying
[Mon Mar 04 04:39:56.876890 2019] [proxy:trace1] [pid 5564] mod_proxy.c(736): [client 220.244.99.86:51059] AH03463: proxying is explicitly disabled for URI path '/index.php'; declining
[Mon Mar 04 04:39:56.876936 2019] [proxy:trace2] [pid 5564] mod_proxy.c(683): [client 220.244.99.86:51059] AH03461: attempting to match URI path '/php72-fcgi-www/index.php' against prefix '/index.php' for proxying

Обратите внимание на изменения контекста от этого единственного запроса.