LocationMatch not matching like Location (Apache 2.4) - apache

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

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

Related

Configure local proxy for the npm audit with Apache

Based on this one https://github.com/chovyy/npm-audit-proxy
In this case
Nexus OSS v3 manager running behind Apache reverse proxy.
There is need to proxy npm audit as well from https://registry.npmjs.org/-/npm/v1/security/audits/.
So how to configure properly Apache to pass npm adit call to
https://registry.npmjs.org/-/npm/v1/security/audits/
This Apache configuration worked in my case.
<VirtualHost 0.0.0.0:443>
ServerName nexus.corporate.domain
SSLEngine on
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 -TLSv1.2
SSLHonorCipherOrder On
SSLCompression off
SSLCertificateFile /etc/ssl/localcerts/nexus/nexus.pem
SSLCertificateKeyFile /etc/ssl/localcerts/nexus/nexus.key
SSLCertificateChainFile /etc/ssl/localcerts/nexus/Local_Corporate_CA_chain.crt
SSLSessionTickets off
SSLProxyEngine On
ProxyPass /repository/npm-public/-/npm/v1/security/audits https://registry.npmjs.org/-/npm/v1/security/audits
ProxyPassReverse /repository/npm-public/-/npm/v1/security/audits https://registry.npmjs.org/-/npm/v1/security/audits
ProxyPass / http://127.0.0.1:8081/ nocanon
ProxyPassReverse / http://127.0.0.1:8081/
ProxyRequests Off
ProxyPreserveHost Off
AllowEncodedSlashes on
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-Port "443"
<Proxy http://127.0.0.1:8081/*>
Order allow,deny
Allow from all
</Proxy>
ErrorLog /var/log/apache2/nexus_apache_error.log
CustomLog /var/log/apache2/nexus_apache_access.log common
</VirtualHost>
I had error Forbidde 403 but it was caused by ProxyPreserveHost on.
Changed it to ProxyPreserveHost off
/repository/npm-public/ is npm group type repository created in nexus.
https://nexus.corporate.domain/repository/npm-public/

How to disable http to https re-direct in Jenkins?

I currently have Jenkins running behind SSL with http re-driecting to https. For a custom integration which doesn't support SSL yet, I need to disable the http to https re-direct. I am unable to do so by commenting the re-direct in apache conf.
Following is my apache config.
<VirtualHost *:80>
ServerName jenkins-tb.myorg.com
ServerAlias www.jenkins-tb.myorg.com
ProxyRequests Off
ProxyVia On
Redirect permanent / https://jenkins-tb.myorg.com/
# RewriteEngine On
# RewriteCond %{HTTPS} !=on
# RewriteRule ^/?login/(.*) https://%{SERVER_NAME}/login/$1 [R,L]
</Virtualhost>
<VirtualHost *:443>
ServerName jenkins-tb.myorg.com
ServerAlias www.jenkins-tb.myorg.com
SSLEngine On
SSLProxyEngine On
SSLCertificateFile /etc/apache2/ssl/crt/jenkins-asd.myorg.com.crt
SSLCertificateKeyFile /etc/apache2/ssl/key/server_jenkins-asd.myorg.com.key
ProxyRequests Off
ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
# ProxyPassReverse /login http://jenkins-thunderbolt.myorg.com/login
# ProxyPassReverse /login https://jenkins-thunderbolt.myorg.com/login
ProxyPass /sonar http://localhost:9000/sonar
ProxyPassReverse /sonar http://localhost:9000/sonar
RequestHeader set X_FORWARDED_PROTO "https"
RequestHeader set X-Forwarded-Port "443"
SetEnv force-proxy-request-1.0 1
SetEnv proxy-nokeepalive 1
<Proxy http://localhost:8080/*>
Order allow,deny
Allow from all
</Proxy>
ProxyPreserveHost on
# AllowEncodedSlashes NoDecode
</VirtualHost>
How do i re-enable http without disabling https? Basically need to stop re-direction from http to https.
Based on you configuration, replace the <VirtualHost *:80> block with the following. But please note, passwords are now transfered in clear text.
<VirtualHost *:80>
ServerName jenkins-tb.myorg.com
ServerAlias www.jenkins-tb.myorg.com
ProxyRequests Off
ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
ProxyPass /sonar http://localhost:9000/sonar
ProxyPassReverse /sonar http://localhost:9000/sonar
RequestHeader set X_FORWARDED_PROTO "http"
RequestHeader set X-Forwarded-Port "80"
SetEnv force-proxy-request-1.0 1
SetEnv proxy-nokeepalive 1
<Proxy http://localhost:8080/*>
Order allow,deny
Allow from all
</Proxy>
ProxyPreserveHost on
</Virtualhost>
This also includes that /sonar is also available over http.

Configuring Gitlab through Apache with SSL

i want to use GitLab through apache with ssl. I followed this guide but i still get a 503 Service Unavailable message.
I have installed GitLab as described in the instruction from GitLab.
My gitlab.rb configuration looks like the file in the guide:
external_url 'https://domain:4443'
nginx['ssl_certificate'] = "/etc/gitlab/tls/SignedCertificateBundle.crt"
nginx['ssl_certificate_key'] = "/etc/gitlab/tls/SignedCertificate.key"
My virtual host:
<VirtualHost *:443>
ServerName domain
ServerAlias domain
Header always set Strict-Transport-Security "max-age=31536000; includeSubdomains;"
SSLEngine on
SSLCertificateFile /etc/gitlab/tls/SignedCertificate.crt
SSLCertificateKeyFile /etc/gitlab/tls/SignedCertificate.key
SSLCACertificateFile /etc/gitlab/tls/IntermediateCertificate.crt
SSLCipherSuite ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
SSLProxyEngine on
ProxyRequests Off
ProxyPass / https://domain:4443/
ProxyPassReverse / https://domain/
Header edit Location ^http://domain/ https://domain/
RequestHeader set X-Forwarded-Proto "https"
</VirtualHost>
Did i forget something?
i found a solution for my problem (maybe others struggling with the same thing)
My gitlab.rb config file:
external_url 'https://domain'
nginx['listen_address'] = 'localhost'
nginx['listen_port'] = 8888
nginx['listen_https'] = false
And my virtual host:
<VirtualHost *:443>
ServerName domain
ServerAlias domain
ServerAdmin mail
RequestHeader set Host "domain"
RequestHeader add X-Forwarded-Ssl on
RequestHeader set X-Forwarded-Proto "https"
ProxyPreserveHost On
ProxyPass / http://localhost:8888/
ProxyPassReverse / http://localhost:8888/
SSLEngine on
SSLCertificateFile /etc/gitlab/tls/SignedCertificate.crt
SSLCertificateKeyFile /etc/gitlab/tls/SignedCertificate.key
SSLCACertificateFile /etc/gitlab/tls/IntermediateCertificate.crt
SSLCipherSuite ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384
</VirtualHost>
For me GitLab is now working with TLS over apache

Jenkins / Apache Reverse Proxy Error

I am running into an issue that seems to be fairly common based off of my searches, however I've followed all the instructions and/or fixes I've run into but none have worked for me so I'm asking this hoping someone can guide me in the right direction.
I have Jenkins 1.644 installed on OS X 10.11.2 from Homebrew. I followed these instructions on how to install and get it setup inside OS X Server 5.0.15 Websites (I believe this version of OS X server is running Apache 2.4.16.
The problem: When I connect to the manage console in Jenkins, I get the error message "It appears that your reverse proxy set up is broken." and a link to this jenkins doc.
Hitting http://127.0.0.1:8080/manage does not produce the error.
I have added the proxy settings to my virtual host file like so:
ProxyRequests Off
ProxyPreserveHost On
AllowEncodedSlashes NoDecode
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass / http://localhost:8080/ nocanon
ProxyPassReverse / http://localhost:8080/
ProxyPassReverse / http://jenkins.exampledomain.com/
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-Port "443"
When I do the test curl:
curl -iLk -e https://jenkins.exampledomain.com/manage \
https://jenkins.exampledomain.com/administrativeMonitor/hudson.diagnosis.ReverseProxySetupMonitor/test
I get the following results:
HTTP/1.1 302 Found
Date: Fri, 22 Jan 2016 06:30:57 GMT
Server: Jetty(winstone-2.9)
X-Content-Type-Options: nosniff
Location: https://jenkins.exampledomain.com/administrativeMonitor/hudson.diagnosis.ReverseProxySetupMonitor/testForReverseProxySetup/https%3A%2F%2Fjenkins.exampledomain.com%2Fmanage/
Content-Length: 0
MS-Author-Via: DAV
HTTP/1.1 404 Not Found
Date: Fri, 22 Jan 2016 06:30:57 GMT
Server: Apache/2.4.16 (Unix) OpenSSL/0.9.8zg
Content-Length: 325
Content-Type: text/html; charset=iso-8859-1
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL /administrativeMonitor/hudson.diagnosis.ReverseProxySetupMonitor/testForReverseProxySetup/https://jenkins.exampledomain.com/manage/ was not found on this server.</p>
</body></html>
Clearly that address is on this server because I can enter the management console by going to the correct address.
I'm stuck... Apache configuration is not my strong point. I'm looking for any help.
--EDIT More Info--
Adding the full virtual host file from the /Library/Server/Web/Config/apache2/sites directory for further detail.
<VirtualHost 127.0.0.1:34543>
ServerName https://jenkins.exampledomain.com:443
ServerAdmin admin#example.com
DocumentRoot "/Library/Server/Web/Data/Sites/jenkins.exampledomain.com"
DirectoryIndex index.html index.php default.html
CustomLog /var/log/apache2/access_log combinedvhost
ErrorLog /var/log/apache2/error_log
<IfModule mod_ssl.c>
SSLEngine On
SSLCipherSuite "ALL:!aNULL:!ADH:!eNULL:!LOW:!EXP:RC4+RSA:+HIGH:+MEDIUM"
SSLProtocol -ALL +TLSv1
SSLProxyEngine On
SSLCertificateFile "/etc/certificates/machine.local.certCA1FileLocation.pem"
SSLCertificateKeyFile "/etc/certificates/machine.local.certCA2FileLocation.key.pem"
SSLCertificateChainFile "/etc/certificates/machine.local.certCA3FileLocation.chain.pem"
SSLProxyProtocol -ALL +TLSv1
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
</IfModule>
<Directory "/Library/Server/Web/Data/Sites/jenkins.exampledomain.com">
Options All -Indexes -ExecCGI -Includes +MultiViews
AllowOverride None
<IfModule mod_dav.c>
DAV Off
</IfModule>
<IfDefine !WEBSERVICE_ON>
Require all denied
ErrorDocument 403 /customerror/websitesoff403.html
</IfDefine>
</Directory>
ProxyRequests Off
ProxyPreserveHost On
AllowEncodedSlashes NoDecode
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass / http://localhost:8080/ nocanon
ProxyPassReverse / http://localhost:8080/
ProxyPassReverse / http://jenkins.exampledomain.com/
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-Port "443"
</VirtualHost>
--EDIT 2 Another Finding--
I have noticed by attempting to curl to the 'not found' url above that indeed the server is reporting it not found. If I hit https://jenkins.exampledomain.com/manage/ I will get a 404. However, if I leave off the trailing /, it works. https://jenkins.exampledomain.com/manage is successful. Hopefully this means something to someone!
Thanks
I know this is an old question, but I was having the same problem with the error:
HTTP ERROR 404
Problem accessing /administrativeMonitor/hudson.diagnosis.ReverseProxySetupMonitor/testForReverseProxySetup/https%3A%2F%2Fbuild.scopeitconsulting.com%2Fmanage/. Reason:
http://build.domain.com/manage vs. https://build.domain.com/manage
I was able to solve my problem by including the two lines from the author's question:
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-Port "443"
So here is my relevant section from a working ssl.conf configuration in case it helps anybody. I am running Jenkins on port 8080 at the root context with http but reverse proxying it behind Apache enforcing https.
ProxyPass / http://localhost:8080/ nocanon
ProxyPassReverse / http://localhost:8080/
ProxyPassReverse / http://build.domain.com/
ProxyPassReverse / https://build.domain.com/
ProxyRequests Off
ProxyPreserveHost On
AllowEncodedSlashes NoDecode
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-Port "443"
<Proxy http://localhost:8080/>
Order deny,allow
Allow from all
</Proxy>
I hope this helps somebody who like me has spent way too much time trying to find a working configuration to resolve the error.
You need to add below to catalina.properties file. Updating Apache configuration itself is not sufficient.
org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true

ProxyPassMatch with regex

The url i'd like to proxy pass looks something like this, could you please help me figure out the correct regex. I'm a apache newbie.
https://example.com/v1/documents?uri=root/support/bugtracking/attachments/29099/support-log.txt
I'd like root/support/bugtracking/attachments/29099/support-log.txt to be passed to https://other-server/download.xqy?file=root/support/bugtracking/attachments/29099/support-log.txt
Currently i have the below configuration which does not seem to be working:
<VirtualHost *:443>
ServerName example.com
SSLEngine on
SSLProtocol all -SSLv2 -SSLv3
SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:!LOW
SSLCertificateFile /etc/httpd/certs/cert.pem
SSLCertificateKeyFile /etc/httpd/certs/key.pem
SSLCACertificateFile /etc/httpd/certs/ca.cert.pem
ProxyRequests Off
ProxyPreserveHost On
ProxyPass / http://localhost:9050/
ProxyPassReverse / http://localhost:9050/
ProxyPassMatch ^/v1/documents?uri=(root/support/bugtracking/*)$ https://other-server.com/download.xqy?file=$1
RequestHeader set X-Forwarded-Proto "https"
</VirtualHost>
You cannot match against the query string with ProxyPassMatch. You'll have to use mod_rewrite to do it.
# XXX: This creates a "worker" for this backend when
# not using ProxyPass.
<Proxy https://other-server.com/>
# Actual thing being set is redundant
ProxySet keepalive=On
</Proxy>
RewriteEngine ON
RewriteCond %{QUERY_STRING} uri=(root/support/bugtracking/.*)$
RewriteRule ^/v1/documents https://other-server.com/download.xqy?file=%1 [P]