OK, so I figured out what’s going on, but it has opened up a whole new mystery for me.
I took a look at the back-end server logs and for everything that was “working” I found that, for a config line like this:
ProxyPassMatch "^/login$" balancer://webfarm/login.php
A request to https://servername/login produced an access_log entry like this:
"GET /login.php/login HTTP/1.1" 200 610 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0"
So, why this works, is a mystery to me, but I do get /login.php run and returned (and also /login in the $_SERVER superglobal PATH_INFO variable).
But, when I use the config line of:
ProxyPassMatch "^/favicon.ico$" balancer://webfarm/favicon.ico
I get an access_log entry of:
"GET /favicon.ico/favicon.ico HTTP/1.1" 404 221 "https://servername/server" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0"
So I guess Apache knows to pass the first example the PHP file to the PHP-FPM interpreter even with extraneous trailing data, but not to return the favicon.ico file when asked for /favicon.ico/favicon.ico. Since
I don't know how the first example is working, I guess I can't be too upset about the second example not working at all.
Anyway, that explains my 404 on requests for favicon.ico when using ProxyPassMatch. But it now raises the question of why the reverse proxy is doing taking the "front-end" URI onto the "back-end" URL. According to https://httpd.apache.org/docs/current/mod/mod_proxy.html#proxypassmatch “The supplied regular _expression_ is matched against the url, and if it matches, the server will substitute any parenthesized matches into the given string and use it as a new url.” So, to my understanding, since I didn’t provide any parenthesized matches, I wouldn’t expect it to tag anything onto the URL sent to the back-end server, yet it does. It tags on the entire RegEx.
So what I can do is rework my ProxyPassMatch lines with parens and things work as described like:
ProxyPassMatch "^/(login)$" balancer://webfarm/$1.php ProxyPassMatch "^/(favicon.ico)$" balancer://webfarm/$1
But why does ProxyPassMatch force the RegEx onto the end of the proxied URL when I don’t use parentheses. Am I doing something wrong or is this a bug?
Thanks in advance for any suggestions,
Scott From: Scott A. Wozny <sawozny@xxxxxxxxxxx>
Sent: January 3, 2021 5:45 PM To: users@xxxxxxxxxxxxxxxx <users@xxxxxxxxxxxxxxxx> Subject: ProxyPass OK, but not ProxyPassMatch for favicon.ico I’m configuring a reverse proxy in stages. Initially, I just wanted to see if the proxying would work, so In a virtual server, I set up a Proxy balancer://webfarm with a couple BalancerMembers inside and an lbmethod of byrequests. Then I used a:
ProxyPass / balancer://webfarm
to make sure I could get to the content on the back end server and it all worked fine. If a file was accessible on the back-end, I would get it back.
Then, to lock things down further, I removed the prefix-based ProxyPass line and replaced it with a series of:
ProxyPassMatch "^/pagename$" balancer://webfarm/pagename.php
lines for each page followed by a:
ProxyPass / !
to send everything not explicitly allowed a 404. This all works fine.
Checking my logs I saw favicon.ico was getting sent 404s on the proxy server, so I added a line to my config with the other allowed elements:
ProxyPassMatch "^/favicon.ico$" balancer://webfarm/favicon.ico
but after restarting Apache, I still get 404s. Thinking there may be something trailing or following that I can’t see, I tried:
ProxyPassMatch "favicon.ico" balancer://webfarm/favicon.ico
restarted and still 404s. The only way I can make it work is with
ProxyPass /favicon.ico balancer://webfarm/favicon.ico
which, while not the end of the world, is inconsistent with my overall lockdown strategy so I’m wondering if anyone can tell me where I went wrong. I haven’t gotten to the allow-list for my images yet, but I’m worried I’m going to have the same problem with them.
Also, I know the ProxyPassMatch line is definitely matching for favicon.ico because even if I put the ProxyPass / that passes everything to the back-end server back into the config, if it’s below the ProxyPassMatch line for favicon.ico I still get a 404.
Thanks,
Scott |