Virtual Domains and qmail

by Mike Thomas

The program qmail is a secure and reliable replacement for sendmail; it was written by Dan Bernstein at the University of Illinois at Chicago. I was attracted to it for several reasons, the most important being that it runs under Linux.

qmail is substantially more secure than sendmail. The system is partitioned into several modules, minimizing the amount of code which runs as root. The /var/spool/mail directory is gone; incoming mail for a user is stored in the user's home directory, eliminating a nagging security hole. qmail gives you control over which mail you accept. You can selectively allow other hosts to use your system as a relay, blocking out all others.

qmail supports mailing lists with automated subscriptions, and these lists can be configured and maintained entirely by the user. No intervention is required on the part of the system administrator to create a new list.

qmail's performance is stellar. Dan Bernstein cites Red Hat Software as an example. Red Hat was running sendmail 8.7 on a 48MB Pentium and found their daily load of 70,000 messages was beginning to overwhelm the system. They switched to qmail on a 16MB 486/66, and their mail hub is now running fine, even on the less powerful hardware.

The reason I began looking into qmail as an alternative to sendmail is the fact that qmail supported e-mail for virtual domains correctly long before sendmail did. Those of you running several virtual domains on a single Linux host can rejoice. With qmail, the e-mail names you select for your virtual domains come from per-virtual-domain name spaces, rather than a single host-wide name space. This means you can have e-mail names like webmaster@domain1.com and webmaster@domain2.com simultaneously.

Drawbacks

The only problem we have had with qmail is the fact that its outgoing queue uses inode numbers in its database; this means the queue cannot be backed up on one machine and restored to another. When we have a disk failure, we must recreate an empty qmail queue directory rather than restoring from backup.

The fact that qmail is not sendmail implies some complications when installing add-on e-mail packages like majordomo. In general there are patched versions of these packages available for qmail.

qmail Installation and Configuration

The qmail sources are available at ftp://koobera.math.uic.edu/www/qmail.html and a lot of useful information is available at http://www.qmail.org/. Compilation and installation of qmail is straightforward. Those who balked at the sendmail.cf file will be pleasantly surprised at qmail's configuration. Everything is human readable and easy to understand. Some claim that sendmail.cf is human readable, but I would argue that point.

Once you have qmail configured and operational, you can start adding virtual domains. The rest of this article deals with virtual domains under qmail. All file and path names assume the default qmail installation.

Supporting E-mail for a New Virtual Domain

Set up the new virtual domain normally. Many of you will have already done this to support the virtual domain with other services like Apache httpd. Make sure there is an MX record in DNS to point mail for the virtual domain to the host running qmail.

Create a master user ID and home directory for the new domain. The master user is just a user who will control all mail for your virtual domain. I generally create a user ID for each virtual domain which the administrators of that domain can use to upload the content for their web site. qmail can use the same user ID.

Add a line to /var/qmail/control/virtualdomains for the new domain, directing mail for that domain to the user created above. If the domain is abc.com and the user is abc, an appropriate line would be:

abc.com:abc

Add abc.com to /var/qmail/rcpthosts to tell qmail you're willing to accept mail addressed to abc.com. Ensure abc.com does not appear in /var/qmail/control/locals/.

Once mail is directed to a user, it is controlled through a series of .qmail-xxx files in that user's home directory. Create the file ~abc/.qmail-default, to indicate user abc is willing to accept all mail directed to the abc.com domain.

Restart qmail and e-mail for all users at abc.com, i.e., john.smith@abc.com, webmaster@abc.com, etc. will now be received by the local user abc. I suspect this is not precisely what you had in mind, so read on.

Forwarding a Virtual Domain User's Mail

If mail for a new user in a virtual domain is to be forwarded to an existing on-site user or to an off-site user, you don't need to create an account for the new user. You can create a .qmail-xxx file in the virtual domain master user's home directory to forward the mail. The master user is the user we created above, who is currently receiving all mail for the virtual domain. For the address john.smith@abc.com, you create a file ~abc/.qmail-john:smith, containing the address to which John's mail is to be forwarded in this way:

&smith.john@home.boston.ma.us

Note that any periods in the user's Internet name are replaced with colons in the .qmail-xxx file name. The forwarding address which is stored within the .qmail-xxx file does not have periods replaced with colons.

POP3 Mail for a Virtual Domain User

If a user of a virtual domain will be picking up his mail using POP3, you must create an account and an incoming mail directory for him. The POP3 daemon, which comes with qmail, cannot pick up mail from an ordinary mbox formatted file.

# adduser jsmith
# chmod g-w ~jsmith
# chmod o-w ~jsmith
# cd ~jsmith
# maildirmake Maildir
# chown -R jsmith.users Maildir

The chmod commands in the above script ensure that no one can write to jsmith's home directory except jsmith himself. qmail enforces this requirement as a security measure, but it can be relaxed with a compile-time option—see ALIAS_PATERNALISM in the conf-unusual.h file.

Note that under Linux distributions which include the adduser command, like Slackware, you can do a maildirmake in /etc/skel, so new users will automatically get a Maildir.

As in the previous section, you need to create a .qmail-xxx file in the home directory of the virtual domain's master user to forward mail to each individual user. To forward mail for john.smith@abc.com to the local user jsmith we would create a file, ~abc/.qmail-john:smith, containing the line:

&jsmith

To indicate where his incoming mail should be stored, we would create a .qmail file in the home directory for jsmith, containing:

/home/jsmith/Maildir/
This step is required because the qmail POP server expects to find a user's mail in a specially constructed directory (the default name of which is Maildir), and we have to tell qmail to put it there.

Once you start storing incoming mail in a nonstandard place, you have to tell the local mail programs where to find it. The standard Linux mail programs cannot read mail from the Maildir format, so qmail includes several wrapper programs to move any incoming mail into mbox format (qail, qine, qlm, for mail, pine and elm respectively). You can rename the real mail user agents and link these wrappers to the usual names, so your users won't even see a difference. These wrappers need a bit of information to operate correctly. To take care of this, add this type of lines to the /etc/profile file:

export MAILDIR=$HOME/Maildir
export MAIL=$HOME/Mailbox
export MAILTMP=$HOME/Mailbox.tmp

The final thing you have to do is install qmail's POP3 daemon. It is split into three programs, one of which deals with user names and passwords. Those of you with shadow passwords installed will appreciate this modularity. A password checking program, checkpassword, which works with ordinary Linux /etc/passwd files, is available at the same URL as the qmail distribution. The POP3 line in your /etc/inetd.conf will have to be modified. How to do this is described in detail in the FAQ that comes with qmail.

If you feel the above changes are too disruptive, an alternative is to patch your existing POP3 daemon to look for a user's incoming mail in an mbox-formatted file in the user's home directory, rather than a similar file in /var/spool/mail. One such package is available at ftp://summersoft.fay.ar.us/pub/qmail/. The only thing you lose by using a patched POP server rather than the POP server distributed with qmail is the much more reliable Maildir mail storage format.

Forwarding Virtual Domain User Mail Without a Master User

If you want to forward all mail for a new virtual domain, but you have no reason to create a master user ID for that domain (e.g., you're not providing web services), you can do this using the special alias user ID. Instead of adding the line abc.com:abc to /var/qmail/control/virtualdomains, add the line:

abc.com:alias-abc

This designates the alias user as the responsible party for all mail to the abc.com domain. qmail's default installation sets the alias user's home directory to /var/qmail/alias, so control of all e-mail for abc.com is done in this directory.

You can create a file ~alias/.qmail-abc-default to forward all mail for abc.com to a specific user. You can also create a series of files, like ~alias/.qmail-abc-webmaster and ~alias/.qmail-abc-john:smith, to forward mail for specific people at abc.com.

Note that the alias user (or any other user) can control mail for multiple virtual domains. To control abc.com and anotherdomain.org, put the following lines in the /var/qmail/control/virtualdomains file:

abc.com:alias-abc
anotherdomain.org:alias-anotherdomain

You'll need these files in the ~alias directory:

~alias/.qmail-abc-john:smith
~alias/.qmail-abc-nancy:jones
~alias/.qmail-abc-webmaster
~alias/.qmail-anotherdomain-sam:adams
~alias/.qmail-anotherdomain-webmaster
Note that unlike sendmail, you can have two users with the same Internet user name, as long as they're in different virtual domains. In the above example, there's a webmaster@abc.com and a webmaster@anotherdomain.org.
To Handle a Virtual Domain With an /etc/aliases-like File

If you have hundreds of users for a virtual domain, you can avoid the hundreds of .qmail-xxx files with a small script that calls qmail's forward command.

Instead of creating individual .qmail-xxx files in the virtual domain master user's home directory, create a single .qmail-default file containing the following line:

|/usr/local/bin/qmail_db_lookup /home/master/qmail_db

with /home/master/qmail_db modified to reflect the home directory of your virtual domain. You can then create (or adapt from your existing /etc/aliases) the file /home/master/qmail_db, consisting of lines with the virtual domain user, a colon and the forwarding address(es). The special user name “-” indicates where mail should be forwarded for any users not explicitly listed. If the “-” user name is not provided, mail for nonexistent users will be bounced. A sample qmail_db file might look like this:

-:  postmaster@somewhere.com
john.smith:   john.smith@alo.com
carl.jones:   cjones@test.net
karen.quincy: kquincy
all:  john.smith@alo.com cjones@test.net kquincy
Note the forwarding addresses for the “-” user must be an actual address; otherwise, mail to nonexistent addresses in the virtual domain will be accepted, but not delivered to anyone.

Listing 1

A more substantial package for supporting /etc/aliases, qmsmac, is available with qmail. qmsmac supports arbitrarily deep-nested aliases and long aliases but, like sendmail, requires you to rebuild a database of aliases every time your /etc/aliases file is changed.

Conclusions

qmail appears to be a speedy and robust replacement for sendmail. We've had qmail running on our Linux Internet server for many months now without a single glitch. The additional features provided by qmail could be useful to those of you hosting several virtual domains from a single Linux box, and the simpler configuration is an added bonus.

Mike Thomas is an Internet application developer working for a consulting firm in Saskatchewan, Canada. Mike lives in Massachusetts and uses two Linux systems to telecommute 2000 miles to his job and to graduate school at the University of Regina. He can be reached by e-mail at thomas@javanet.com.
Load Disqus comments