Today I have a tip about running 2 separate physical servers behind the same NAT using the same public IP, and how we can work around this with Apache’s virtual hosts.
Two of my friends just started their own blogs. They are both hosting them on their own servers that are located in their bedrooms. The problem is that they live together and share an internet connection and a public IP address. They both have their own .com domain names, and both domain names resolve to their public IP. This is where the problem lies. Only one server can be set to receive forwarded traffic from the router on port 80. Their solution was to just have one person run on port 8080, but this had problems as well. If someone forgot to add the port number when typing in the URL, then it would go to the wrong person’s blog. After being frustrated for a few days with this solution, they came to me for help. Below I’ll outline the steps that I took to fix this situation.
The solution I came up with for this problem is to use a combination of Apache’s virtual hosts and reverse proxy. I kept the setup they currently had: one machine is running on port 80 (from here on referred to as Server1), the other is running on port 8080. Traffic for both sites is routed to Server1, which has the job of analyzing the host name and deciding if the traffic is meant for itself, or if it should be sent on to Server2. Server1 is configured to use Apache’s virtual hosts. Virtual hosts allow you to serve different content based on which domain name the user types into their address bar. If someone goes to domain1.com, Server1’s configuration knows that this request is meant for itself, and serves the blog content that is hosted locally. However, if someone goes to domain2.com, Server1 knows this is meant for Server2. At this point Apache uses the reverse proxy feature, which means Server1 makes an HTTP request to Server2 on port 8080. Server2 then sends its blog content back to Server1 and then Server1 sends it back to the client who typed in the domain name. Server1 acts as a proxy between the client and Server2.
First we need to make sure that the modules we need are activated. The servers being used in this example are running Apache2 on Ubuntu Feisty Fawn. Different Linux distributions or versions will be different, but the basic ideas codesented here are the same. We need to make sure mod_proxy and mod_proxy_http are loaded.
If the proxy modules are loaded, you’ll see them listed. If nothing is found, this means you need to create symbolic links from the mods-available folder to the mods-enabled folder.
sudo ln -s /etc/apache2/mods-available/proxy.load proxy.load
sudo ln -s /etc/apache2/mods-available/proxy_http.load proxy_http.load
Next we need to edit the apache2.conf configuration file and setup our virtual hosts and reverse proxy settings. In my example configuration file, domain2.com is the domain name of Server2, and 192.168.1.120 is the IP address of Server2. You will need to edit these to suit your environment.
sudo nano /etc/apache2/apache2.conf
Go to the bottom of the config file and find the following lines.
# Include the virtual host configurations:
Insert the following right before the above section.
Allow from all
ProxyPass / http://192.168.1.120:8080/
ProxyPassReverse / http://192.168.1.120:8080/
Now you can restart Apache, and everything should be working.
sudo /etc/init.d/apache2 restart
With the power of Apache’s reverse proxy and virtual hosts, you are able to get around the limitations of hosting multiple physical servers behind a single public IP. The configurations are simple once you understand the principles behind it.
For more reading, you can visit the Apache documention –