Apache proxying subdomain root requests - apache

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.

Related

Bad redirection of Mattermost docker behind reverse proxy apache2

I am trying to install the docker version of Mattermost on my Ubuntu 14.04 with apache2 version 2.4.7.
Here is the configuration of mattermost-ssl.conf:
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerAdmin webmaster#localhost
ServerName www.my.website.fr
ServerAlias website.fr
DocumentRoot /home/www/www-website
[...]
<Proxy *>
Require all granted
</Proxy>
ProxyPreserveHost On
ProxyRequests Off
RewriteEngine on
ProxyPass /mattermost http://localhost:8083
ProxyPassReverse /mattermost http://localhost:8083
RewriteCond %{REQUEST_URI} /api/v[0-9]+/(users/)?websocket [NC,OR]
RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC,OR]
RewriteCond %{HTTP:CONNECTION} ^Upgrade$ [NC]
RewriteRule .* ws://127.0.0.1:8083%{REQUEST_URI} [P,QSA,L]
<Location /home/www/www-soft/mattermost>
Require all granted
ProxyPass http://127.0.0.1:8083/
ProxyPassReverse http://127.0.0.1:8083/
</Location>
[...]
</VirtualHost>
</IfModule>
The website is accessible but nothing appears on the page, because I got such error messages (one example among several others of the same form):
Failed to load resource: the server responded with a status of 404 (Not Found) https://www.my.website.fr/static/main.9e27a2872d73987ea8ec.css
Instead of trying to access the file at:
https://www.my.website.fr/mattermost/static/main.9e27a2872d73987ea8ec.css (which exists, I tested)
(I replaced my website domain by "my.website.fr")
Is there any obvious reason why the apache proxy is not redirecting correctly with the /mattermost prefix ? Am I missing something ?
The dedicated page in Mattermost documentation didn't help me much resolving this (https://docs.mattermost.com/install/config-apache2.html)
From apache documentation: https://httpd.apache.org/docs/2.4/mod/core.html#location
The directive limits the scope of the enclosed directives
by URL.
Which means you need to change:
<Location /home/www/www-soft/mattermost>
Require all granted
ProxyPass http://127.0.0.1:8083/
ProxyPassReverse http://127.0.0.1:8083/
</Location>
to
<Location /mattermost>
Require all granted
ProxyPass http://127.0.0.1:8083/
ProxyPassReverse http://127.0.0.1:8083/
</Location>
Because your document root is set to
DocumentRoot /home/www/www-website
You're also using proxypass to handle requests to the same path
ProxyPass /mattermost http://localhost:8083
ProxyPassReverse /mattermost http://localhost:8083
You need to chose which solution you want to implement: both might not work well together.
At last, you're also using
ProxyPreserveHost On
which I'm not sure it's needed/working as you think: please refer to https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#proxypreservehost to find out if it's realy required in your environment.

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>

apache RewriteRule and proxypass

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.

Why does my page page return blank when using a server name with mod_rewrite?

I am using Apache, mod_rewrite, mod_pagespeed, and mod_proxy.
When accessing my page via IP (10.10.10.12:80), it successfuly rewrites me to 10.10.10.12:81 and then proxies me to an external server (10.10.10.13).
When accessing my page via DNS name (www.example.com), it returns a blank page. Viewing source code shows that my pagespeed configurations applied but my JS doesn't render and nothing shows up.
Below is the relevant code in my configuration:
<VirtualHost *:80>
ProxyRequests off
ServerAdmin xxx#xxx.com
DocumentRoot /var/www/html
RewriteEngine On
RewriteLog "/home/dvanpham/rewrite.log"
RewriteLogLevel 3
#Directs escaped fragment code to an external rendering server
RewriteCond %{QUERY_STRING} ^_escaped_fragment_=(.*) [NC]
RewriteRule .* http://10.10.111.54:82/?page=http://10.10.111.54:81/#!%1 [NE,P,L]
#Directs all other traffic to port 81, which then sends traffic to 2 other servers
RewriteRule ^(.*)$ http://10.10.111.54:81$1 [NE,P]
RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK)
RewriteRule .* - [F]
</VirtualHost>
<VirtualHost *:81>
ProxyRequests off
<Proxy balancer://regscluster>
# BalancerMember http://10.10.112.47:8280
BalancerMember http://10.10.112.48:8280
Order Deny,Allow
Deny from none
Allow from all
ProxySet lbmethod=byrequests
</Proxy>
ProxyPass / balancer://regscluster/
</VirtualHost>
<VirtualHost *:82>
ProxyRequests off
<Proxy balancer://nodecluster>
BalancerMember http://10.10.111.56:8080
BalancerMember http://10.10.111.57:8080
Order Deny,Allow
Deny from none
Allow from all
ProxySet lbmethod=byrequests
</Proxy>
ProxyPass / balancer://nodecluster/
</VirtualHost>
Please let me know if there is any more information I can provide or if you have any insight into this issue!
EDIT: It looks like the issue is specifically related to mod_pagespeed and mod_rewrite when using the domain name.
The issue was that mod_pagespeed was listening for ProxyPass and rewriting the URLs accordingly but did not listen to RewriteRule.
Setting
"ModPagespeedMapOriginDomain http://localhost *.domain.com"
did the trick.

ProxyPass and DocumentRoot on one domain

Let's say I have the following configuration:
<VirtualHost domain.com>
# Server names, admins, logs etc...
ProxyVia On
ProxyRequests Off
<Location "/">
ProxyPass http://localhost:8080/tomcat-webapp/
ProxyPassReverse http://localhost:8080/tomcat-webapp/
Order allow,deny
Allow from all
</Location>
</VirtualHost>
Now, I want the address domain.com/forum to display content of my MyBB forum, which has its files inside the /var/www/forum directory. How to accomplish this?
Actually, I resolved this problem with the following code:
ProxyPass /forum !
ProxyPass / http://localhost:8080/tomcat-webapp/
ProxyPassReverse / http://localhost:8080/tomcat-webapp/
Alias /forum /var/www/forum
What it is recommending is using mod_rewrite to perform the ProxyPass instead of ProxyPass/ProxyPassReverse command.
Try something like:
RewriteRule ^/forum - [L]
RewriteRule ^/(.*) http://localhost:8080/tomcat-webapp/$1 [P,L]
ProxyPassReverse / http://localhost:8080/tomcat-webapp/
I use:
<VirtualHost *:80>
#other irrelevant configs here
ProxyPass /forum http://localhost:8080/myBB
ProxyPassReverse /forum http://localhost:8080/myBB
ProxyPass / http://localhost:8081/tomcat-app
ProxyPassReverse / http://localhost:8081/tomcat-app
</VirtualHost>
You don't have to say "tomcat-app" if your tomcat app is the root app.