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

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

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/"

Apache24 how to proxy and return 404 for undefined endpoints

I have two virtual hosts running on a single Tomcat server. Lets call them a.com and b.com. Tomcat is configured to support only http on port 8080. (This is simplified, in real life there are multiple Tomcat instances each running a set of virtual hosts.)
I am fronting the host with Apache24 for the purpose of proxying incoming https requests to backend http. This emulates a production environment in which https certificates are handled by a corporate firewall, and requests are forwarded to the backend via http with some additional header fields inserted.
So, I have this proxying for restricted (external) users with two-way authentication:
https://a.com:443 -> http://a.com:8080
I also have this proxying for trusted (internal) users:
http://a.com:80 -> http://a.com:8080
http://b.com:80 -> http://b.com:8080
The problem is that due to some Apache24 default handling, a request to https://b.com/foo gets routed to http://a.com:8080/foo. I want to the https to b.com to return a 404! I know I need some default mappings to kill the b.com request but so far nothing has worked.
The Apache24 details:
File httpd-vhosts.conf:
<VirtualHost a.com:80>
ProxyPreserveHost On
ProxyRequests Off
ServerName a.com
DocumentRoot "c:/tmp"
ProxyPass / http://a.com:8080/
ProxyPassReverse / http://a.com:8080/
Header set Access-Control-Allow-Origin "*"
</VirtualHost>
<VirtualHost b.com:80>
ProxyPreserveHost On
ProxyRequests Off
ServerName b.com
DocumentRoot "c:/tmp"
ProxyPass / http://b.com:8080/
ProxyPassReverse / http://b.com:8080/
Header set Access-Control-Allow-Origin "*"
</VirtualHost>
File httpd-ssl/conf:
<VirtualHost a.com:443>
ProxyPreserveHost On
ProxyRequests Off
SSLEngine On
ServerName a.com
SSLVerifyClient require
SSLVerifyDepth 2
SSLStrictSNIVHostCheck on
#RewriteEngine On
RequestHeader set X-Forwarded-Proto https
RequestHeader setifempty CUSTOMFIELD "expr=CN=%{SSL_CLIENT_S_DN_CN}"
ProxyPass / http://a.com:8080/
ProxyPassReverse / http://a.com:8080/
SSLCertificateFile "c:/certs/a.com.crt"
SSLCertificateKeyFile "c:/certs/a.com.key"
SSLCACertificateFile "c:/certs/ca.crt"
</VirtualHost>
I see in the Apache24 logs lines that start like this when I request https://b.com/foo:
mod_proxy.c(880): [client 127.0.0.1:57956] AH03461: attempting to match URI path '/foo' against prefix '/' for proxying
mod_proxy.c(997): [client 127.0.0.1:57956] AH03464: URI path '/foo' matches proxy handler 'proxy:http://a.com:8080/foo'

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.

apache 2 proxypassreverse appends virtualhost port

I have been trying to setup a reverse proxy using apache 2 mod_proxy and the proxypass & proxypassreverse directives.
I am installing WSO2 Identity Server and wish to access that app using a url such as the following .
hxxp://myserver.domain.com/wso2/
The myserver.domain.com is accessible on the internet
Internally on my network I have set up a virtualhost running in my apache2 configuration with the following parameters:
For various reasons, port 80 is unavailable and the virtualhost must stay as :8080.
Finally, here is my virtual host configuration
<VirtualHost *:8080>
<Location /wso2/>
ProxyPass hxxps://internal.wso2.node:9443/
ProxyPassReverse hxxs://internal.wso2.node:9443/
</Location>
ProxyVia On
ProxyPreserveHost Off
ProxyAddHeaders Off
ProxyRequests Off
SSLProxyEngine On
SSLProxyCheckPeerCN Off
</VirtualHost>
The issue:
I can use my web browser ( Firefox/Chrome) to request the http://myserver.domain.com/wso2/ resource. In my log files I see that the request does hit the apache server and the virtualhost catches the /wso2/ location.
It passes through the proxy and lands on the internal.wso2.node server. however, the product WSO2 IS preforms several redirects which, in the log files I see it requesting the resource with the port appended.
Here is the request flow
hxxp://myserver.domain.com/wso2/ -> hxxps://internal.wso2.node:9443/
REDIRECT x3
hxxps://internal.wso2.node:8080/carbon ->
hxxps://internal.wso2.node:8080/carbon/admin/login.jsp
Back to my web browser
hxxp://myserver.domain.com:8080/wso2/carbon/admin/login.jsp
For some reason the apache response back appends its virtual host to the url I am requesting.
If I remove the port:8080 and request again the full url it will access the resource fine. However any attempt to access using only http://myserver.domain.com/wso2/ will result in redirects and the port appended.
As per covener's suggestion the culprit in this case proved to be the following directives:
UseCanonicalName Off
UseCanonicalPhysicalPort Off
Additionally, the web app I am trying to access makes use of sessions and cookies, therefore we must also proxy those, see the added directives under the ProxyPass & ProxyPassReverse.
Therefore the updated virtualhost configuration file should now look like this
<VirtualHost *:8080>
ServerName: myServer.domain.com
UseCanonicalName Off
UseCanonicalPhysicalPort Off
<Location /wso2/>
ProxyPass hxxps://internal.wso2.node:9443/
ProxyPassReverse hxxs://internal.wso2.node:9443/
ProxyPassReverseCookiePath / /wso2/
ProxyPassReverseCookieDomain internal.wso2.node myserver.domain.com
</Location>
ProxyVia On
ProxyPreserveHost Off
ProxyAddHeaders Off
ProxyRequests Off
SSLProxyEngine On
SSLProxyCheckPeerCN Off
</VirtualHost>