I recently decided to migrate my Mac OS X server apache installation (this wordpress site) to CentOS. I was having too many difficulties with it and when I went to change my SSL cert, it was causing SSL failures with clients connecting. The problem I had, is that in addition to apache, I am utilizing the wiki functionality on macOS X. With no easy way to migrate that data I needed a way to still expose the wiki to the internet. I knew Apache could act as a reverse proxy, but all the documentation I found generally dealt with doing a reverse proxy via HTTP, and not HTTPS. After struggling for many hours trying to get it to work, I finally have a stable HTTPS reverse proxy working with Apache on CentOS, with the ability to also reach the Wiki instance running on my OS X server.
First some pre-requisites:
- Working Apache configuration (I went with CentOS)
- Two valid SSL Certs. (One is needed on the proxy server, and one needed on the OS X server. Whilst you probably could use a self signed for the internal server I just went ahead and used LetsEncrypt for both. You could also probably use the same cert if you already have one by copying it to the proxy server, but again LetsEncrypt makes it so easy to acquire certs that I would highly recommend it)
- Valid DNS external records. I currently host my DNS via Google Domains. Using ddclient I am able to update my Google Domains with the dynamic IP assigned by my provider.
- Valid Internal DNS records. This is critical for making sure the SSL handshake is correct. Your proxy server should return an internal address (192.168.x.x or 10.x.x.x) when it does the lookup for the internal server that is being proxied. You could also use /etc/hosts for this
- On your router you should have the appropriate ports forwarded. In my case I had to change the ports 80/443 forwarded to the new CentOS server instead of the macOS X server. You may also need to adjust firewall rules depending on your configuration.
Ok on to the config:
- First I installed CentOS, updated it and and installed Apache (this guide will not cover how to configure all of this as there are plenty of guides out there on how to do this)
- Create a new virtual host for the site you want to proxy. In my case I expose http and https to the internet. However, if someone connects to port 80 then they are automatically rerouted to an https site. On CentOS I create a basic virtual host at /etc/httpd/sites-available/host.example.com.conf (substitute your host information). Inside the file is a basic one that looks like this:
Substitute your host information for the ServerName directive<VirtualHost *:80>
ServerName host.example.com
</VirtualHost>
- Create a symbolic link from /etc/httpd/sites-available/host.example.com.conf to /etc/httpd/sites-enabled/host.example.com.conf
- Next download and run the LetsEncrypt application. When prompted choose the option to force all HTTPS connections. This will update the virtual host with Rewrite Rules to always make the connection https. (This will create a new conf file @ /etc/httpd/sites-enabled/host.example.com-le-ssl.conf In my configuration I moved that file to the sites-available folder and then symbolic linked it to the sites-enabled folder.
- In the newly created host.example.com-le-ssl.conf I added the following directives in the VirtualHost block (Leave the existing information that LetsEncrypt created):
Couple of notes:ErrorLog /var/log/apache/host.example.com/error.log
ProxyRequests Off
SSLProxyEngine On
ProxyPass / https://host.example.com/
ProxyPassReverse / https://host.example.com/
- You will need to create that folder for the error log if it does not exist.
- The trailing / is required after the URL.
- Again substitute your host in the URL strings for ProxyPass and ProxyPassReverse
- Restart the apache service (On CentOS/RHEL/Fedora it’s sudo systemctl restart httpd On Debian/Ubuntu sudo service apache2 restart)
- From a device not connected to your home network (I use my iPhone with wifi turned off) attempt to access your site. If everything went correctly you should now see the proxied site).