A Guide to Virtual Services
As Internet sites grow in number, some clients want to create a presence without dedicating a machine to the task. In many cases, a client may never get the amount of usage which would justify a dedicated machine. People like florists and civic event organizers may not have any other use for the machine, so the extra hardware would go to waste.
The solution to this problem is to use a single computer to serve multiple clients. If the machine is serving web presences, FTP directories, and e-mail services almost exclusively, a single machine with enough horsepower can easily handle the needs of several clients, especially those with low traffic.
However, this solution has a drawback, with which many are familiar. Although several domains can be easily pointed to a single host, the URLs will produce the same results regardless of which service, and which domain, was requested. For example, if tryme.com and comehere.com both pointed to the same host, http://www.tryme.com/ and http://www.comehere.com/ would produce exactly the same main page—clearly not what these organizations would have in mind.
But this problem has a solution—virtual services. A virtual service is exactly like a standard service (Web, e-mail, or FTP), but it provides different results depending on which target was selected, despite the fact that they all reside on the same machine.
This month, we examine how to set up and use a virtual web service. Next month we cover e-mail and FTP, as well as possible future capabilities. Keep in mind the Perl motto: “There Is More Than One Way To Do It.” As the Internet has grown, several alternatives have sprung up. This document describes only one method, and by the time you read it, there may be others, so look around before you decide on any one path!
Please note, in all the solutions described, I assume that you have at least two domain names registered and operating, and two IP addresses. You should have working routes to both IP addresses, and nslookup from any outside Internet host should return the correct IP address for each domain name. You can consult other references for information on how to do this.
IP aliasing is the key to the virtual services on the level of the operating system. As the intended audience of this article is Linux users and system administrators, I will present only the information pertinent to Linux. Other operating systems may or may not have the capability to do IP aliasing, and you should consult your documentation and other publications for information on them.
Under normal circumstances, only one IP address may be tied to each network device. The virtual services described in this article rely on having a separate IP address for each domain serviced. How, then, does one manage all the traffic with a single machine? IP aliasing makes this possible.
To enable IP aliasing you must first compile your kernel with IP aliasing support. If you don't already have the kernel sources, you shouldn't continue without them. Obtain a fairly recent kernel distribution from a suitable mirror site and unpack the archive, typically into /usr/src/linux. Then go into the directory and re-make the kernel. Be sure to answer “Yes” to the question about whether or not to support IP aliasing.
If you think your kernel might already support IP aliasing, a quick way to check is to verify the existence of /proc/net/alias* files. Once you have the support enabled, you simply need to configure the interfaces in a slightly different manner. Normally this would be done with a combination of ifconfig and route. The following is a common example:
/sbin/ifconfig eth0 10.1.1.10 <other options> /sbin/route add -net 10.1.1.0 gw 10.1.1.10 <other options>
This creates a setup for the eth0 device (which you should replace with whatever device you use for your connectivity) and adds a route for the local network (10.1.1.*) to go through it. (This will also automatically handle the route to the device itself.)
To handle IP aliasing, we simply add a colon and the alias number to which we want to refer. If we had obtained IP addresses 10.1.1.6 and 10.54.21.8 from our service provider, and we wanted them both to talk to our ethernet card connected to our T1 router, we would use:
/sbin/ifconfig eth0:0 10.1.1.6 <other options> /sbin/ifconfig eth0:1 10.41.21.8 <other options> /sbin/route add -net 10.0.0.0 dev eth0:0 /sbin/route add -host 10.41.21.8 dev eth0:1
This will set up two aliases for the Ethernet card, 0 and 1, each with a different IP address. All traffic to either IP address will be seen by any daemon listening to the Ethernet device, and traffic anywhere in the 10.* realm will be routed out through the first device, as a safety catch. You may need to modify these lines to support additional options and, perhaps, a default route. That is all there is to it!
The point of virtual web services is to present different document trees to users requesting pages from the same machine using different domain names. Users receive the main index page and path names associated with a particular domain name, without any knowledge of the other domains which exist on the same machine.
There are actually two solutions to this problem. The newcomer to the scene uses a fairly elegant method where the client, in its request, also specifies the exact target it was looking for. However, this works only for web services, and only with quite recently released clients from Microsoft and Netscape. If you want to support everybody without relying on the client to make your services work, you will need another solution.
The problem is fairly simple once you understand it. You need a modified HTTP daemon listening to requests coming in to a specific IP address, rather than all those directed to the current machine. Then a server is started for each virtual client, with options specifying different configuration files, document source trees, and so on.
Most web servers now support the requirements for virtual services, but some do not. You will need at least version 1.5 if you use the NCSA server. I use the Apache server, version 1.1.1. Other servers designed as “drop-in” replacements for the NCSA daemon should have this capability, but you should check your server documentation for details on configuring this feature.
To date, almost every server has a different configuration. This article covers the Apache daemon only because it is what the author uses, not because the author considers the server to be more or less capable than any other.
Once you have ping working on the two domain names, you can begin to configure your virtual web services. The most important thing is to select an intelligent document tree layout. If you only have a few clients, you might have a single source root with different subdirectories, one per client. Their tree would then be rooted at their respective subdirectory. If you have more clients, you may need a more complex layout. It is important to decide this now because changing it later can become quite messy.
In your server configuration file, you need to set up services for each domain. This is easily done in Apache by enclosing configuration statements within a <VirtualHost> container. For example, the following configuration for 10.1.1.6 (the IP address we obtained for www.tryme.com) would be changed from:
ServerName www.tryme.com ServerAdmin email@example.com DocumentRoot /usr/web/tryme/docs TransferLog /usr/web/tryme/access.log ErrorLog /usr/web/tryme/errors.log
<VirtualHost 10.1.1.6> ServerName www.tryme.com ServerAdmin firstname.lastname@example.org DocumentRoot /usr/web/tryme/docs TransferLog /usr/web/tryme/access.log ErrorLog /usr/web/tryme/errors.log </VirtualHost>This will instruct Apache (and several other similar daemons) to accept requests with those configuration parameters only for those requests directed to 10.1.1.6, in this case www.tryme.com.
Note that this automatically disables server-hosting, and any other targets must be set up as well, or they will not be accessible. Normally, if a machine had several IP addresses, requests directed at any address would be serviced. Including a <VirtualHost> specification prevents this activity. Also note that virtual hosting in Apache can include an optional port number (e.g., <VirtualHost 10.1.1.6:8080>) to provide services for a specific port.
Once you have this configured, start or restart the web daemon, and you should be configured for virtual web services! Next month we examine virtual e-mail and FTP services, and new techniques that provide similar functionality.
Chad Robinson is the Senior Systems Analyst for BRT Technical Services Corporation. He can usually be found behind a monitor and a keyboard, especially if they are hooked to a system running Linux. When he's not programming or administering systems, he is usually spending time with his love, Alison.