apache RewriteRule and proxypass - apache

I am in the process of setting up a jira server and will use apache to be a proxy to the tomcat service. I have my apache setup 90% completed but can't workout the final configuration. The goal is to have users be able to access the FQDN, the alias or the fully qualified alias but the URL is always rewritten to the DNS alias. e.g user browses to:
http://jira.domian.com rewrite to https://jira
http://nbsrvjira-07v rewrite to https://jira
http://nbsrvjira-07v.diasemi.com rewrite to https://jira
All the above work however the below fail:
https://jira.domian.com rewrite to https://jira
https://nbsrvjira-07v rewrite to https://jira
https://nbsrvjira-07v.diasemi.com rewrite to https://jira
Unless a specific URL is used it will cause issue within the application, the apache configuration is below:
The http to https redirect:
<VirtualHost *:80>
ServerName nbsrvjira-07v.domain.com
ServerAlias jira-test jira-test.domain.com
ErrorLog "/var/log/httpd/nbsrvjira-07v.domain.com_error.log"
ServerSignature Off
CustomLog "/var/log/httpd/nbsrvjira-07v.domain.com_access.log" combined
RewriteEngine On
RewriteRule ^/(.*) https://jira-test/ [noescape,last,redirect=302]
</VirtualHost>
The https to proxy pass:
VirtualHost *:443>
ServerName nbsrvjira-07v.domain.com
ServerAlias jira jira.domain.com
ErrorLog "/var/log/httpd/nbsrvjira-07v.domain.com_error.log"
ServerSignature Off
CustomLog "/var/log/httpd/nbsrvjira-07v.domain.com_access.log" combined
SSLEngine On
SSLCertificateFile "/etc/pki/tls/certs/nbsrvjira-07v.domain.com.cert"
SSLCertificateKeyFile "/etc/pki/tls/private/nbsrvjira-07v.domain.com.key"
RewriteEngine On
ProxyPass / http://localhost:8080/ connectiontimeout=5 timeout=300
ProxyPassReverse / http://localhost:8080/
</VirtualHost>
I have tried various rewrite rules within the https configuration but none seem to work. Can someone help?
Chris

Maybe set up more than one VirtualHost for *:443 where one or more will just redirect to https://jira and only one will act as https://jira and contain the proxying? Just a guess.

Related

ProxyPass worker name (*long url here*) too long

I have a URL www.example.com.
This should point to the page
www.data.city.author/blah/blah/fjfjf/fkkeklf/eied/shudfj
and show the content in
www.data.city.author/blah/blah/fjfjf/fkkeklf/eied/shudfj
but in the address box, it should show www.example.com
My present configuration in vhost.conf for the proxy is:
SSLProxyEngine on
Proxypass "/" www.data.city.author/blah/blah/fjfjf/fkkeklf/eied/shudfj
ProxyPassReverse "/" www.data.city.author/blah/blah/fjfjf/fkkeklf/eied/shudfj
The Problem is that Apache 2.4 has a bug that when using ProxyPass, URL should not be more than 96 characters. So it is truncating the URL to 96 characters and hence the configuration is returning with an error message.
Any other way to solve my case. I tried using apache RewriteRule with [P] flag but it does not work in my case.
EDIT
Below is my present configuration
<VirtualHost *:11080>
ServerAdmin webmaster#dummy-host.example.com
ServerName int.chicagomeningvax.org
ServerAlias www.int.chicagomeningvax.org
DocumentRoot "/app/web-vhosts"
ErrorLog "/app/apache-vhosts/logs/error_log"
CustomLog "/app/apache-vhosts/logs/access_log" combined env=!dontlog
RewriteEngine on
RewriteRule / https://data.cityofchicago.org/Health-Human-Services/Meningitis-Vaccine-Locations-Map-Visualization/n4bi-r8ij [R=302,P]
</VirtualHost>
If your url is too long please use Alias instead, it worked for me.
In your mod_proxy.conf file:
Alias http://dummy:8009 http://yourlongoriginalurl:8009
Proxypass / http://dummy:8009

Redirect specifc HTTPS request to a specific port with apache

I have a problem to redirect some request to an other port. Here's my configuration:
I have a public domain like XXXX.ddns.net
I have a Rapsbian server with apache and files in my /var/www folders are correctly served (angular website)
On the same Raspbian server there is a REST server running on the 3000 port
This is running on HTTPS with SSL(letsencrypt)
I would like that all requests to XXXX.ddns.net/api/* to be redirected to the 3000 port.
I change the .htaccess file and the rewrite rule seems to works on local but I can't make it working from my internet site. API requests achieve with a error 500.
Here is my current .htaccess file:
RewriteEngine On
RewriteRule ^api/(.*) https://localhost:3000/api/$1 [QSA]
# not sure if it should be http or https in the rule but nothing works
#RewriteRule ^api/(.*) http://localhost:3000/api/$1 [QSA]
# If an existing asset or directory is requested go to it as it is
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
# If the requested pattern is file and file doesn't exist, send 404
RewriteCond %{REQUEST_URI} ^(\/[a-z_\-\s0-9\.]+)+\.[a-zA-Z]{2,4}$
RewriteRule ^ - [L,R=404]
Here is my current 000-default-le-ssl.conf file (in /etc/apache2/sites-available):
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerAdmin webmaster#localhost
DocumentRoot /var/www/html
ServerName XXXX.ddns.net
SSLCertificateFile /etc/letsencrypt/live/XXXX.ddns.net/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/XXXX.ddns.net/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
<Location /api>
ProxyPass http://127.0.0.1:3000/api
ProxyPassReverse http://127.0.0.1:3000/api
</Location>
</VirtualHost>
</IfModule>
If someone could help me to achieve it...
Thanks!
Your self-found solution looks strange to me. You switch on the SSLProxyEngine and than disable all security measures. Is the backend API running under HTTPS and HTTP at port 3000 at the same time? This is not possible.
I use this setup (apache as proxy to backend application) pretty often and would suggest the following configuration:
As I did not understand the purpose of the rewrite directives I left them out. The VirtualHost at port 80 always redirects HTTP requests to HTTPS. If this works add permanent to the directive (permanent is cached by some browsers, see comment in VirtualHost *:80).
The VirtualHost for HTTPS serves content from your DocumentRoot at /var/www/html. The Directory directive takes care that only correctly addressed files are served (no lookups possible). The VirtualHost also provides the proxy for the /api on the same server on port 3000.
It should work for apache 2.4 if your letsencrypt configuration is correct (fill-in the XXXX). Both VirtualHost configurations can be written into a single file, usually located in /etc/apache2/sites-available with a symlink to /etc/apache2/sites-enabled. Please remove/rename your .htaccess file and other configurations before testing this configuration. If you need access control through apache this could also be configured directly in the VirtualHost configuration.
<VirtualHost *:80>
ServerName XXXX.ddns.net
# Always https
Redirect / https://XXXX.ddns.net/
# Redirect permanent / https://XXXX.ddns.net/
</VirtualHost>
<VirtualHost *:443>
ServerAdmin webmaster#localhost
ServerName XXXX.ddns.net
# These are your SSL settings; your responsibility
SSLCertificateFile /etc/letsencrypt/live/XXXX.ddns.net/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/XXXX.ddns.net/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
# Your document root; where the JavaScript application lives
DocumentRoot /var/www/html
<Directory /var/www/html/ >
Options -Indexes +FollowSymLinks -MultiViews
AllowOverride None
Order Allow,Deny
Allow From All
</Directory>
# Reverse proxy settings for api
ProxyRequests Off
ProxyPreserveHost On
<Location /api >
ProxyPass http://127.0.0.1:3000/api
ProxyPassReverse http://127.0.0.1:3000/api
</Location>
</VirtualHost>
Thanks for your help. I don't really know how but it works now!
I dont rember exactly what i did, but the last one was to modify my 000-default-le-ssl.conf file like this:
SSLProxyEngine On
SSLProxyVerify none
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
SSLProxyCheckPeerExpire off
<Location /api>
ProxyPass http://127.0.0.1:3000/api/
ProxyPassReverse http://127.0.0.1:3000/api/
ProxyPass https://127.0.0.1:3000/api/
ProxyPassReverse https://127.0.0.1:3000/api/
</Location>

if-then-else condition in apache virtual host

I have an Apache virtual host defined for https ://sb.domain1.com and I need to do a different action depending on the IP address which calls the virtual host. If the call comes from 172.16.xxx.yyy then i need to redirect to http ://sb.domain2.com else i need to redirect to http ://sb.domain1.com.
That is I don't know how to translate the following lines (which come from /etc/http/conf.d/ssl.conf file):
<VirtualHost 192.168.254.68:443>
ServerName sb.domain1.com
SSLProxyEngine on
SSLCertificateKeyFile /etc/httpd/conf/ssl.key/server.key
SSLCertificateFile /etc/httpd/conf/ssl.crt/server.crt
SSLCertificateChainFile /etc/httpd/conf/ssl.crt/STAR.ca-bundle
SSLEngine on
SSLSessionCacheTimeout 600
if IP = 172.16.xxx.yyy
then
Redirect to http ://sb.domain2.com
else
ProxyPass / http ://sb.domain1.com/
ProxyPassReverse / http ://sb.domain1.com/
else
ErrorLog "|/usr/sbin/rotatelogs /var/log/httpd/sb/ssl_error_log 86400"
CustomLog "|/usr/sbin/rotatelogs /var/log/httpd/sb/ssl_access_log 86400" combined
</VirtualHost>
can you suggest me translating the above directives?
Something along the lines of this should work:
RewriteEngine On
RewriteCond %{REMOTE_ADDR} ^172\.16\.
RewriteRule ^/(.*) http://sb.domain2.com/$1 [L,QSA]
and then just
ProxyPass / http://sb.domain1.com/
ProxyPassReverse / http://sb.domain1.com/
After all, if you match the IP, you will be redirected, so no other requests will be made here. Everyone else will then be proxied.

Apache proxying subdomain root requests

Description
Internal Tomcat server that has webapps listening on 8080:
"http://internal:8080/foo-webservice/"
"http://internal:8080/foo-website/"
External facing Apache server is proxying requests for a subdomain:
"http://foo.domain.com/"
Any requests of the root of the subdomain would be proxied to the foo-website webapp on Tomcat.
Any other requests would be proxied to the appropriate path / webapp
Use Case A
Request:
"http://foo.domain.com/index.html"
Proxied to:
"http://internal:8080/foo-website/index.html"
Use Case B
Request:
"http://foo.domain.com/webservice/listener.html?param1=foo&param2=bar"
Proxied to:
"http://internal:8080/foo-webservice/listener.html?param1=foo&param2=bar"
VirtualHost definition
Current virtual host definition which satisfies Use Case B:
<VirtualHost *:80>
ServerName foo.domain.com
ProxyRequests Off
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ErrorLog /var/log/apache2/foo_error.log
LogLevel warn
CustomLog /var/log/apache2/foo_access.log combined
# RewriteRules
# ?
# ProxyPass
ProxyPreserveHost On
ProxyPass / http://internal:8080/
ProxyPassReverse / http://internal:8080/
</VirtualHost>
Attempt 1
# RewriteRules
RewriteEngine On
RewriteRule ^/(.*) http://internal:8080/foo-website/$1 [P]
Use Case A is satisfied
Use Case B fails
Attempt 2
# RewriteRules
RewriteEngine On
RewriteRule ^/$ http://internal:8080/foo-website/$1 [P]
Use Case B is satisfied
Use Case A is not completely satisfied
The index.html in foo-website is loaded, but none of the files in the js, img or css folders.
ProxyPass rules match in order
ProxyPass /webservice/ http://internal:8080/foo-webservice/
ProxyPassReverse /webservice/ http://internal:8080/foo-webservice/
ProxyPass /website/ http://internal:8080/foo-website/
ProxyPassReverse /website/ http://internal:8080/foo-website/
ProxyPass / http://internal:8080/foo-website/
ProxyPassReverse / http://internal:8080/foo-website/
No rewrite rule. Isn't that good enough ?
I think that you need to use the first attempt but include the QSA (query string append) flag in the square brackets at the end of each RewriteRule directive.
I think the issue with Attempt 2 (none of the files in the js, img or css folders being mapped) was a sign that my approach was wrong.
My solution now is to redirect any requests to the root, to the foo-website webapp.
<VirtualHost *:80>
ServerName foo.domain.com
ProxyRequests Off
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ErrorLog /var/log/apache2/foo_error.log
LogLevel warn
CustomLog /var/log/apache2/foo_access.log combined
# RewriteRules
RewriteEngine On
RewriteRule ^/$ /foo-website/ [R]
# ProxyPass
ProxyPreserveHost On
ProxyPass / http://internal:8080/
ProxyPassReverse / http://internal:8080/
</VirtualHost>
This was not what I originally wanted, but I think this is the resolution.

Apache mod-proxy ProxyErrorOverride for specific URL patterns

I am using Apache 2.2 with mod-proxy and I have configured it with several ProxyPass statements to proxy from remote URL to local URL. I need to have custom error documents returned from Apache for these proxied URLs so I set "ProxyErrorOverride On" in my mod-proxy configuration along with some ErrorDocument directives (with local URL path) to return custom error pages for a few HTTP status codes of interest. However, when a status code is returned for which I have NOT created an ErrorDocument directive for, Apache replaces the response body with a default error page instead of leaving the original response body intact. This won't work with the application. So I really have 2 questions:
1) Is it possible to configure Apache to leave the original response body intact for a particular status code if I don't have an ErrorDocument override defined for it?
2) Is it possible to have the ProxyErrorOverride directive only apply to some of the URLs in my ProxyPass statements?
As arober11 pointed out in the comment above:
Afraid the answer is: No and No. If the directive could be limited to
a location, directory, or set of URL's, then there would be something
in the "Context" section, of the man page:
httpd.apache.org/docs/2.2/mod/mod_proxy.html#proxyerroroverride
on the other hand: you can always add it to mod_proxy.c yourself.
For question 2:
Definitely doable. Using internal redirects to either new host or port this is possible. Brief outline using hosts (add noErrorOverrideUrl,doErrorOverrideUrl in DNS or /etc/hosts of apache-machine):
NameVirtualHost *:80
<VirtualHost *:80>
RewriteEngine On
RewriteRule ^(/noErrorOverrideUrl/.*) http://noErrorOverrideUrl$1 [L,P]
RewriteRule ^(/doErrorOverrideUrl/.*) http://doErrorOverrideUrl$1 [L,P]
</VirtualHost>
<VirtualHost *:80>
ServerName noErrorOverrideUrl
ProxyErrorOverride Off
ProxyPass ...
...
</VirtualHost>
<VirtualHost *:80>
ServerName doErrorOverrideUrl
ProxyErrorOverride On
ProxyPass ...
...
</VirtualHost>
Brief outline using ports:
Listen 80
Listen 81
Listen 82
<VirtualHost *:80>
RewriteEngine On
RewriteRule ^(/noErrorOverrideUrl/.*) http://server:81$1 [L,P]
RewriteRule ^(/doErrorOverrideUrl/.*) http://server:82$1 [L,P]
</VirtualHost>
<VirtualHost *:81>
ProxyErrorOverride Off
ProxyPass ...
...
</VirtualHost>
<VirtualHost *:82>
ProxyErrorOverride On
ProxyPass ...
...
</VirtualHost>
You can upgrade apache and use the If sentence avaible on 2.4+
<VirtualHost *:80>
...
<If "%{REQUEST_URI} =~ m#^\/QA(.*)$#">
ProxyErrorOverride Off
</If>
..
</VirtualHost>
Documentation