Apache Proxypass Exclude Rule Ignored – How to Fix

apache-2.4proxypass

I've been scratching my head on this for far too long.

I have what I consider a simple configuration using the proxypass rules for Apache, I want to supply a list of exclusions before using a 'catchall' rule to redirect all traffic to a local node server.

The setup follows:

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

The result of the above configuration is that /contact-us is sent to node (localhost:3000), as I understand the documentation it should be ignored. If I set a destination for /contact-us then the request is correctly handled and the proxied content is returned.

Am I missing something? Does adding the catchall (/) to the ruleset change the behaviour?

Edit: Added rest of file for reference

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

Best Answer

I found my issue and you were right @HBruijn.

I am running the Laravel framework on the virtualhost which means requests are directed to /index.php to be routed, so after the first rule succeeded (/contact-us !) the request was rewritten to /index.php which was then being proxied in the catch all rule.

I was able to add an exclude rule for (/index.php), and also the following Fpm request (see the log below) to solve my problem. This solution may not be possible for everyone.

I was able to unravel this thanks to this comment by @yunzen - https://serverfault.com/a/895673, by adding LogLevel error proxy:trace5 I was able to see the following:

[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

Note the context changes from this single request.