Friday, July 19, 2024

Virtual domain hosting with Linux

Datamation content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

sendmail tutorial

Internet service providers (ISPs) have discovered an additional, quite lucrative revenue stream to providing connectivity: hosting “virtual domains.” But in fact, hosting a virtual domain is a fairly simple DIY (do it yourself) and usually entails nothing more than configuring a few files.

Here you will learn everything you need to know to set up and host a new virtual domain yourself. You will need:

  • the Linux OS
  • the Sendmail e-mail server
  • BIND (Berkeley Internet Name Domain), including named (pronounced name-dee)
  • the Apache Web server
  • While it is certainly possible to use other server programs such as qmail to accomplish these same goals, I’ll limit my discussion to what I have listed above. Not only do these programs have widespread usage, they’re what I’ve chosen to use for my own server.

    What is a virtual domain?

    You’ve undoubtedly become familiar with the concept of the Internet domain; and are two everyday examples. In fact, you probably typed in a domain name to reach this Web site. But what differentiates a “real” domain with one that’s “virtual”?

    In the old days, each individual “dot-com” needed to have its own server, and all domains were “real.” This limitation was dictated by HTTP 1.0, the first version of the Web protocol. However, possibilities were expanded with the release of the following version, HTTP 1.1. For the first time, a single computer could host multiple (or virtual) domains.

    Hosting multiple domains on one machine is both convenient and economical. Many Web sites have low enough traffic that they don’t require their own dedicated server. Does it not make sense, then, to combine several sites onto one machine? Of course. That’s precisely what virtual hosting allows you to do.

    Without any further ado, here’s what you need to do to host a virtual domain:

      1) Register your domain 2) Configure DNS (named) 3) Configure the Web server (Apache) 4) Configure the e-mail server (Sendmail) 5) Provide your customer access to files

    For the purposes of this article, I’m going to pretend I’ve been hired to host Here’s an in-depth look at what I need to do to make it happen.

    Domain registration

    The first step in hosting a domain, real or virtual, is to register it with InterNIC, or rather Network Solutions, or another company authorized as a registrar (for a list, see here). The cost is $70.00 for the first two years and then $35.00 per each following year.

    In addition to the .com, .net, and .org “top-level” domains, there are individual country-coded domains such as .uk. If you need to use one of these, you’ll find a list of every available country code and their respective contact information at the IANA (Internet Assigned Numbers Authority).

    Regardless of what top-level domain you decide to put your domain under, you’ll need to provide the registrars with the IP addresses of the machines that will be handling DNS lookups for your new domain.

    If the domain you’ll be hosting isn’t new (i.e., if it’s a transfer from another hosting company), you’ll need to submit the transfer request in much the same way as you’d request a new domain. Fortunately, transfers are free.


    DNS, or the Domain Name System, matches domain names (such as with IP addresses ( This process is managed in part by InterNIC, which maintains the gigantic database of .com, .net, and .org domains.

    If you type “whois” (without quotes) on the command line, you’ll see the information that InterNIC maintains on (Being a smart person, you can probably extrapolate that you can get the registry information on any .com, .net, or .org domain by typing “whois “). In addition to the contact info, there’s a small section on the bottom that states:

       Domain servers in listed order:

    This is what we care about! It states that DNS requests for should be directed to (, and, failing that, should be redirected instead to (, the backup. There could be several backups listed, but the minimum is one, as we have here.

    Now, what happens when gets a DNS request? We can presume that ns5 has a copy of “named” running. Named, which is part of the BIND package, is what handles these requests.

    Named is normally started at boot time. You probably have an entry for it in one of your /etc/rc.d files. Mine is in /etc/rc.d/rc.inet2 and looks like this:

       # Start the NAMED/BIND name server.
       if [ -f ${NET}/named ]; then
          echo -n " named"

    The first thing named needs to do on startup is, like many other daemons, read its configuration file. In this case, it’s /etc/named.boot. There’s usually a “directory” line that tells named where it can find the DNS files. It looks like this:

       directory /var/named

    This simply states that all the DNS files will be in the /var/named directory. The directory could be /abc/123; it makes no difference as long as that’s where the files are.

    Then, there will be an entry for each domain that you host. They look like this:


    This tells named that the DNS file for (assuming I hosted that) is called “”, and that we will be the primary host. Again, the file could be called “spaghetti” if you wanted it to be. All that matters is that the actual file name matches up with what you have listed in named.boot.

    Now that we’ve told named where the DNS files are, let’s have a look at the contents of /var/named/

    $ORIGIN com.
    opensourceit   IN    SOA (
                   IN     NS
                   IN     NS
                   IN     MX     0
    www            IN     A
    @              IN     A

    Now, it’d take a book to explain what all this means (and, in fact, several good ones have been written), but you can basically just copy this as a template and exchange your information with what I have here. With that in mind, here’s a brief explanation:

    In a DNS file, all names not ending with a period are appended with your domain name. This appending name (your domain name) is called the “origin”, and presumably, in this case, it’d be “”. We don’t want that, so we override it with:

       $ORIGIN com.

    Now the “opensourceit” on the next line will be read as “”.

    SOA means “Start of Authority” and basically means that the important stuff starts here. Note that “” is the e-mail address of the domain’s administrator; the “@” is replaced with a period as is proper DNS file syntax.

    The “IN NS” lines reflect what we have listed with InterNIC:

       IN     NS
       IN     NS

    “IN NS” stands for INternet Name Server. Then, the “MX” (mail exchange) line tells DNS where to direct e-mail. The 0 means that is the primary mail server; a low number has a higher priority.

       IN     MX     0

    Finally, we change the $ORIGIN variable to be the full domain name, and we say that is the same thing as plain ol’ The IP numbers are the right ones for

       www            IN     A
       @              IN     A

    Many people find DNS confusing but it generally suffices to swap the names you need with those found in a template like I have here.

    Once you’ve added your “primary” line to named.boot and created, you’ll need to restart named by sending it a SIGHUP: kill -HUP . For instance, if “ps -ax” told you that named was process 76:

       76  ?  S    0:16 /usr/sbin/named

    you’d type:

       kill -HUP 76

    Alternately, you could wait until you’re done with everything and then restart your server.

    A cautionary tale: When I first attempted to get named going on my own machines, I had a heck of a time. I wanted to transfer DNS control from my upstream provider but nothing I did seemed to work. No matter how I configured my files (and everyone tells you differently), it never got going correctly. Finally, close to desperation, I realized my fault: I had a bad binary! After a quick upgrade of named, I was up and running.

    Web server

    This part is fairly easy. You’ll just need to edit your httpd.conf, which on my system is /http/conf/httpd.conf. At the end, there’s a place to put virtual domain entries. Here’s what they look like:

    #DocumentRoot /www/docs/
    #ServerAlias domain.tld *.domain.tld
    #ErrorLog logs/
    #TransferLog logs/

    So, in this case, here’s how your entry might look:

    DocumentRoot /home/openuser
    DirectoryIndex index.html
    ServerAlias *
    ErrorLog logs/error_log
    TransferLog logs/access_log

    Starting from the top, we have the IP address of the hosting machine (same as before, with DNS) located within the VirtualHost brackets. This is followed by the admin’s e-mail address, ServerAdmin. Then, there’s the DocumentRoot, the directory where the actual Web pages can be found. I’ve specified this as the /home/openuser directory, but once again, this is entirely arbitrary. Do whatever meets your needs.

    Next, the DirectoryIndex is the first Web page brought up when someone visits the site. I’ve chosen “index.html” (as is standard), but it could be anything. Do be sure that this page actually exists, though, even if it’s blank. Otherwise, you’ll get an error when you restart Apache. Then there’s the ServerName ( and ServerAlias lines. These may take a little explaining.

    ServerName is what Apache is “listening” for. In this case, it’s, so Apache will ignore requests for any other variation, including simply “” (minus the leading “www.”). (You get around this by using ServerAlias.) ServerName is also what’s displayed by the Web client as Web pages are retrieved.

    ServerAlias, on the other hand, allows you to add variations to the ServerName. I’ve got and *, which then allows just about any sort of address. Whether the client requests,,, or anything else, Apache will dish up the pages.

    ErrorLog is, predictably, where errors are recorded, for example, when clients request non-existent pages. TransferLog records all successful Web requests. Note that while you can specify a different file for each virtual host, you probably shouldn’t. Not only will this slow down operations, you’ll run into problems when you start adding a lot of virtual hosts because a process can only have so many files open (usually 64) at any given time. (There is a way around this, though. See’s documentation for details.) My recommendation is to just use the same log and error files for every virtual host. This may not be pretty, but hey, it works.

    Finally, add the line.

    After you’ve made this addition to httpd.conf, restart Apache with a SIGHUP as before – or wait and restart the entire server.

    E-mail server

    Now we get to Sendmail. You may need to download a new version of Sendmail, unpack it, and move to the src directory to compile but once you’ve set it up the first time, future virtual hosts will be a breeze.

    Basically, we want e-mail bound for to go there and not to us (the hosting company). If we simply added a Cw line to our /etc/ file, all mail would come here (to us). Also, we want to have ALL mail going somewhere – even mail addressed to non-existent users. This way, no mail will bounce.

    You create the Makefile by typing “Build” or “makesendmail” (it makes no difference – they’re both links to the same executable) from Sendmail’s src directory. Then, “makesendmail install” installs the binaries. See the README files if you need extra help.

    Read the cf/README file to learn how to create a .mc file in the cf/cf directory. Our file might look like this:

       #  This file contains definitions for
       VERSIONID(`@(#)     1.0 ( 5/1/97')
       FEATURE(`virtusertable', `dbm /etc/virtusertable')dnl

    Note the “virtusertable” definitions. This is what we’re interested in for virtual hosting, and I’ll describe it in detail below. It’s similar to the /etc/aliases file. For now, choose a database format. The default is “dbm” but you may also choose “btree” or “hash.” The “hash” format is used if you compiled Sendmail with NEWDB instead of NDBM (the default).

    Then, there’ll also be the cf/domain/ file:

       #  This file contains the global definitions for
       VERSIONID(`@(#)   1.0 ( 5/1/97')

    The use_cw_file line means that all Cw definitions will be in their own external file (/etc/ instead of in

    Finally, the following three commands are keyed in to generate the file:

       cd sendmail-VERSION/cf/cf
       m4 ../m4/cf.m4 > obj/
       cp obj/ /etc/

    Now we’re ready to roll! Let’s create the virtusertable.

    As I said, the virtusertable is similar to /etc/aliases. It takes the incoming mail for a virtual host and routes it to the correct destination. As the Sendmail people put it, it “maps virtual addresses into real addresses.” Virtual addresses appear on the left, and the actual recipients are on the right, separated by whitespace (spaces or tabs). The file itself is a textfile. You can call it anything; I suggest “virtusertable”!

    Here are some examples:          rmcginty                       support

    Since we’re actually, all mail will come to us by default. But since we compiled virtusertable support into Sendmail, the diversions listed above will take effect. First of all, all mail sent to will now be sent to the local rmcginty ( Bob’s mail will be redirected to Hotmail, and everything else will go to Make sense?

    Finally, you can make the following construction:        

    This will route all mail originally sent to to the same user at

    To compile the virtusertable (and it won’t be useful prior to compilation), type:

       makemap dbm /etc/virtusertable  

    Be sure to replace "dbm" with "btree" or "hash" if necessary (if you did so above). This creates /etc/virtusertable.db, much in the same way that "newaliases" creates /etc/aliases.db. In fact, I recommend creating a script called "newvirtusers" that does this for you. Since the output is virtusertable.db, your original textfile (/etc/virtusertable) is left intact.

    Now, add your new virtual domain to /etc/ Don't forget this step or else all mail to that domain will bounce!

    At this point, you can SIGHUP Sendmail, or restart the server. There won't be any more daemon changes, so if you're planning to restart the server, now's the time to do it.

    FTP access

    The final step is to provide your client access to his or her Web pages. What I do is create a login for that person with "adduser." Ftpd also requires that the user not appear in /etc/ftpusers file, but they must have a recognizable shell (i.e., one that appears in /etc/shells). I don't want my FTP people being able to log in to a shell account with /bin/bash, so I made up a shell for them that I also inserted into /etc/shells. This is a simple script that states that logins from their account are not allowed. If they log in through FTP, they don't see the message. If they try to telnet or dial in, they do.

    Now, when the user FTPs in, they are placed in their home directory. How, then, are they to access their Web pages? Simple! Remember when you created the DocumentRoot line in httpd.conf? It looked like this:

       DocumentRoot /home/openuser

    That stated that all the Web pages would be found in the /home/openuser directory, which is precisely what the FTP user has access to.

    And that's all there is to it!ø

    Related resources

    1. Sendmail home page The official home page of Sendmail, maintained by the Sendmail Consortium. Their section on Virtual Hosting is of special interest. 2. Sendmail, by Bryan Costales and Eric Allman. O'Reilly's classic reference guide. 3. The Apache Software Foundation Home of the Apache Web server and related documentation. Great stuff! 4. DNS and BIND, by Paul Albitz and Cricket Liu. Everything you ever wanted to know about DNS.

    Jay Link is twenty-something and lives in Springfield, IL. He administrates InterLink BBS - an unintentionally nonprofit Internet service provider - in his fleeting spare moments as well as working various odd jobs to pay the rent.

    Subscribe to Data Insider

    Learn the latest news and best practices about data science, big data analytics, artificial intelligence, data security, and more.

    Similar articles

    Get the Free Newsletter!

    Subscribe to Data Insider for top news, trends & analysis

    Latest Articles