LocationMatch not matching like Location (Apache 2.4)

4.2k Views Asked by At

I'm trying to understand what is going on with LocationMatch. Right now I have a Location similar to the following,

<Location "/context">
  RequestHeader set X-Forwarded-Proto https
  RequestHeader set X-Forwarded-Port 443
  ProxyPreserveHost On
  ProxyPass        http://example.com/context retry=0 connectiontimeout=300 timeout=300
  ProxyPassReverse http://example.com/context
</Location>

Next I change only Location to LocationMatch, as below, and that works fine.

<LocationMatch "/context">
  RequestHeader set X-Forwarded-Proto https
  RequestHeader set X-Forwarded-Port 443
  ProxyPreserveHost On
  ProxyPass        http://example.com/context retry=0 connectiontimeout=300 timeout=300
  ProxyPassReverse http://example.com/context
</LocationMatch>

But as soon as I introduce a regular expression this no longer matches correctly. For example, I want to match paths starting with /context,

<LocationMatch "^/context">
  RequestHeader set X-Forwarded-Proto https
  RequestHeader set X-Forwarded-Port 443
  ProxyPreserveHost On
  ProxyPass        http://example.com/context retry=0 connectiontimeout=300 timeout=300
  ProxyPassReverse http://example.com/context
</LocationMatch>

I've been through the documentation multiple times and can't seem to figure out why this regex doesn't match. I've also seen SOQs like Apache LocationMatch matching urls starting with... but this regex doesn't work. I have a single VirtualHost on a vanilla Ubuntu apache2 install with this single LocationMatch. The entire conf file looks like this,

ProxyRequests off

PassEnv HTTPD_SERVER_NAME HTTPD_SERVER_ADMIN SSL_CERTIFICATE_FILE SSL_CERTIFICATE_KEY_FILE

<VirtualHost *:443>
  SSLEngine on
  SSLCertificateFile ${SSL_CERTIFICATE_FILE}
  SSLCertificateKeyFile ${SSL_CERTIFICATE_KEY_FILE}

  Protocols h2 http/1.1
  ServerName ${HTTPD_SERVER_NAME}
  ServerAdmin ${HTTPD_SERVER_ADMIN}
  DocumentRoot /var/www/html

  ErrorLog ${APACHE_LOG_DIR}/error.log
  CustomLog ${APACHE_LOG_DIR}/access.log combined

  SSLCipherSuite EECDH+AESGCM:EDH+AESGCM
  # Requires Apache 2.4.36 & OpenSSL 1.1.1
  SSLProtocol -all +TLSv1.3 +TLSv1.2
  SSLOpenSSLConfCmd Curves X25519:secp521r1:secp384r1:prime256v1
  # Older versions
  # SSLProtocol All -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
  SSLHonorCipherOrder On
  Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
  Header always set X-Frame-Options DENY
  Header always set X-Content-Type-Options nosniff
  # Requires Apache >= 2.4
  SSLCompression off
  # Requires Apache >= 2.4.11
  SSLSessionTickets Off
  SSLProxyEngine on
  SSLProxyVerify none
  SSLProxyCheckPeerCN off
  SSLProxyCheckPeerName off
  SSLProxyCheckPeerExpire off

  <LocationMatch "^/context">
    RequestHeader set X-Forwarded-Proto https
    RequestHeader set X-Forwarded-Port 443
    ProxyPreserveHost On
    ProxyPass        http://example.com/context retry=0 connectiontimeout=300 timeout=300
    ProxyPassReverse http://example.com/context
  </LocationMatch>
</VirtualHost>

My question is, should <LocationMatch "^/context"> match URLs starting with /context? For example, https://mydomain/context? And if this should match, any idea what else could be interfering? I'm on version 2.4.41, but I've seen this behavior since at least 2.4.6. Thanks

1

There are 1 best solutions below

0
On

According to the Apache docs on the ProxyPass directive:

When used inside a <Location> section, the first argument is omitted and the local directory is obtained from the <Location>. The same will occur inside a <LocationMatch> section; however, ProxyPass does not interpret the regexp as such, so it is necessary to use ProxyPassMatch in this situation instead.

If I understand this correctly, it's not that your <Location> regex is invalid, it's just that your <ProxyPass> doesn't interpret it as a regex. So use <ProxyPassMatch> instead.

Also, this SO question led me to some other pages which support the idea that <LocationMatch> and <ProxyPass> are incompatible with each other:

As indicated by this comment and this page, I need to replace ProxyPass [with] ProxyPassMatch when using that inside a LocationMatch block