Я слишком долго ломал голову над этим.
У меня есть то, что я считаю простой конфигурацией с использованием правил 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
Обратите внимание на изменения контекста от этого единственного запроса.