Review of qmail

qmail is an MTS for UNIX and UNIX-like systems (including FreeBSD, Linux, SunOS, Solaris, HP/UX, AIX, and IRIX, amongst others) that was written by Dan Bernstein to overcome the limitations of and flaws in Sendmail, and to demonstrate by example that there are better ways of doing some things (such as using Maildirs to hold messages instead of the traditional error-prone "mbox" storage format).

qmail has an official web page run by the author, with links to several mailing lists that the author runs, as well as an unofficial web page run by its users and Dave Sill's Life With qmail page.

It supports all of the more recent innovations that one would expect of a modern mail system:

qmail is Modular.

Like MMDF, ZMailer, and Postfix, qmail comprises a suite of programs, each of which does one particular job. It takes this to greater lengths than the other MTSs, however. It follows the UNIX philosophy of combining small single-purpose tools together. Many tasks are performed by small programs executed in chains or as parts of pipelines.

The interfaces between each of the parts is well documented and simple, using pipes, environment variables, and command lines in the usual UNIX manner. This makes qmail flexible, allowing substitutions to be made for individual parts of the system according to one's requirements.

Some of the subsitution options are provided as standard in the package. Substituting qmail-qmqpc for qmail-queue, for example, turns qmail into mini-qmail.

There is a large cottage industry of providing add-ons and substitutes for various parts of qmail, the size of which can be seen by looking at the users' web page. One of the more popular add-ons is checkpassword, which is called by qmail-popup, qmail's POP3 server, to validate user and password information. Changing the authentication scheme used by the POP3 server merely involves replacing that one program.

Even qmail's configuration is modular. qmail doesn't have large monolithic configuration files with complex structures (that have to be read and parsed every time that a new mail process is created, only to have 70% or more of that information remain unused because it is irrelevant to the task at hand). qmail's configuration comprises individual files in /var/qmail/control, each file having a single job. For example: The names of the local domains are listed, one per line, in the file /var/qmail/control/locals.

Many configuration tasks (and FAQ answers!) are, as a result of this philosophy, one-liners involving echo and cat. Configuration can be automated easily using scripts.

qmail is Secure.

qmail was designed to be secure. Not only does the mail system not trust the outside world, but different modules in the mail system don't even trust one another. Different parts of the mail system run under different non-privileged UIDs ("qmaild", "qmailr", "qmailq", &c.). So, for example, even if the SMTP server (qmail-smtpd, which runs as user "qmailr") were compromised, the rest of the system will not be.

qmail has only one setuid binary, qmail-queue, which is setuid to one of the qmail user IDs. It has no binaries that are setuid to the superuser.

qmail has only two programs that run as the superuser, qmail-start which spawns the other dæmon processes under the correct UIDs, and qmail-lspawn which spawns the local delivery program qmail-local under the UID and GID of the user being delivered to. Neither program writes to any files or runs any program as the superuser.

And, of course, qmail doesn't treat the superuser as a "real" user, and the local delivery program never runs as the superuser.

qmail provides a flexible aliasing/forwarding mechanism: .qmail files.

For those who have large amounts of litter left around from a prior Sendmail system, qmail supports /etc/aliases and ~/.forward by dint of using Dan Bernstein's optional supplementary fastforward and dot-forward packages, respectively. However, it is a testament to the power and versatility of qmail's own native aliasing and forwarding mechanism that both are merely plug-ins that run off it.

With qmail, each user controls all local parts that begin with the user's username, allowing each user to have an unlimited number of different local parts. Delivery to each local part is (optionally) controlled by a separate ~/.qmail-* file in the user's home directory. qmail places no limit (apart from the Internet limits on the lengths of mailbox names, of course) on the number of levels of address extensions that can be appended to the username, and allows users to employ "catch-all" ~/.qmail*-default files for controlling all local parts that have all of their address extensions in common except for the final one.

(This mechanism can be used in a wide variety of ways. For example: Users can use it to perform mail sorting amongst multiple mailboxes and mail filtering by destination username, or to create their own "one-shot" throwaway addresses.)

The postmaster only has to learn this one mechanism. This is because system aliases, such as "Postmaster" and "root", are handled by the same mechanism, using .qmail-* files under the control of a pseudo-user named "alias" (i.e. ~alias/.qmail-postmaster and ~alias/.qmail-root).

Full instructions on how to migrate from /etc/aliases and ~/.forward to ~/.qmail files are provided, of course.

qmail provides an optional new mail folder mechanism: Maildirs.

qmail can deliver to /var/spool/mail, simply by changing the default delivery instruction that is passed to qmail-start so that it uses procmail or binmail; but in the standard configuration qmail delivers to an "mbox"-style mailbox in each user's own home directory, ~/Mailbox . This allows mailboxes to be covered by the same disc quotas and directory permissions as home directories. One simply points one's MAIL environment variable at ~/Mailbox. (Making old programs with hard-coded filenames use these mailboxes is a trivial matter of populating /var/spool/mail with appropriate symlinks, of course.)

Strictly speaking, qmail delivers to "mboxrd"-format mailboxes (there being several different "mbox" formats). This format was proposed by Rahul Dhesi on 1995-06-04, and uses a reversible encoding of "From " lines in messages. MUAs can obtain messages in their original form, as they were before they were delivered to the mailbox, even if the original messages contained a "From " line.

As an alternative to the "mbox" format, however, qmail supports "Maildir" style mailboxes. These have the advantage that they don't require any locking, so there's no possibility of mismatched lock protocols between delivery agents and MUAs or between different machines (where one mailbox is NFS mounted by many machines). They also fail gracefully (without corrupting the mailbox) when a mail message to be delivered exceeds the user's disc quota, when a delivery agent dies (or the machine crashes) in the middle of delivering to the mailbox, or when contact is lost with an NFS server.

Patches and directions are available on the the users' web page to show how most of the popular MUAs and mail handling utilities can be converted to use Maildirs. (Recent versions of many MUAs now support Maildirs straight out of the box without any need for modification.)

qmail provides options for resource-limited hosts.

qmail provides several options for use with resource-limited hosts:

qmail provides an upgrade path from Sendmail.

qmail provides a replacement wrapper to be symlinked to /usr/bin/sendmail and full step-by-step instructions on how to upgrade from Sendmail and what the user-visible differences (improvements) will be.

Where and what to download

qmail can be installed from RPMs or from compressed tarballs containing the source. If you choose the latter, for basic mail delivery just download qmail.

The installation instructions are out of date. It is now recommended that the qmail dæmons (qmail-start and qmail-smtpd) be controlled by dæmontools rather than /etc/inittab or /etc/init.d/*, because it provides finer control and does not have race conditions when starting and stopping dæmons. Similarly, for SMTP server support it is recommended that UCSPI-TCP be used instead of inetd, because UCSPI-TCP can enforce inbound concurrency limits in a reasonable manner.


© Copyright 1998–2004 Jonathan de Boyne Pollard. "Moral" rights asserted.
Permission is hereby granted to copy and to distribute this web page in its original, unmodified form as long as its last modification datestamp information is preserved.