Apache 2.4 – Fixing ProxyPass Directives Not Working on RHEL7.5

apache-2.4mod-proxyreverse-proxyrhel7

I'm having trouble setting up a reverse proxy with apache 2.4.6 on RHEL7.5.

I have the following virtualhost which sends requests to 3 backends:

<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>

However, when I try a curl, I hit the last rule:

# 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

which means that the ProxyPass directive is not matching my request. I have also tried wrapping the ProxyPass* directives within a <Location> directive but it did not work either.

Trying an equivalent rule (v1) with RewriteRule works as expected, balancing requests between the 3 servers:

# 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

I can see that the requests are matching the proper VirtualHost, since I'm seeing the redirects, but I can't fathom why the ProxyPass is seemingly being ignored.

I've checked and apache is loading the modules (confirmed also by the 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)

I have other servers with similar setups running apache v2.4.6 on RHEL7.4 and apache 2.2.15 on RHEL6.5 which work. I can't find any difference in loaded modules between the RHEL7 servers, but still one works and the other doesn't.

There's probably some difference in configuration which I'm missing. The configuration is mostly default, with changes only to files in /etc/httpd/conf.d (the above virtualhost is contained in its own file).

What is failing here? Why doesn't the ProxyPass directive work?

Best Answer

RewriteRule gets processed at runtime before ProxyPass. The catchall RewriteRule will match everything. Remove that rule and use ErrorPage directives instead.

Related Topic