
By Charles Fisher
Every serious Webmaster must know how to host multiple
virtual Web sites upon a single server. As Unix remains the most
popular Web server platform, the core of interest in virtual
domains lies within this environment. This article will present
general principles behind virtual hosts upon all versions of
Unix, and the specific configuration commands required to
configure virtual hosting on Red Hat Linux and the Apache
Web
Server.
Questions regarding this article should be directed to the
author at
cfisher@netexpress.net
How You Can Use This Information
There are two basic audiences that will have an interest in
the mechanics behind virtual hosting:
- A commercial Internet Service Provider (ISP), who will provide
Web services for a number of unrelated individuals or
corporations (that is, a server
www.isp.net
hosts
www.company.com
,
www.non-profit-agency.org
,
user.isp.net
, etcetera).
- A corporate Website that
is responsible for hosting several
internal departmental Web servers (that is,
mis.company.com
,
hr.company.com
,
accounting.company.com
,
sales.company.com
, etcetera.).
There will be only minor differences in the methods used to configure
these servers.
The information presented within this document is intended for
Intel-based systems running Red Hat Linux 4.2. Much of the same
information will be applicable, however, to other Unix platforms
where IP Aliasing is available.
Red Hat 4.2 is ready for WWW virtual hosts right out of the
box. Other versions of Linux (or Unix) may require substantial
configuration before the principles outlined below can be
applied. In other words, if you are pressed for time, use Red
Hat.
This article assumes that you have a system that
reliably
runs Red Hat 4.2. It is also assumed that your
network interface cards are properly configured, that your
network routers are
functioning, and that you have added user
accounts to your Unix system for each of your virtual host
administrators.
Over and above a working Linux system, you will require the
following administrative rights:
- An internet domain, obtained from
InterNIC
or the appropriate
issuing authority,
- Full administrative control over your domain and its primary name
server (the DNS server need not necessarily be the same machine
as your virtual host server),
- IP addresses. One is required for each virtual host.
You can get this access from your ISP, service provider, or network
administrator.
If you are unable to obtain these required items, refer to the
Cheaters Never Prosper
section; you might be able
to implement a limited workaround.
Major Challenges
There are many issues behind virtual hosts, and many levels of
technical understanding. These is
sues can be better understood
through the use of an analogy.
It is the job of a secretary to answer a set of office
telephones. There are ten companies headquartered in this
imaginary office, and each telephone should be answered as one of
these different companies.
The secretary, upon receiving this assignment, realizes that
he will have to answer ten different telephones, one for each
company. He immediately suggests to the management that they
hire nine additional secretaries for each of the nine additional
telephones.
The management rejects this proposition as too expensive. At
this point, a (questionably) brilliant young manager goes to each
of the telephones and uses call forwarding to direct all the
incoming calls to a single telephone. This seems to be a good
idea, but the secretary has some problems when he answers the
incoming calls:
- Secretary
- Hello, Acme Incorporated.
- Customer
- Excuse me, I was calling Widget
s Ltd. Do I have the right number?
- Secretary
- Yes, miss, this is also Widgets Ltd. How may I help you?
The problem here is that the secretary never knows which
particular company was contacted. There are many lost calls, and
many complaints to management.
In abject frustration, the secretary calls the telephone
company to see if they can help. A telephone company technician
arrives. She brings a special telephone. This new telephone has
an indicator that flashes a different code for each ringing
telephone line. Finally, the secretary can determine which
company is being called, and has the information to answer the
telephone differently.
This situation is very similar to the principles behind WWW
virtual hosts.
The
Domain Name Service (DNS)
is very similar
to the telephone book that customers use to look up a company
telephone number.
Every internet host has a unique
IP Address
that correspo
nds to a telephone number.
A person who receives a telephone call has no information
about how their telephone number was found (that is, the text in
the telephone book that corresponded to their number).
Usually, every different Web server must have a different IP
address (just as every different company must have a different
telephone number), even if several of these Web servers run on
the same computer.
The major points involved in this process are then:
- Configuring your kernel to answer to multiple IP addresses on a
single network card.
- Setting up the new addresses.
- Setting up names in the DNS tables to point to these addresses.
- Setting up your Web server to distinguish these names, and apply
different document roots to them.
- Setting up Sendmail to handle electronic mail for these new names.
Cheaters Never Prosper
The best method to establish virtual hosts is to configure the
server network card with m
ultiple network addresses. There is,
however, an alternative method that can be used with
JavaScript-enabled browsers.
Let us imagine that the server network card is configured with
a single IP address, and that the names
www.company-a.com
and
www.company-b.com
both resolve to
this same IP address.
Let us further imagine that there is an
index.html
file in the document root of the Web
server, and that this document root must be used to serve
different pages for the different companies.
The JavaScript
location
variable contains the URL
used to access the current page. In addition, if
location
is modified, the browser will immediately
load the new URL contained within the variable.
The JavaScript to exploit this feature for virtual hosts could
be as simple as:
<script language="JavaScript">
<!--
if (location=="http://www.company-b.com/")
location="http://www.company-a.com/comp
any-b/"
//-->
</script>
With this approach, the
browser
, not the server,
makes the decision as to which page to load.
JavaScript will clean up the
location
variable to
some extent, insuring that it contains the
http://
and a trailing slash. However, you will have to experiment to
insure that all possible URL types are covered.
This method is quite handy for Webmasters who do not have full
administrative control of their machine. It is much easier to
apply a change to one file than perform extensive reconfiguration
of the network interfaces.
The greatest drawback is that non-JavaScript-aware browsers
(such as
Lynx
)
will not execute the script and load the new page, nor will
JavaScript-aware browsers (Netscape 2 and later versions,
Internet Explorer 3 and later), if JavaScript has been disabled
by the user.
However, there are some other problems with this appr
oach:
- To some degree, the browser will render the HTML of the main
page before the location is changed to the alternate page. To
minimize this effect, place the above JavaScript near the
beginning of the
<HEAD>
tag.
- The history list will contain the original URL, not the
redirected location.
- If the user presses the browser's
Back
button, the
original URL will be reloaded, which will immediately redirect.
This essentially disables the use of the
Back
button.
The JavaScript
replace()
method offers enhanced
flexibility. After the
replace()
method is
executed, the user cannot navigate to the previous URL by
pressing the
Back
button. Unfortunately,
replace()
is not supported in any of the Netscape
Navigator 2 releases, so version tests must be performed.
Following is an example using
replace()
:
<script language="JavaScript">
<!--
var j
s_ok = false;
if (navigator.appName.substring(0,9) == "Microsoft" &&
parseInt(navigator.appVersion) >= 4 )
js_ok = true;
if (navigator.appName.substring(0.8) == "Netscape" &&
parseInt(navigator.appVersion) >= 3 )
js_ok = true;
if (location=="http://www.company-b.com/")
if (js_ok == true)
replace("http://www.company-a.com/company-b/")
else
location="http://www.company-a.com/company-b/"
//-->
</script>
Compiling the Kernel
If you are running Red Hat Linux 4.2 with the default kernel,
you can skip this section. Red Hat has IP Aliasing compiled as a
module right out of the box.
If you have replaced the standard Red Hat kernel, or if you
are running a different Linux distribution, you might have to
initiate a kernel rebuild after you have ensured that IP Aliasing
has been enabled.
Under Linux, the easiest way to r
econfigure your kernel build
parameters is to issue the command:
cd /usr/src/linux; make menuconfig
as root. You will be presented with a menu of kernel options.
Under the networking options, you will find
IP: aliasing
support
.
You can either configure IP Aliasing as a driver included in
the kernel, or as a loadable module. You should be familiar with
the module utilities
modprobe
and
kerneld
before you attempt to configure module
drivers. If you're not comfortable with loadable modules, just
compile the IP aliasing support right into the kernel.
IP Aliasing
A full discussion of this subject under Linux is available in the
IP-Alias-HOWTO
.
A
general overview
of IP aliasing issues on other platforms is available.
Assuming, however, that a Linux system's
eth0
Ethernet interface has been configured with IP address 1.2.3.3,
the following commands will configure
eth0
to respond
to 1.2.3.4 as well:
/sbin/ifconfig eth0:1 1.2.3.4
/sbin/route add -host 1.2.3.4 dev eth0:1
Obviously, no other machine on the network should be using the IP
address 1.2.3.4. If you are unsure, do not guess; check with your
administrator.
You will probably want to add these commands to your system boot
scripts. Be certain that they execute after your main
ifconfig
command(s).
A sequence can begin with
eth0:1
and continue to
eth0:2
,
eth0:3
,
eth0:4
...
This allows several virtual IP addresses on one network interface --
up to 255.
DNS Magic
Let us say that we have obtained the domain acme.com, and we want
to run www.acme.com as a virtual host on 1.2.3.4.
On the pr
imary DNS server, it is necessary to modify the
/etc/named.boot
file. The following line should be
inserted:
primary acme.com db.acme
There should also be a line near the top of the
/etc/named.boot
file that starts with the word
``directory''. It will be necessary to write a
db.acme
file into the aforementioned directory on
the DNS server.
The
db.acme
file would be of the following form:
@ IN SOA acme.com. root.acme.com. (
199701010 ; Serial
10800 ; Refresh
1800 ; Retry
3600000 ; Expire
86400 ) ; Minimum
IN NS dns1.acme.com.
IN NS dns2.acme.com.
IN MX 10 mail.acme.com.
localh
ost IN A 127.0.0.1
acme.com. IN A 1.2.3.4
www IN A 1.2.3.4
mail IN CNAME acme.com.
ftp IN CNAME acme.com.
This will make both ``acme.com'' and ``www.acme.com'' the host
name of the virtual host.
There are several items above that should be modified for a
real installation. The names of the DNS servers (dns1 and dns2)
should be configured with the actual DNS server names. And,
``acme.com'' should be replaced with the real domain name, and
1.2.3.4 should be the real IP address.
When you have finished adding the new file, run the Red Hat
command
named.restart
to reinitialize your name
server (or send the HUP signal to the
named
process
on other platforms - you can do that with:
kill -HUP `cat /var/run/named.pid`
or
kill
-HUP `cat /etc/named.pid`
(depending upon your version of BIND).
This configuration is for a newly-acquired domain name. If
you are adding a virtual host to a preexisting domain, your
configuration might be quite different.
You will also have to configure your secondary name server(s)
to update from the primary. On each of your secondary DNS
servers, you should place the following line at the end of
/etc/named.boot
:
secondary acme.com 5.6.7.8 db.acme
Replace the
5.6.7.8
above with the IP address of
your primary name server (or the IP address of another secondary,
if you have made the primary unavailable for some reason), then
run
named.restart
.
If you are running your name servers under Red Hat Linux 4.2,
you should have applied the
DNS security patch
. There have been
a number of major
security holes in Red Hat Linux 4.2; make sure your production
systems are up to date.
For information on DNS configuration, you might consult
Tom Yager's article
on the subject
, the
DNS-HOWTO
, the
Linux Network
Administrators' Guide
, or the famous book
DNS and BIND, 2nd.
Edition
(O'Reilly page), which can also be
purchased at a discount from the Amazon Bookstore
.
Apache Configuration
Your Web server must now be configured to serve a different document
root to each different domain name.
You can initiate this behavior with the Red Hat Linux Apache
server by adding the followi
ng lines to the end of
/etc/httpd/conf/httpd.conf
:
<VirtualHost acme.com>
ServerAdmin webmaster@acme.com
DocumentRoot /home/acme/public_html
ServerName acme.com
ErrorLog logs/acme-error_log
TransferLog logs/acme-access_log
RefererLog logs/acme-referer_log
AgentLog logs/acme-agent_log
</VirtualHost>
A number of the above items must be changed for a real
installation. The directory of the document root, the server
name, and the names of the log files should be customized.
Now, restart your Web server. You should be able to load the
new domain and see its relevant default page.
In case of trouble, extra documentation is available at the
Apache Web Site
.
Sendmail Configuration
The Red Hat Web site has very good documentation on this issue
in their
Red Ha
t Sendmail Virtual Hosting Tips
.
In this example, the domain
isp.net
is hosting
acme.com
. We will configure Sendmail to route mail addressed to
any user at
acme.com
to
acme@isp.net
.
The first step is to modify
/etc/sendmail.cw
by appending
the names of all the virtual hosts. In the case of
acme.com
,
the following lines should be appended:
acme.com
www.acme.com
At this point,
/etc/sendmail.cf
must be modified.
As this is a critical system configuration file, you should
have a backup before you make any changes.
Under Ruleset 98 (search for the string
"S98" in the text), append the following line:
R$* < @ $* acme.com. > [tab] $#local $@ $:luser
The only thing that is not specifically mentioned in the Red
Hat documentation is that the
sendmail.cf
file is
extremely sensitive to placement of
tabs and spaces. The rules
below, which are discussed in the Red Hat documentation, must
have a tab in the indicated position:
R$* < @ $* virtual.com. > [tab] $#local $@ $:luser
R$* < @ $* acme.com. > [tab] $(map_virtual $1 $:acme $)
Be certain that you replace the
[tab]
sequence
above with a single tab. Examine the other lines in the section
if the format is not clear.
When you have finished the modifications discussed above, restart
Sendmail with the following commands:
/etc/rc.d/init.d/sendmail.init stop
/etc/rc.d/init.d/sendmail.init start
If you are not running on Red Hat, send the TERM signal to your sendmail
daemon and then restart it with the same options that were used at boot.
You also have the option of simply rebooting, or taking the system into
single user mode and back to multiuser.
You can then ask Sendmail to whom it would route mail
addressed to users in ``acme.com'':
sendmail -bv test@acme.com
sendmail -bv test@www.acme.com
Both tests should report that the mail would be delivered to
user acme at ``isp.net''.
If you are working on another platform, you will have to
become familiar with Sendmail rulesets. You might want to start
with the
Sendmail, 2nd. Edition
(O'Reilly page) which can be
purchased at a discount from the Amazon Bookstore
.
Conclusion
There are many levels of configuration behind any Web site,
regardless if it implements virtual hosts or not. If it does,
then additional levels of complexity are introduced. The
administrator must be familiar with networking primitives,
kernel-build parameters, DNS configuration, WWW-server
configuration, Sendmail rules, and perhaps a little
JavaScript.
Linux is
an ideal platform for many Web server applications,
mostly because of its low cost. The GPL release of Red Hat Linux
is available from
Linux Systems Labs
for the cost of
the distribution media ($1.95). Linux also includes an unlimited-
seat SMB server, FTP, WWW, Telnet, X Window System, NFS, Netware
client/server, and electronic mail servers. If you need an
inexpensive, reliable virtual host solution that offers the
flexibility of Unix, Linux is the way to go.
Well-traveled Unix administrators will undoubtedly implement
similar virtual hosts under the major commercial Unix variants
(Solaris, AIX, HP-UX, Digital Unix), most probably under Netscape
Enterprise Server. The commands change, but the concepts remain
the same.
Author Biography
Charles Fisher is a writer and consultant who specializes in
Linux. He has a
home page
that describes
his personal and p
rofessional interests.
|