Introduction
I was given a task by my new employer to implement a reverse proxy. This is something in my career I had never done before or was even aware was used on a daily basis to protect back-end web / application servers from being directly accessed by the web at large. Now this took me some time to figure out and I thought to myself why not get the info online to make someone else’s life easier. It also provides a secondary benefit in that allows access to multiple web servers behind a single public IP.
What is a Reverse Proxy
I think it is safe to assume most people working in the IT field have heard of or encountered a forward proxy server before. In case you haven’t however a proxy server is used to serve as an intermediary between clients accessing resources on remote servers. The most common usage for example is for a company to have a proxy server in place to allow all internet web browsing to pass through it. Why is this done though? Multiple reasons really, but the usual reasons are for tracking purposes, content blocking, WAN reduction and caching results.
Reverse Proxies switch this scenario so instead of LAN users accessing public web servers, the reverse proxies are handling internet requests for multiple internal servers which have no public facing connectivity. This again is done for a number of reasons including security, caching, load balancing and compression.
How to Deploy a Reverse Proxy for multiple domains
For this example it is assumed a working knowledge of firewall principals and DNS is understood. This is a fairly complex setup that will more than likely fail if you do not have a solid understanding of protocols and general ipv4 networking principals. The reverse proxy is placed in a secondary DMZ with a lower security level so if the server was ever compromised, only web and DNS access is allowed to pass through the firewall.
The following is a basic diagram of the setup and I will follow up with the reverse proxy configuration:
Packet Flow
A request is made by an internet client for a resource which exists on one of the web servers. The web servers however have no external DNS or NAT rules on the firewall to allow direct access from the internet. All traffic must pass through the reverse proxy server.
A packet arrives at the ASAs outside interface as directed by public DNS for the domain.
The ASA NAT’s the packet to the reverse proxy server address as per the ASA static NAT statement and access list.
The packet traverses the switch on VLAN 5 and hits the reverse proxy server.
The reverse proxy server sees the URL and queries the DNS servers which are on the protected internal network.
It forwards the packet to the required web server.
Reverse Proxy Setup Guide
The following link is the current best guide I found to actually setup the reverse proxy so rather than rewrite what is already a great post, here it is:
It runs through the setup in detail, however the part I had difficulty setting up was the virtual host configuration file on the reverse proxy server. Now before we even get this working the following prerequisites need to be fulfilled:
Internal DNS needs to be functioning and accessible by the reverse proxy so it can resolve the web servers by name. This requires an access list on the firewall to allow queries to the DNS servers. This can be tested easily using nslookup.
The reverse proxy server should be accessible from the web using a static NAT and access list to allow inbound web traffic. At this stage it would display the Apache default web page.
The reverse proxy server should also be able to access the web servers over port 80. This can easily be tested using a telnet session over port 80 from the reverse proxy console and the get command. This also requires an access list on the firewall allowing web traffic to the web servers.
Now once these steps are confirmed as working, the following is an example of the configuration information required on the reverse proxy server:
sudo nano /etc/apache2/sites-available/000-default.conf
<VirtualHost *:80>ProxyPreserveHost On# Servers to proxy the connection, or;# List of application servers:# Usage:# ProxyPass / http://[IP Addr.]:[port]/# ProxyPassReverse / http://[IP Addr.]:[port]/ProxyPass / https://www.ip-life.net:80/ProxyPassReverse / https://www.ip-life.net:80/ServerName www.ip-life.net</VirtualHost><VirtualHost *:80>ProxyPreserveHost On# Servers to proxy the connection, or;# List of application servers:# Usage:# ProxyPass / http://[IP Addr.]:[port]/# ProxyPassReverse / http://[IP Addr.]:[port]/ProxyPass / https://www.ip-life.net:80/ProxyPassReverse / https://www.ip-life.net:80/ServerName ip-life.net</VirtualHost><VirtualHost *:80>ProxyPreserveHost On# Servers to proxy the connection, or;# List of application servers:# Usage:# ProxyPass / http://[IP Addr.]:[port]/# ProxyPassReverse / http://[IP Addr.]:[port]/ProxyPass / http://blog.davidmessenger.co.uk:80/ProxyPassReverse / http://blog.davidmessenger.co.uk:80/ServerName blog.davidmessenger.co.uk</VirtualHost><VirtualHost *:80>ProxyPreserveHost On# Servers to proxy the connection, or;# List of application servers:# Usage:# ProxyPass / http://[IP Addr.]:[port]/# ProxyPassReverse / http://[IP Addr.]:[port]/ProxyPass / http://www.davidmessenger.co.uk:80/ProxyPassReverse / http://www.davidmessenger.co.uk:80/ServerName www.davidmessenger.co.uk</VirtualHost><VirtualHost *:80>ProxyPreserveHost On# Servers to proxy the connection, or;# List of application servers:# Usage:# ProxyPass / http://[IP Addr.]:[port]/# ProxyPassReverse / http://[IP Addr.]:[port]/ProxyPass / http://www.davidmessenger.co.uk:80/ProxyPassReverse / http://www.davidmessenger.co.uk:80/ServerName davidmessenger.co.uk</VirtualHost>
Conclusion
The configuration works by recognising the URL as the HTTP request is made and passing it to the relevant web server. Also note the duplication of entries for the default web servers. This is to make sure all web traffic regardless of whether it was typed with WWW or without WWW is forwarded on to the correct server. As you can see from the configuration I am using this exact setup for this website along with my other sites.
For security reasons I would also recommend using UFW on the web servers and proxy to block all open ports other than the required ports.