Proxy reversing SSL server in Apache - 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.

Related

Apache2 Proxy Pass: Why don't I need to redirect to http*s*:// for SSL?

I just set up a JupyterHub and wanted to proxy a subdomain to the according port (sub.domain.com should point to 127.0.0.1:5000) in this case.
So I used ProxyPass and ProxyPassReverse in my server.conf. To my confusion, when setting up the redirect for the SSL-Site, it did not work when i proxied to https://127.0.0.1:5000 but I had to proxy to http://127.0.0.1:5000. Otherwise my browser would show a 500 - Proxy Error ("Error during SSL Handshake with remote server".)
So: Is the security of my connection in any way compromised when redirecting to http?
And more important: Why does it not work when I redirect to https://?
This is my full .conf:
<VirtualHost XX.XXX.XXX:XX:80>
SuexecUserGroup "#1000" "#1000"
ServerName sub.domain.com
ProxyPass / http://127.0.0.1:5000/
ProxyPassReverse / http://127.0.0.1:5000/
</VirtualHost>
<VirtualHost XX.XXX.XXX:XX:443>
SuexecUserGroup "#1000" "#1000"
ServerName sub.domain.com
SSLEngine On
SSLCertificateFile /etc/letsencrypt/live/sub.domain.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/sub.domain.com/privkey.pem
#Include /etc/letsencrypt/options-ssl-apache.conf
SSLProxyEngine On
#SSLProxyVerify none
ProxyPass / http://127.0.0.1:5000/
ProxyPassReverse / http://127.0.0.1:5000/
</VirtualHost>
I already played around with the ProxyEngine Options, but couldn't make it work.
Since your JupiterHub is running with plain HTTP on 127.0.0.1:5000 you need to use ProxyPass http://127.0.0.1:5000. Using https://... instead would mean that Apache would try to connect to your JupiterHub by HTTPS, which fails because it does not speak HTTPS.
This plain HTTP connection is internal on your machine only though. For external access you have Apache as reverse proxy which based on your configuration provides both HTTP and HTTPS access from outside and proxies it internally to your JupiterHub. Proxying plain HTTP directly to your JupiterHub is likely a bad idea though, instead it should redirect to the HTTPS version of your site with something like this:
<VirtualHost XX.XXX.XXX:XX:80>
ServerName sub.example.com
Redirect permanent / https://subexample.com/
</VirtualHost>
Additionally it is recommended to enforce HTTPS for the site by setting HSTS.
So: Is the security of my connection in any way compromised when redirecting to http?
The traffic can be intercepted if you keep proxying plain HTTP from outside directly to your JupiterHub instead of redirecting it to HTTPS. As for needing HTTPS on localhost itself see Is there a benefit to having SSL connections on localhost?

Reverse proxy in Apache + CentOS for HTTPS requests to PostgREST webserver

I would like to make https requests to my postgREST webserver, which by design doesn't support https. I spend several days now I don't know any further...
My setup
My server is running on CentOS 7.9.2009
I have a website domain that uses Wordpress to serve my content in home/myuser/public_html
I setup PostgREST 7.0.1 on my server which runs on port 3000
I am running Apache/2.4.51 (cPanel)
My Problem
The following request works just fine: http://my-domain.com:3000/my_db_table
I would like to run the same request like: https://my-domain.com/api/my_db_table
My Apache configuration is in an "includes" file, seems to be loaded (as errors occur when I put wrong syntax intentionally in this file) and it looks like this:
<VirtualHost *:443>
DocumentRoot /
ServerName my-domain.com
ServerAlias my-domain
ErrorLog /home/myuser/public_html/api/error.log
CustomLog /home/myuser/public_html/api/access.log combined
SSLEngine on
SSLUseStapling off
SSLCertificateFile /etc/ssl/certs/server.my-domain.com.crt
SSLCertificateKeyFile /etc/ssl/private/server.my-domain.com.key
<Location /api/ >
ProxyPreserveHost On
ProxyPass http://localhost:3000/
ProxyPassReverse http://localhost:3000/
RequestHeader set X-Forwarded-Port "443"
RequestHeader set X-Forwarded-Proto "https"
</Location>
</VirtualHost>
running httpd -t returns Syntax OK
after my changes I run sudo systemctl restart httpd
when I then try to do a request like curl -i https://my-domain.com/api/my_db_table I am redirected to the 404 page of my Wordpress website
the error.log file of my apache config does not include any errors (it included errors for stapling which I resolved by adding the line SSLUseStapling off in my config)
I don't know what to do anymore. And because I don't have any error logs I even don't know how to start debugging it. I would be happy for any hint somebody could provide me.
I have successfully use https with postgrest and the following settings in the virtuahost section but I didn't use the tag.
ProxyHTMLEnable On
ProxyPreserveHost On
SSLEngine on
SSLProxyEngine On
RewriteEngine on
#Proxy for postgrest api
ProxyPassMatch "/api/(.*)" "http://localhost:3000/$1"
ProxyPassReverse "/api/" "http://localhost:3000/"

Reverse proxy an http:// domain to a GitHub Pages URL

I have a URL, http://example.com, that I would like to use to serve content from my GitHub Pages site at https://myusername.github.io/mysite/ via a reverse proxy in Apache. This is both as a temporary workaround until I update example.com's DNS setting to point to GitHub Pages, as well as to teach myself how reverse proxies work.
I have my Apache config like so:
<VirtualHost *:80>
ServerName example.com
SSLEngine On
SSLProxyEngine On
SSLProxyVerify none
SSLProxyCheckPeerCN off
ProxyPass "/" "https://myusername.github.io/mysite/"
</VirtualHost>
When I try to go to "example.com", I get "The proxy server could not handle the request GET /.
Reason: Error during SSL Handshake with remote server."
Is what I'm trying to do possible, and if so, what should I be changing?
I'm using Apache 2.2.
You should probably remove the line:
SSLEngine On
It enables HTTPS on your port 80... but you don't provide an SSL certificate (...and HTTPS uses port 443).
You should also add the line:
ProxyPassReverse "/" "https://myusername.github.io/mysite/"
The following config works perfectly on reverse proxy github pages
<VirtualHost *:80>
ServerName custom-domain
ServerAdmin encycode#gmail.com
ProxyRequests Off
ProxyPreserveHost On
SSLProxyEngine on
SSLProxyVerify none
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
SSLProxyCheckPeerExpire off
RequestHeader set Host "myusername.github.io"
RequestHeader set X-Forwarded-Proto https
RequestHeader set Origin "myusername.github.io"
ProxyPass / https://myusername.github.io/mysite/
ProxyPassReverse / https://myusername.github.io/mysite/
</VirtualHost>
Make sure you replace myusername with your github username, mysite with your github repo name and custom-domain with your custom url
You don't have to implement a reverse proxy yourself, since Github allows you to specify a custom domain
https://docs.github.com/en/pages/configuring-a-custom-domain-for-your-github-
pages-site

MQTT over websocket over Apache SSL

I have an mqtt broker providing unencrypted websocket. I would like to proxy it through an Apache which should encrypt the websocket to the outside.
It is an Apache 2.4 on a Windows machine.
My config is:
<VirtualHost *:80>
ServerName test.someurl.com
RewriteEngine On
RewriteCond %{HTTP:Upgrade} =websocket [NC]
RewriteRule /(.*) ws://localhost:9876/$1 [P,L]
</VirtualHost>
<VirtualHost *:443>
ServerName test.someurl.com
SSLEngine on
SSLCertificateFile "C:/Program Files (x86)/Apache24/conf/ssl/some_certificate.crt"
SSLCertificateKeyFile "C:/Program Files (x86)/Apache24/conf/ssl/some_key.key"
RewriteEngine On
RewriteCond %{HTTP:Upgrade} =websocket [NC]
RewriteRule /(.*) ws://localhost:9876/$1 [P,L]
# Websocket proxy
# wss redirects to working ws protocol
# ProxyPass /wss ws://127.0.0.1:9876 retry=0 keepalive=On
# ProxyPassReverse /wss ws://127.0.0.1:9876 retry=0
</VirtualHost>
I am able to connect through ws / port 80. It works fine. However, I am not able to connect using the wss.
I tried both using a rewriting and also a proxy_pass directives. I tried 100 different solution. However, this one looked most promising as port 80 is working for ws but not for the encrypted part. Any idea? Or I am just blinded by the options O:)
This is an old question, but as I've just got this working:
I have Mosquitto listening on port 8000 (which is firewalled to block any connections other than from localhost)
listener 8000
socket_domain ipv4
allow_anonymous true
protocol websockets
Then setup apache as so:
<VirtualHost *:80>
ProxyPass /ws/ ws://localhost:8000/
ProxyPassReverse /ws/ ws://localhost:8000/
</VirtualHost>
<VirtualHost *:443>
SSLCertificateFile ...
SSLCertificateChainFile ...
SSLCertificateKeyFile ...
ProxyPass /ws/ ws://localhost:8000/
ProxyPassReverse /ws/ ws://localhost:8000/
</VirtualHost>
Finally, the web-application is set to connect like so:
mqtt.connect((window.location.protocol == "https:" ? "wss:" : "ws:") + "//example.org/ws/");
Note that the proxy protocol can be "ws" or "wss" - both seem to work interchangeably. This is the connection between apache and mosquitto, there's no need to encrypt (they're on the same host). The use of the "/ws/" suffix on the path means I can do without mod_rewrite, and simply use mod_proxy.
This approach is the only way I could require authentication when accessed over HTTPS (which is public) but not over HTTP (which is behind the firewall).

Redirecting http to https using ReWrite rule using AWS sends all requests to default webroot instead of using ProxyPass

I have an Apache webserver running on an AWS EC2 instance on port 80.
I have an ELB with a certificate. All requests are intercepted by the ELB and forwarded to my EC2 instance, where my webserver listens for any calls.
When any http traffic comes, I redirect it to https using the rule given below which is present in my http-vhosts.conf file:
<VirtualHost *:80>
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} =http
RewriteRule .* https://%{HTTP:Host}%{REQUEST_URI} [L,R=permanent]
</VirtualHost>
Now in my http-vhosts.conf, I redirect any traffic coming to port 443(which is the default https port) using proxypass as shown below:
<VirtualHost *:443>
ServerName www.mywebsite.com
ProxyRequests Off
ProxyPreserveHost On
<Proxy *>
Order deny,allow
Allow from all
</Proxy>
ProxyPass / http://localhost:8080/
ProxyPassReverse / http://localhost:8080/
</VirtualHost>
Now suppose I make a call to:
http://www.mywebsite.com
It is redirected to:
https://www.mywebsite.com
But this link now serves the index.html file present in my default webroot given in httpd.conf file, instead of redirecting it using ProxyPass.
Can someone please tell me where am I going wrong?
If you are terminating SSL on the ELB, and the communication between ELB and EC2 is only on port 80, then your proxy configuration will never get invoked.
To fix this, you have two options: The first one is to add the proxy config (the settings you have in the *:443 VirtualHost entry) to the *:80 entry.
The second option would be to add configure the ELB to talk to your EC2 instance on 443 as well as 80. You will need to install & configure SSL and an appropriate cert (self-signed will do).