Configuring Apache virtual hosts for NAT

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.

Problem

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.

Solution

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.

Configuration

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.

1
2
3
cd /etc/apache2/mods-enabled

ls proxy*

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.

1
2
3
4
5
cd /etc/apache2/mods-enabled

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.

1
sudo nano /etc/apache2/apache2.conf

Go to the bottom of the config file and find the following lines.

1
2
3
# Include the virtual host configurations:

Include /etc/apache2/sites-enabled/

Insert the following right before the above section.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
NameVirtualHost *

        ServerName domain2.com

        DocumentRoot /var/www/

        ProxyRequests Off

          Order deny,allow

          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.

1
sudo /etc/init.d/apache2 restart

Conclusion

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 -

http://httpd.apache.org/docs/2.0/mod/mod_proxy.html

http://httpd.apache.org/docs/2.0/vhosts/

7 thoughts on “Configuring Apache virtual hosts for NAT

  1. Pingback: Smoothwall Express Subdomains

  2. Hi Jeff,

    Awesome write up! I’m having some trouble though. After following the steps I get an error when restarting apache:

    1
    2
    3
    4
    We failed to correctly shutdown apache, so we're now killing all running apache processes. This is almost certainly suboptimal, so please make sure your system is working as you'd expect now!
     ... waiting Syntax error on line 237 of /etc/apache2/apache2.conf:
     directive requires additional arguments
       ...fail!
  3. Nice post. I learn one thing tougher on completely different blogs everyday. It should at all times be stimulating to learn content material from different writers and follow a little one thing from their store. I’d favor to make use of some with the content material on my weblog whether or not you don’t mind. Natually I’ll provide you with a hyperlink in your net blog. Thanks for sharing.

  4. Dear Jeff,

    Thanks a lot, i have found it very helpful……and it gives me an ample time to spend my weekend peacefully

    Thanks!!!!

  5. Wanted to drop a remark and let you know your Rss feed is not functioning today. I tried including it to my Bing reader account and got absolutely nothing.

  6. a better solution would be to setup two virtual host running on same port 80.
    and in configuration you can setup different directories for the two webs :)