Setting up multiple Web servers can be a costly endeavor. However, you can drastically cut costs by setting up several sites on virtual servers with Apache. In doing so, you can host multiple Web sites on a single machine, which will afford you savings in time, hardware, and IP addresses.
In this Daily Drill Down, I'll tell you how to configure Apache for multiple sites using virtual hosts.
Linux and Windows
Because Red Hat is a popular OS to use with Apache, I used Apache 1.3.24 running on Red Hat Linux 7.2 for my explanations in this article. Windows users can now enjoy the same functionality by using the latest Apache 2.0.35. This new release has much better Windows support than the 1.3.x versions and can also serve multiple sites from a single server.
For my examples, I used a very simple Apache installation that I installed with the command shown in Listing A. This command indicates that my Apache software resides in /usr/local/apache and that I have enabled the headers feature, which I will discuss later in this article.
Types of virtual hosts
Apache supports three types of virtual hosts: name-based hosts, IP-based hosts, and the less useful port-based hosts.
An IP-based virtual host looks at the IP address of the requested site and then searches the Apache configuration file to find the location of the content that serves that IP address. This method requires a separate IP address for each host installed on the Apache server. In DNS, each Web site also has its own IP address.
A name-based virtual host uses the headers sent from the requesting client to determine which content to send back to the client. This type of virtual hosting arrangement can be supported with a single IP address. In DNS, all Web sites that reside on the particular server share the same IP address.
A port-based virtual host allows the server to take advantage of port redirection. With this type of virtual host, a server can be running hosts on the same IP address on ports 80, 8080, etc.
The good, the bad, and the ugly
While the ability to host multiple sites on a single server is great, each method of doing so has its drawbacks. IP-based virtual hosting requires additional IP addresses, which can be somewhat difficult to come by for some organizations. Name-based virtual hosting cannot be used with SSL, and some very old browsers don't support it. However, if you're able to accept or work around these potential difficulties, you can see how virtual hosting provides your enterprise with more flexibility and cost savings.
Name-based virtual hosting
First, I'll demonstrate how to set up name-based virtual hosting on a Linux box.
For this example, I will explain how to set up three hosts. For this article, I used www.testnet.com, www.anothertestnet.com, and www.athirdtestnet.com, all of which were set up in DNS at the IP address 172.16.1.72. Setting up the names in DNS is the important first step, because it’s much easier than trying to rely on local hosts files. If you don't control your DNS server and just want to test virtual hosting, set up a DNS such as BIND on your Linux server. If you decide to do this, do it in a lab first so you don’t cause total network confusion by adding unknown DNS servers on the production network.
The content placement
To set up these three hosts on your Apache server, you need to create directories that will hold the content for each site. You also must configure Apache to look at the headers from the client to determine which directory should be used.
The first step is to create the directories. I prefer to put all content under the Apache default document directory. To keep the confusion level low, I like to name the directory after the name of the site that it will be serving, so I created directories on my Web server with these commands:
Inside each of these directories, I placed a file named index.html with just enough content to identify which Web site was visited.
The Apache configuration
Next, you need to modify your Apache configuration file to allow Apache to take advantage of these new content locations automatically. To make this change, modify /usr/local/apache/conf/httpd.conf. First, you must uncomment a line near the end of the file (the entry is on line number 1,215) to tell Apache that name-based virtual hosts will be used. You must also specify the IP address of the server. The original line in the httpd.conf file will look like:
The modified httpd.conf line will look something like this:
Listing B shows the entries that are added to the end of the httpd.conf file with the required virtual host configuration information.
Notice that each VirtualHost entry uses the IP address from the NameVirtualHost directive that was also configured in httpd.conf. This is Apache’s way of matching up interfaces with virtual sites. In each VirtualHost entry, provide Apache with the fully qualified domain name of the Web site, aliases for the Web site, and the location of the content for that site.
Once you've made changes to the virtual server configuration, you must restart Apache. During this process, you can also tell Apache to check your virtual server configuration by adding the -S parameter to the command. You can stop Apache with the command /usr/local/apache/bin/httpd stop, and restart it with the command /usr/local/apache/bin/httpd start –S.
As the Apache server starts, the httpd.conf file is parsed, and your virtual server configuration is analyzed. Listing C shows the parse results of the analysis for the configuration above.
This log indicates that the three sites that I set up are being served by 172.16.1.72. The log also tells me the exact point in the configuration file at which the virtual server entry appears. For example, for www.athirdtestnet.com, the virtual server entry starts on line 14 of httpd.conf.
Line number discrepancy
My virtual server entry is so close to the beginning of the httpd.conf file in this example because I moved these entries to the beginning to make it easier to make changes to them for this article.
Viewing each site
When you browse to each site, you should be served content specific to that site, which indicates that your virtual server configuration works exactly as you planned and that you are serving three distinct Web sites with separate content using a single IP address and server.
IP-based virtual hosts
Like name-based virtual hosts, IP-based virtual hosts also allow you to run multiple Web sites on the same physical hardware. Unlike name-based hosts, however, IP-based virtual hosts generally require that additional IP addresses be assigned to the host. You don't necessarily need multiple physical network adapters, though. Here are the steps you need to take to set up this type of virtual host.
First, you need to assign multiple IP addresses to your Linux server. You can do this by either adding physical network adapters with their own IP addresses or by assigning additional IP addresses to your existing Ethernet adapter. Since I don't have the option of adding physical interfaces to the machine that I used, I opted for the latter.
In many circumstances, using the same physical adapter on a machine is fine and will not create a huge network bottleneck—at least for smaller sites. If you know your site is going to receive a lot of traffic, you should consider multiple Ethernet adapters.
My IP address is 172.16.1.72, so I added an additional IP address, 172.16.1.230, to the same interface with the command shown in Listing D.
Of course, placing this in the system startup would also be prudent so that the subinterface comes up automatically at system startup.
The results of the ifconfig command are shown in Listing E.
Setting up Apache
For the first example in this section, I used only the first two virtual sites, www.testnet.com and www.anothertestnet.com. I used www.testnet.com as the primary domain on this server. As the primary domain, its content will be served by default, unless other directives in the httpd.conf file override the default entry. My secondary site, www.anothertestnet.com, was a virtual site.
You must first make sure that the entry NameVirtualHost from the previous example is commented out of httpd.conf, because we're not working with name-based virtual hosts for this example. Next, remove the VirtualHost entries from the httpd.conf file that we entered in the previous setup and add the entry shown in Listing F.
Since www.testnet.com is my primary site, I need to change the location of the primary server’s document root from /usr/local/apache/htdocs to /usr/local/apache/htdocs/www.testnet.com. Changing the document root of the primary server requires you to add the entry shown in Listing G to the VirtualHost section of the httpd.conf file.
When using IP-based virtual hosts, you need to navigate to them by IP address. For example, when I browse to 172.16.1.72, which I have assigned to the main server, I am greeted with a message informing me that I have reached www.testnet.com, which is exactly what is supposed to happen. When I browse to 172.16.1.230, I am greeted with www.anothertestnet.com, which is also exactly as I intended.
Port-based virtual hosts
In addition to using names and IP addresses, Apache can listen for traffic on other TCP ports and serve up content to requests that come in to that port. Port-based virtual servers are often used in conjunction with load-balancing equipment. The load balancers are configured with the DNS name and the TCP port that serves the content. This TCP port matches the Apache virtual server configuration. The site is often deployed on multiple servers to provide for redundancy and high availability, hence the load-balancing equipment.
Setting up Apache
To set up Apache, you must manipulate the VirtualHost entries in httpd.conf. For this type of setup, Apache must be told which ports it should listen on.
For this example, I set up two Web sites on the same server with the same IP address. The first site, www.testnet.com, was served on port 80, while the second site, www.athirdtestnet.com, was served on port 8080.
Next, I removed the virtual host entries and added the new virtual host entries shown in Listing H.
After making these changes, I restarted Apache and browsed to both http://172.16.1.72 and http://172.16.1.72:8080. My tests showed the correct content for each site.
When deciding which type of virtual server to set up, I always keep the following tips in mind:
- If you only have access to one IP address for your Web server, stick with host-based virtual servers.
- If you have access to multiple IP addresses and can add more Ethernet adapters to your server, use IP-based virtual servers.
- If load balancing is crucial and you are deploying the same site across multiple servers, use port-based virtual servers.