RewriteRule é processado em tempo de execução antes de ProxyPass. O RewriteRule catchall vai corresponder a tudo. Remova essa regra e use diretivas ErrorPage.
Estou tendo problemas para configurar um proxy reverso com o apache 2.4.6 no RHEL7.5.
Eu tenho o seguinte virtualhost que envia solicitações para três back-ends:
<VirtualHost *:80>
ServerName www.example.com
RewriteEngine On
ProxyPreserveHost On
<Proxy balancer://backend8093>
BalancerMember http://backend01:8093 route=1
BalancerMember http://backend02:8093 route=2
BalancerMember http://backend03:8093 route=3
ProxySet lbmethod=bybusyness
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
ProxySet stickysession=ROUTEID
</Proxy>
# v1, works
#RewriteRule ^/scheduler/(.*) proxy:balancer://backend8093/scheduler/$1 [L]
# v2, doesn't work
ProxyPass "/scheduler" "balancer://backend8093/scheduler"
ProxyPassReverse "/scheduler" "balancer://backend8093/scheduler"
RewriteRule .* http://failure [R,L]
</VirtualHost>
No entanto, quando tento uma onda, eu bato na última regra:
# curl -vvv -H "host: www.example.com" localhost/scheduler/xxx
* About to connect() to localhost port 80 (#0)
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 80 (#0)
> GET /scheduler/xxx HTTP/1.1
> User-Agent: curl/7.29.0
> Accept: */*
> host: www.example.com
>
< HTTP/1.1 302 Found
< Date: Thu, 07 Jun 2018 16:04:46 GMT
< Server: Apache/2.4.6 (Red Hat Enterprise Linux) OpenSSL/1.0.2k-fips
< Location: http://failure
< Content-Length: 198
< Content-Type: text/html; charset=iso-8859-1
, o que significa que a diretiva ProxyPass
não está correspondendo à minha solicitação. Eu também tentei quebrar as diretivas ProxyPass*
dentro de uma diretiva <Location>
, mas também não funcionou.
Experimentar uma regra equivalente (v1) com RewriteRule
funciona como esperado, balanceando solicitações entre os três servidores:
# curl -vvv -H "host: www.example.com" localhost/scheduler/xxx
* About to connect() to localhost port 80 (#0)
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 80 (#0)
> GET /scheduler/xxx HTTP/1.1
> User-Agent: curl/7.29.0
> Accept: */*
> host: www.example.com
>
< HTTP/1.1 200 OK
< Date: Thu, 07 Jun 2018 16:06:34 GMT
< Server: Apache/2.4.6 (Red Hat Enterprise Linux) OpenSSL/1.0.2k-fips
< Last-Modified: Thu, 07 Jun 2018 13:20:51 GMT
< ETag: "11-56e0d26f87639"
< Accept-Ranges: bytes
< Content-Length: 17
< Set-Cookie: ROUTEID=.1; path=/
<
backend01 hello
Posso ver que as solicitações estão combinando com o VirtualHost
adequado, já que estou vendo os redirecionamentos, mas não consigo entender por que o ProxyPass
está aparentemente sendo ignorado.
Eu verifiquei e o apache está carregando os módulos (confirmado também pelo server-info
handler):
# httpd -M | grep proxy
proxy_module (shared)
proxy_ajp_module (shared)
proxy_balancer_module (shared)
proxy_connect_module (shared)
proxy_express_module (shared)
proxy_fcgi_module (shared)
proxy_fdpass_module (shared)
proxy_ftp_module (shared)
proxy_http_module (shared)
proxy_scgi_module (shared)
proxy_wstunnel_module (shared)
Eu tenho outros servidores com configurações semelhantes executando o apache v2.4.6 no RHEL7.4 e o apache 2.2.15 no RHEL6.5, que funcionam. Não consigo encontrar nenhuma diferença nos módulos carregados entre os servidores RHEL7, mas ainda um funciona e o outro não.
Há provavelmente alguma diferença na configuração que estou perdendo. A configuração é principalmente padrão, com mudanças apenas nos arquivos em /etc/httpd/conf.d
(o virtualhost acima está contido em seu próprio arquivo).
O que está falhando aqui? Por que a diretiva ProxyPass
não funciona?