Я слишком долго ломал голову над этим.
У меня есть то, что я считаю простой конфигурацией с использованием правил proxypass для Apache,Я хочу предоставить список исключений, прежде чем использовать правило 'catchall' для перенаправления всего трафика на локальный сервер узла.
Настройка выполняется следующим образом:
ProxyPass /contact-us !
ProxyPass / http://localhost:3000/
ProxyPassReverse / http://localhost:3000/
Результатом вышеуказанной конфигурации является / contact-us
отправляется на узел ( localhost: 3000
), как я понимаю в документации его следует игнорировать. Если я установил пункт назначения для / contact-us
, то запрос будет правильно обработан и будет возвращен проксированный контент.
Я что-то упустил? Изменяет ли добавление catchall ( /
) в набор правил поведение?
Edit: Добавлен остаток файла для справки
<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>
Я обнаружил свою проблему, и вы были правы @HBruijn.
Я запускаю фреймворк Laravel на виртуальном хосте, что означает, что запросы направляются на /index.php
на быть перенаправленным, поэтому после успешного выполнения первого правила ( / contact-us!
) запрос был переписан в /index.php
, который затем проксировался в правиле catch all.
Мне удалось добавить правило исключения для ( /index.php
), а также следующий запрос Fpm (см. Журнал ниже), чтобы решить мою проблему. Это решение может быть недоступно для всех.
Я смог разгадать это благодаря этому комментарию @yunzen - https://serverfault.com/a/895673 , добавив LogLevel прокси-сервер ошибки: 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
Обратите внимание на изменения контекста из этого единственного запроса.
На основании небольшого комментария в документации для 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]
Если вы поместите это в раздел Virtual Host, это сработает. Если вы поместите его в раздел Directory, этого не произойдет, потому что ProxyPass уже задействован.