How to keep HTTP_HOST of backend server when forwarding web traffic - apache

For forwarding an internal website (i.e. normally not available on internet) to internet I use ProxyPass in Apache.
I have the following setup:
Backend server: An internal laptop or Raspberry PI or virtual machine running an Apache web server on macOS or Linux, accessible in my home wifi. From that machine the following reverse SSH tunnel is run.
Frontend server: A VPS rented running Ubuntu running Apache web server.
When I perform a reverse SSH tunnel to the VPS :
ssh -N -p 22 -R 1081:127.0.0.1:80 root#myVPS
I can access my internal localhost site on https://forward.example.com, just like it behaves internally.
But the glitch is that the $_SERVER["HTTP_HOST"] now returns "localhost:1081" as specified in the ssl.conf.
In PHP I get the remote IP address by $_SERVER['HTTP_X_FORWARDED_FOR'] rather than $_SERVER['REMOTE_ADDR'], so that works fine.
There is also a $_SERVER['HTTP_X_FORWARDED_HOST'] which shows 'forward.example.com'.
Some posts on the internet advised me to specify ProxyPreserveHost on, but enabling that makes things worse: I get a redirect loop.
Is there a way to let Apache force $_SERVER['HTTP_X_FORWARDED_HOST'] ('forward.example.com' in my example) into $_SERVER"HTTP_HOST"]?
Virtual host section in ssl.conf:
<VirtualHost *:443>
SSLEngine on
DocumentRoot /var/www/html/test/
ServerName forward.example.com
LogLevel Debug
ErrorLog ${APACHE_LOG_DIR}/forward-error.log
CustomLog ${APACHE_LOG_DIR}/forward.log combined
SSLCertificateFile /root/.acme.sh/forward.example.com/fullchain.cer
SSLCertificateKeyFile /root/.acme.sh/forward.example.com/forward.example.com.key
# SSLCertificateChainFile /root/.acme.sh/forward.example.com/fullchain.cer
SSLProxyEngine On
ProxyRequests Off
# This causes a redirect loop !!!
# ProxyPreserveHost on
# https://httpd.apache.org/docs/2.4/mod/mod_proxy_wstunnel.html
ProxyPass / http://localhost:1081/
ProxyPassReverse / http://localhost:1081/
RewriteCond %{HTTP:Upgrade} websocket [NC]
RewriteCond %{HTTP:Connection} upgrade [NC]
RewriteRule ^/?(.*) "ws://localhost:1081/$1" [P,L]
</VirtualHost>

Related

Apache redirecting to http after log in in ShinyProxy

I have sucessfully set up an Apache HTTPD web server and ShinyProxy instance so that I can access a set of shiny apps over https (on server runing amazon linux).
When I visit
https://www.example.com
I (as expected) get the login page provided by the web applicaiton (shiny proxy). For now this is set up to use simple authentication.
However when I log in (which is sucessful) the page i am viewing redirects me to http://example.com . I need it to stay on https especially because google auth will not allow you to redirect to an http page.
I think the problem is probably with my apache config file. The relevant part is
<VirtualHost *:80>
ServerName example.com
Redirect / https://www.example.com/
</VirtualHost>
<VirtualHost *:443>
ServerName example.com
DocumentRoot /var/www/
SSLEngine on
SSLProxyEngine On
SSLCertificateFile <path to crt>
SSLCertificateKeyFile <path to key>
SSLCertificateChainFile <path to bundle>
# This block is needed for the interal workings off the app
<Proxy *>
Allow from localhost
</Proxy>
RewriteEngine on
RewriteCond %{HTTP:Upgrade} =websocket
RewriteRule /(.*) ws://localhost:3600/$1 [P,L]
RewriteCond %{HTTP:Upgrade} !=websocket
RewriteRule /(.*) http://localhost:3600/$1 [P,L]
ProxyPass / http://localhost:3600/
ProxyPassReverse / http://localhost:3600/
ProxyRequests Off
ProxyPreserveHost On
</VirtualHost>
Does anyone have any thoughts about how I might fix this?
I have found a solution, and so am providing the answer in case anyone else is still stuck.
If you are still having this problem for me the issue was the home page image that I was including in my ShinyProxy application.yml file was served over http, so Apache was forcing the whole website back to http. Exchanging the default image for one served over https fixed the problem.
Additionally in the latest version of ShinyProxy (2.4+) you need to include in application.yml under the server block the line
forward-headers-strategy: native

Apache not loading document root correctly

Apache shows default page and doesn't load site configuration. OS: Debian 10.
Site is enabled but somehow it doesn't show files from public_html folder. Any help is appreciated.
<VirtualHost *:443>
SSLEngine On
ServerAdmin admin#abc.com
ServerName abc.com
ServerAlias *.abc.com
DocumentRoot /home/xx/public_html
SSLEngine on
SSLCertificateFile /home/xx/ssl.cert
SSLCertificateKeyFile /home/xx/ssl.key
<Directory /home/xx/public_html>
Require all granted
</Directory>
ErrorLog /home/xx/logs/error.log
CustomLog /home/xx/logs/access.log common
LogLevel debug
</VirtualHost>
No enough reputation to comment, so I’m trying with an answer and will clean it up if useful.
No mention of what you’re finding, if anything, in your logs. I assume you’re accessing using HTTPS to be sure your requests are going to port 443, but if per chance you were not I would try that first by specifying the protocol when entering the URL in your browser - otherwise you are probably making your request to the server on port 80 and not 443 where your VirtualHost is listening.
http://example.com ====> browser sends request to port 80, default port for http
https://example.com ====> browser sends request to port 443, default port for https
Is there also a VirtualHost entry for port 80 to redirect those requests to 443? If your browser is trying to load it as http using port 80 first then perhaps that’s why you’re seeing the Apache default page as I believe the server will be attempting to serve from /var/www/html/ for requests on port 80 unless you have already pointed these elsewhere with another VirtualHost, etc.
An example of what I mean that I have in use; either the ReWriteEngine or the Redirect permanent may be redundant, but I can confirm it functions fine for me as follows:
<VirtualHost *:80>
ServerName www.example.com
ServerAlias example.com
Redirect permanent / https://www.example.com
RewriteEngine on
RewriteCond %{SERVER_NAME} =www.example.com [OR]
RewriteCond %{SERVER_NAME} =example.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
For my setup, I preferred that the www subdomain be default and set up DNS intentionally to treat it as such, so the bare domain is ServerAlias in my instance.

How to run socket.io on port 443 where apache is running?

I need to run socket.io on port 443 (where apache run https site with Let's Encrypt)
The idea is to use a apache proxy that will redirect the traffic to the socket.io port.
I found that solution:
<VirtualHost *:443>
ServerName mysite.com
ServerAlias www.mysite.com
SSLEngine on
SSLProxyEngine On
ProxyRequests Off
SSLCertificateFile /etc/apache2/ssl/mysite.com.crt
SSLCertificateKeyFile /etc/apache2/ssl/mysite.com.key
SSLCertificateChainFile /etc/apache2/ssl/ca.cer
DocumentRoot /var/www/errorPages
ErrorDocument 503 /503.html
ProxyPass /503.html !
ProxyPass / http://localhost:3999/
ProxyPassReverse / http://localhost:3999/
RewriteEngine on
RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC]
RewriteCond %{HTTP:CONNECTION} ^Upgrade$ [NC]
RewriteRule .* ws://localhost:3999%{REQUEST_URI} [P]
</VirtualHost>
I run the socket.io on port 3999
HTTPS site works fine, howevever I got http 404 errors.
I guess problem is on rewriteCond.
websocket.js:112 WebSocket connection to
'wss://mysite.com/socket.io/?id=11518237&username=john failed: Error
during WebSocket handshake: Unexpected response code: 404
Try mod_proxy_wstunnel
It provides support for the tunnelling of web socket connections to a backend websockets server. The connection is automatically upgraded to a websocket connection
https://httpd.apache.org/docs/2.4/mod/mod_proxy_wstunnel.html
Use different IP addresses for the different uses. You have <VirtualHost *:443> which tries to use all IP addresses for the single virtual host. I think you want a <VirtualHost pub.lic.ip.addr:443> for Let's Encrypt and a <VirtualHost localhost:443> for the socket.io proxy.

Proxy reversing SSL server in Apache

I am struggling with proxy reversing an SSL server in Apache.
Right now I have many websites under many subdomains in one domain.
For example:
gitlab.mydomain.com
nextcloud.mydomain.com
plex.mydomain.com
All the websites use Letsencrypt certificates so they are HTTPS enabled.
The thing is, that so far no server running at my localhost was HTTPS. For example Plex is running as a standalone HTTP server on my localhost which I simply proxy reverse using Apache and in the internet it is secured with Letsencrypt.
Now I need to proxy reverse an already secured HTTP server. Namely Jenkins - it is running with Letsencrypt on my localhost for various reasons. I should also mention that the certificate used to encrypt it on localhost is the same as the certificate I use in Apache.
So my Jenkins is running on port 8443 and my Apache configuration for Jenkins is the following:
# Just to redirect HTTP to HTTPS
<VirtualHost *:80>
ServerName jenkins.mydomain.com
ServerAlias www.jenkins.mydomain.com
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L]
</VirtualHost>
<Virtualhost *:443>
ServerName jenkins.mydomain.com
ServerAlias https://jenkins.mydomain.com
ProxyRequests Off
ProxyPreserveHost On
AllowEncodedSlashes NoDecode
<Proxy https://localhost:8443/jenkins*>
Order deny,allow
Allow from all
</Proxy>
ProxyPass /jenkins http://localhost:8443/jenkins nocanon
ProxyPassReverse /jenkins http://localhost:8443/jenkins
ProxyPassReverse /jenkins http://jenkins.mydomain.com/jenkins
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-Port "443"
RequestHeader set X-Forwarded-Ssl on
RewriteEngine on
RewriteRule "^/$" "/jenkins/" [R]
SSLEngine on
SSLCertificateFile path/to/fullchain.pem
SSLCertificateKeyFile path/to/privkey.pem
</Virtualhost>
However, with this configuration I get an error 502 (Proxy Error):
The proxy server received an invalid response from an upstream server.
The proxy server could not handle the request GET /jenkins/.
Reason: Error reading from remote server
The 502 you're getting is because Apache isn't receiving a response from http://localhost:8443/jenkins. This is the first issue that needs to be resolved before anything else can work. Ensure that you are able to access Jenkins by utilizing cURL.
For example: curl http://localhost:8443/jenkins if no response then try curl https://localhost:8443/jenkins if no response there, then I'd take a look and see if Jenkins is configured properly.
There are a couple things I did notice that should be updated in your Virtual Host configuration.
ServerAlias https://jenkins.mydomain.com should be ServerAlias www.jenkins.mydomain.com as https:// should not be included in a ServerAlias directive, plus you may want to be able to get to the site using https://www.jenkins.mydomain.com since that's in the non-https directive. You also most likely will want to include a rewrite in your https virtual host that rewrites www.jenkins.mydomain.com to jenkins.mydomain.com.
You probably don't need the second ProxyPassReverse directive.

Port configuration for Bitnami Redmine on domain on win 2008 server

I've installed Redmine using Bitnami Stack on Win Server 2008 R2 64 bit. I already have IIS running over there, and wants to configure subdomain.domain.com to access the redmine which can be accessed on http://127.0.0.1:3000/redmine.
I'm following this guide (http://wiki.bitnami.org/Applications/BitNami_Redmine_Stack) to do the same. But unable to get it working.
After configuring I can't access Redmine altogether, but still access Bitnami page on the http://127.0.0.1:3000/
I want to confirm what port should I configure to listen in below, should I leave it port 80 or configure it to listen on port 3000? Pls advise.
<VirtualHost *:80>
ServerAdmin example.com
ServerName example.com
ServerAlias server
ErrorLog "logs/error.log"
CustomLog "logs/access.log" combined
# this not only blocks access to .svn directories, but makes it
# appear as though they aren't even there, not just that they are
# forbidden
<DirectoryMatch "^/.*/\.svn/">
ErrorDocument 403 /404.html
Order allow,deny
Deny from all
Satisfy All
</DirectoryMatch>
# This passes through remote_user to mongrel
RewriteEngine On
# Redirect non-static requests to cluster
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
RewriteRule ^/(.*)$ balancer://redminecluster%{REQUEST_URI} [P,QSA,L]
</VirtualHost>
#ProxyPass / balancer://redminecluster
#ProxyPassReverse / balancer://redminecluster
<Proxy balancer://redminecluster>
BalancerMember http://127.0.0.1:3001
BalancerMember http://127.0.0.1:3002
</Proxy>
If you already have IIS running in port 80 and serving other applications what you could try is to configure IIS as a reverse proxy for apache.
https://serverfault.com/questions/47537/can-iis-be-configure-to-forward-request-to-another-web-server