Apache LocationMatch matching urls starting with... - apache

I'm using apache to redirect AJAX request to server backend in my AJAX app.
Everything that starts with /service/ should go to service backend:
<LocationMatch "/service">
ProxyPass http://backend:8080/service Keepalive=On
Header set Cache-Control "no-cache, no-store, must-revalidate"
</LocationMatch>
Everything that starts with /auth goes to authentication server:
<LocationMatch "/auth">
ProxyPass http://keycloak:8090/auth/ Keepalive=On
</LocationMatch>
I was happy with my apparently working solution, unless the auth channel was added to backend, and them I've noticed, that requests to /service/auth/info are not consumed by backend, but land in authentication server.
Apparently I have some understanding problem. How should I match URLs that start with given string, and not contain it somewhere in the middle?

Use the caret (^) to indicate the beginning of the string:
<LocationMatch "^/service">

Related

Precedence of Apache <Location> directives?

We are using Apache 2.4.48 and a module that Oracle provides (the "WebLogic Plugin for Apache" - I guess equivalent to ProxyPass/ProxyPassReverse, but more WebLogic specific) to proxy some endpoints that are on WebLogic server. The configuration was setup awhile ago, and I am trying to understand the behavior of the directive.
In the Apache ssl.conf, we have (for example):
<VirtualHost _default_:443 _default_:14101>
<Location />
WLSRequest On
SetHandler weblogic-handler
WebLogicCluster XXX01.foo.com:14101,XXX02.foo.com:14101,XXX03.foo.com:14101,XXX04.foo.com:14101
WLCookieName OAMSESSIONID
SecureProxy ON
WLSSLWallet "/apps/products/apache/2.4.46/instances/apache_oam/conf/certs/wallet"
#RequireSSLHostMatch false
Debug OFF
WLLogFile "/apps/products/apache/2.4.46/instances/apache_oam/logs/oam_location.out"
</Location>
<Location /service/show>
SetHandler default-handler
WLSRequest Off
AuthType None
Require all granted
Header always set Access-Control-Allow-Origin %{ACAO}e env=ACAO
Header always set Access-Control-Allow-Credentials "true"
Header always set Access-Control-Allow-Methods "GET, POST, OPTIONS"
Header always set Access-Control-Allow-Headers "Origin, Content-Type, Accept, Authorization"
</Location>
.
.
.
### Cert Check ###
ScriptAlias /certcheck "/apps/products/apache/instances/apache_oam/cgi-bin/certcheck"
<Location /certcheck>
SSLVerifyClient optional_no_ca
</Location>
### End Cert Check ###
</VirtualHost>
I (probably mistakenly) always thought that, in Apache configuration, the more specific directive would take precedence over the less specific, but, when I test with the above, the
<Location />
appears to cause EVERY request to be proxied to the backend servers, even though the "<Location /certcheck>" is "more specific".
Because of this, the /certcheck, which is supposed to be a local resource, is causing the request to be proxied to the backend, instead of serving from the local resource.
Can someone explain why this is happening?
Also, if what we WANTED was to proxy every request/URI UNLESS we specify the URI in a "<Location /xxxx>", how can we accomplish this?
Thanks,
Jim

How to set Connection properties on an Apache Reverse Proxy

I have to set connection properties on an Apache 2.4 Proxy which only uses the ProxyPassRerverse directive instead of the ProxyPass directive which accepts additional parameters like lim, max, ttl, timeout ...
<Location /postbox-sdd/>
LuaHookTranslateName /etc/httpd/conf.d/hooks.lua map_xxx_to_postbox early
ProxyPassReverse /postbox-sdd/
Session On
SessionEnv On
SessionCookieName cfsession path=/
SessionCookieName2 session path=/;domain=localhost;httponly;secure;version=1;
SessionHeader X-Replace-Session
SetEnv HTTPS on
RequestHeader edit Destination ^http: https: early
Header add referer "https://postbox.xxx"
RequestHeader set referer "https://postbox.xxx"
Header unset CACHE-CONTROL
RequestHeader unset CACHE-CONTROL
</Location>
When i try to use the ProxySet directive (for example ProxySet ttl=20) after the ProxyPassReverse line i end up with an error because i don't know the worker name. Is there a default worker name or is it possible to set one?
ProxySet can not find 'ttl=20' Worker
The reason for doing this is to use a kind of connection pooling to the destination system postbox.xxx. I want to reuse existing connections for new requests instead of permanent open/close for every new request.
Thanks for help

Apache mod_headers modification not passing through on ProxyPass

I have web socket GET requests that are coming to an Apache http sever and are being forwarded to a Apache Tomcat 8.5.x server (represented here as 192.168.1.77:80).
I'm attempting to use mod_headers to set the "upgrade" header value.
Inside my VirtualHost tag, I have the equivalent to the following:
<LocationMatch "/somewhere">
ProxyPass ws://192.168.1.77:80/socket
RequestHeader set Upgrade "myvalue"
</LocationMatch>
This does not work as I would expect it to. The set seems to be applying to Apache http but not Apache Tomcat.
In Apache http, when I add %{Upgrade}i to my LogFormat, I see the "Upgrade" header is set to "myvalue".
However, in the Tomcat logs, if I add *%{Upgrade}i", I see that my RequestHeader set operation did not take effect, and Tomcat records the original value for the "Upgrade" header in the original GET request.
Note: I have already tried adding the "early" argument like so:
<LocationMatch "/somewhere">
ProxyPass ws://192.168.1.77:80
RequestHeader set Upgrade "myvalue" early
</LocationMatch>
Any thoughts as to what is going wrong or what I might be missing?
I'm using mod_proxy_wstunnel, and apparently the upgrade header "WebSocket" is hard-coded in that module.

Secure to secure proxy with Apache 2.4 and separate hosts

I am trying to proxy a SCORM entry point on my LMS to the content on another LMS. The manifest resource href looks like:
https://example.com/training/rest/of/the/content/link?key=value
And in my httpd.conf, I have the following:
SSLProxyEngine on
RewriteRule ^proxy:.* - [F]
ProxyPass /training/ https://theirsite.com/
ProxyPassReverse /training/ https://theirsite.com/
<Location /training/>
SetOutputFilter proxy-html
Header add referer https://theirsite.com/
Header set Accept-Ranges none
RequestHeader set referer https://theirsite.com/
RequestHeader unset Accept-Encoding
ProxyHTMLEnable on
ProxyHTMLExtended on
ProxyHTMLURLMap / ppt/
ProxyHTMLURLMap https://example.com/ ppt/
ProxyHTMLURLMap https://example.com/training/ ppt/
ProxyHTMLURLMap ppt/ https://example.com/training/
</Location>
The problems I am having are this:
The value in my manifest href is correctly hitting the content host (so my proxy values are correct), but are not returning to https://example.com/training/, they are returning to https://example.com, which leads to my next problem.
I am having to map all of the URLs when the body returns to me, which is not a problem, except the client host is actually using a third-party for a particular JS library, and mapping / to a standardized value so I can then re-standardize the entire body back to https://example.com/training/, is breaking that particular link.
I have tried various rewrites and substitutions, but I feel I may be missing a key component on this proxying business :/

Apache Proxy CORS on end server being down or timing out

I am using angularjs on the UI and it cant tell the difference between the server being down or a timeout both respond with something like the following. This is due to cors. When server is down or a request times out apache does not add the cors header.
"{"data":null,"status":0,"config":{"method":"GET","transformRequest":[null],"transformResponse":[null],"url":"https://api.domain.com/containers/60539","headers":{"Accept":"application/json, text/plain, */*"}},"statusText":""}"
How can I make sure that I get the proper 502/503 statuses back from apache on the GET request while having 200 on the options?
Thank you!
Current Config:
<VirtualHost *:443>
ServerName api.domain.com
<IfModule proxy_module>
ProxyRequests Off
SSLProxyEngine On
SSLProxyVerify none
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
ProxyPass / 1.1.1.1
Header set Access-Control-Allow-Origin "*"
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
Header set Pragma "no-cache"
Header set Expires "Wed, 11 Jan 1984 05:00:00 GMT"
</IfModule>
SSLEngine on
SSLCertificateFile "${WILDCARDSSLCRT}"
SSLCertificateKeyFile "${WILDCARDSSLKEY}"
SSLCertificateChainFile "${WILDCARDSSLCHAIN}"
</VirtualHost>
Instead of Header set use Header always set:
Header always set Access-Control-Allow-Origin "*"
https://httpd.apache.org/docs/current/mod/mod_headers.html#Header explains:
The table that corresponds to always is used for locally generated error responses as well as successful responses.
And a couple of guides with some good guidance:
Getting CORS to work with Apache
Setting CORS (cross-origin resource sharing) on Apache with correct response headers allowing everything through