Bug 64537 - ProxyPassMatch with mod_proxy_ajp ignores AJP secret
Summary: ProxyPassMatch with mod_proxy_ajp ignores AJP secret
Status: NEW
Alias: None
Product: Apache httpd-2
Classification: Unclassified
Component: mod_proxy_ajp (show other bugs)
Version: 2.4.43
Hardware: PC Linux
: P2 normal (vote)
Target Milestone: ---
Assignee: Apache HTTPD Bugs Mailing List
Depends on:
Reported: 2020-06-19 10:26 UTC by Cedric Roijakkers
Modified: 2021-04-14 10:01 UTC (History)
2 users (show)

ap_proxy_define_match_worker() (12.52 KB, patch)
2020-06-19 15:29 UTC, Yann Ylavic
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Cedric Roijakkers 2020-06-19 10:26:56 UTC
We have an application running onder Spring Boot, which uses Tomcat to serve http pages. We are connecting with http to Tomcat using the AJP protocol.

The version of Tomcat used in Spring Boot is 9.0.34, and for the AJP connector we have enabled an AJP secret for extra security.

Now, when proxying to this Tomcat server with ProxyPass, this all works fine:

ProxyPass /foo ajp://ajp_host:ajp_port/tomcat/foo retry=0 secret=le_secret

But recentry, we've introduced some configuration that parts of the proxied URLs need to go to a different backend application. For this, the configuration now looks like this:

ProxyPassMatch "^/foo/bar/([0-9]+)/baz$" "ajp://ajp_host1:ajp_port1/tomcat/foo/bar/$1/baz" retry=0 secret=${le_secret}
ProxyPass /foo ajp://ajp_host2:ajp_port2/tomcat/foo retry=0 secret=le_secret

As you can see, the idea is that certain parts under /foo/bar end up on server one, while all the rest under /foo ends up on server two.

This results in HTTP 403 errors when connecting to server one, as if the AJP secret is not being sent to Tomcat.

So my assumption here, is that ProxyPassMatch ignores the secret being passed as an argument.

Interestingly enough, if we configure both Proxy rules to the same backend server as such:

ProxyPassMatch "^/foo/bar/([0-9]+)/baz$" "ajp://ajp_host1:ajp_port1/tomcat/foo/bar/$1/baz" retry=0 secret=${le_secret}
ProxyPass /foo ajp://ajp_host1:ajp_port1/tomcat/foo retry=0 secret=le_secret

Then everything actually works. I suspect this happens because both the ProxyPass line and the ProxyPassMatch line use the same connection pool to Tomcat under water, which does have the secret set (from the ProxyPass line I presume) and it works by accident.

For now, I've worked around the issue by disabling the secret in Tomcat, and then I can see the traffic nicely being split between the two different Tomcats, but I would like to enable the secret again as soon as the issue is fixed.
Comment 1 Yann Ylavic 2020-06-19 10:52:03 UTC
Does it change anything if you declare the ProxyPass before the ProxyPassMatch?
Comment 2 Cedric Roijakkers 2020-06-19 11:03:11 UTC
In this specific case that would not help, since the ProxyPass /foo declared before the ProxyPassMatch /foo/bar (and the rest of the regex) would send all traffic over the first proxy rule, instead of splitting it over the two, so that defied the purpose of my configuration.
Comment 3 Yann Ylavic 2020-06-19 15:29:36 UTC
Created attachment 37318 [details]

Can you please try this patch?

This looks like the same issue as bug 43513. The fixes are in trunk but were never backported to 2.4.
Comment 4 Cedric Roijakkers 2020-06-29 08:27:49 UTC
I've given your patch a test, and indeed this seems to solve the issue.

I've re-enabled the secret in our Tomcat application, and I can see the secret is now correctly being used in all different connection pools to the different Tomcat instances. The same configuration that was previously generating 403 errors is now working as expected.

Would it be possible to backport this fix to the 2.4 branch for next release? For now, we'll just keep using this patch in our production environment.
Comment 5 Cedric Roijakkers 2020-08-27 11:37:46 UTC
Update from the trenches: we've been running this patch for a few months in production now, and it has solved the problem. Can it be backported to 2.4 and included in a following release?