Life with qmail

Dave Sill
23 September 2000
http://web.infoave.net/~dsill/lwq.html


Table of Contents


1. Introduction

1.1. Audience

Life with qmail is aimed at everyone interested in running qmail, from the rank amateur (newbie) who just installed Linux on a spare PC all the way up to the experienced system administrator or mail administrator. If you find it lacking or unclear, please let me know. Send comments to lwq@sill.org.

There's a wealth of information available on qmail from a variety of sources. Some is targeted to newbies, some assumes that the reader is more experienced. Life with qmail is an attempt to "glue" this information into a single source, filling in some of the cracks and assuming only that the reader has basic skills such as:

1.2. What is qmail?

qmail is an Internet Mail Transfer Agent (MTA) for UNIX-like operating systems. It's a drop-in replacement for the Sendmail system provided with UNIX operating systems. qmail uses the Simple Mail Transfer Protocol (SMTP) to exchange messages with MTA's on other systems.


Note: The name is "qmail", not "Qmail".

1.3. Why use qmail?

Your operating system included an MTA, probably Sendmail, so if you're reading this document you're probably looking for something better. Some of the advantages of qmail over vendor-provided MTA's include:

1.3.1. Security

qmail was designed for high security. Sendmail has a long history of serious security problems. When Sendmail was written, the Net was a much friendlier place. Everyone knew everyone else, and there was little need to design and code for high security. Today's Internet is a much more hostile environment for network servers. Sendmail's author, Eric Allman, has done a good job of tightening up the program, but nothing short of a redesign can achieve true security.

1.3.2. Performance

qmail parallelizes mail delivery, performing up to 20 deliveries simultaneously, by default.

1.3.3. Reliability

Once qmail accepts a message, it guarantees that it won't be lost. qmail also supports a new mailbox format that works reliably even over NFS without locking.

1.3.4. Simplicity

qmail is smaller than any other equivalently-featured MTA.


Note: The official qmail web page, http://cr.yp.to/qmail.html covers the advantages of qmail more extensively.

1.4. History

qmail was written by Dan Bernstein (DJB), http://cr.yp.to/djb.html, a math professor now at the University of Illinois in Chicago. Dr. Bernstein is also well known for his work in the field of cryptography and for his lawsuit against the U.S. government regarding the publishing of encryption source code. See http://www.news.com/News/Item/0,4,36217,00.html?owv for information regarding the lawsuit.

The first public release of qmail, beta version 0.70, occurred on January, 24, 1996. The first gamma release, 0.90, was on August, 1, 1996.

Version 1.0, the first general release, was announced on February, 20, 1997. The current version, 1.03, was released on June, 15, 1998.

The next release is expected to be an evaluation version of 2.0. Some of things that might appear in version 2 are covered at http://cr.yp.to/qmail/future.html.

1.5. Features

The qmail web page, http://cr.yp.to/qmail.html, has a comprehensive list of qmail's features. This section is based heavily on that list.

1.5.1. Setup

1.5.2. Security

1.5.3. Message construction

1.5.4. SMTP service

1.5.5. Queue management

1.5.6. Bounces

1.5.7. Routing by domain

1.5.8. SMTP delivery

1.5.9. Forwarding and mailing lists

1.5.10. Local delivery

1.5.11. POP3 service

1.6. Related packages

qmail follows the classic UNIX philosophy that each tool should perform a single, well-defined function, and complex functions should be built by connecting a series of simple tools into a "pipeline". The alternative is to build more and more complex tools that re-invent much of the functionality of the simpler tools.

It's not surprising, then, that qmail itself doesn't do everything everyone might want it to do. Here, then, are some of the most popular add-ons written for qmail. Of course, many standard UNIX utilities can also be plugged into qmail.

1.7. Architecture

Appendix D covers qmail's functional and physical structure. In a nutshell, qmail consists of a series of programs (modules) that perform different tasks.

1.8. License

qmail is copyrighted by the author, Dan Bernstein, and is not distributed with a statement of user's rights. In http://cr.yp.to/softwarelaw.html, he outlines what he thinks your rights are under U.S. copyright law. In http://cr.yp.to/qmail/dist.html he grants the right to distribute qmail source code. Binary distributions are allowed under the terms described there and in http://cr.yp.to/qmail/var-qmail.html, although, at this time, nobody is actually attempting this.

The bottom line is that you can use qmail for any purpose, you can redistribute unmodified qmail source distributions and qualifying var-qmail binary distributions, and you can distribute patches to qmail. You can't distribute modified qmail source code or non-var-qmail binary distributions.

1.9. Comparison with other MTA's

A book could be written about this topic, but it would be tedious reading. Here's a quick comparison of qmail with some of the most common UNIX MTA's.

MTA Maturity Security Features Performance Sendmailish Modular
qmail medium high high high addons yes
Sendmail high low high low x no
Postfix low high medium high yes yes
exim medium low high medium yes no

Sendmailish means the MTA behaves like Sendmail in some ways that would make a switch from Sendmail to the alternative MTA more user-transparent, such as the use of .forward files, /etc/aliases, and delivery to /var/spool/mail.

Cameron Laird has a web page comparing these and other free and commercial MTA's at http://starbase.neosoft.com/~claird/comp.mail.misc/MTA_comparison.html.

1.10. Documentation

1.10.1. man pages

The qmail distribution comes with a complete set of man pages. After installation, they're in /var/qmail/man. You'll probably need to add that directory to your MANPATH environment variable.

Shell Command
Bourne (/bin/sh) MANPATH=$MANPATH:/var/qmail/man; export MANPATH
bash, Korn export MANPATH=$MANPATH:/var/qmail/man
C Shell setenv MANPATH $MANPATH:/var/qmail/man

At this point, commands in the format "man name-of-qmail-man-page" should display the appropriate man page.

The man pages are also available on-line in HTML format from:


Note: the qmail man pages are loaded with information, but they require careful reading because they're written in a very dense, technical style. You might want to print off a set and read them through once to familiarize yourself with what's there and where it is. Very little information is repeated on multiple pages, so if you don't know where something is covered, it can be hard to find it.

1.10.2. Docs

The qmail distribution includes a series of documents that are installed under /var/qmail/doc. They include:

These docs are also available on-line from:

1.10.3. FAQs

There are two official FAQ (Frequently Asked Questions, with answers) documents:

The web FAQ is more complete.

1.10.4. Books

1.10.4.1. qmail

John Levine and Russell Nelson are writing a qmail book for O'Reilly & Associates (http://www.oreilly.com) which should be available later this year. Russell and John are frequent contributors to the qmail mailing list, and have demonstrated thorough knowledge of qmail and the ability to communicate it effectively and politely. O'Reilly has an excellent reputation in computing-related publishing. This book will undoubtedly become the qmail "bible".

For more information or to order this book when it becomes available, see http://www.amazon.com/exec/obidos/ASIN/1565926285/davesill.

1.10.4.2. Running qmail

Richard Blum has written Running qmail, which is published by Sams. This book has received mixed reviews on the qmail mailing list.

For more information or to order this book, see http://www.amazon.com/exec/obidos/ASIN/0672319454/davesill.

1.10.5. List archives

The qmail e-mail mailing list, maintained by Dan Bernstein, is a valuable source of information. A web archive of the lists messages is kept at:

A search engine for the archive is at:

Other web archives are available at:

Most questions about qmail can be answered by searching the list archives first.

1.10.6. Other Web Sites

1.11. Support

1.11.1. Mailing lists

The following lists reside on list.cr.yp.to. In order to prevent harvesting of e-mail addresses by spammers, I'm avoiding the use of complete, valid addresses and "mailto" URL's.

The lists are managed by ezmlm, which uses different addresses to perform different functions:

To specify a subscription/unsubscription address, say joe@example.com, send the message to:

1.11.1.1. qmail

The main qmail mailing list. Discussion and questions/answers on everything related to qmail, except serialmail. Read the FAQ and search the list archives before posting a question. When you ask questions, please try to include sufficient details to make it possible for people to respond:

1.11.1.2. qmailannounce

The qmail announcement mailing list. New releases are announced here. There's no submission address: it's a read-only list.

1.11.1.3. serialmail

For discussion of the serialmail package.

1.11.1.4. ezmlm

For discussion of the ezmlm mailing list manager.

1.11.2. Consultants

See http://www.qmail.org/top.html#paidsup for a list of commercial support providers.

1.11.3. FAQTS Knowledgebase

A database of qmail-related questions and answers is available at http://qmail.faqts.com. If you have a question that the FAQ doesn't answer, try searching this knowledgebase. It's especially good at answering "how to" questions.


2. Installation

This section covers installing qmail. If you're an experienced system administrator, you can install qmail following the directions in INSTALL in the source distribution. The INSTALL directions are the official installation directions. They're more complex than the Life with qmail directions, and they assume that the reader is an experienced system and mail administrator.


Note: If you choose to install using the following directions, you should read through the entire section to familiarize yourself with the overall process.

2.1. Installation Issues

2.1.1. Binary vs. source code

Due to qmail's restrictive licensing regarding the distribution of prebuilt packages, qmail is usually installed from a source code distribution.

If you're not familiar with the distinction between source code and binaries, imagine ordering a pizza delivered to your house. The "binary" version of the pizza arrives ready-to-eat. The "source code" pizza comes as a kit containing flour, yeast, cheese, sauce, toppings, and directions for cooking the pizza yourself. Source code installations are a little more work for you, but if you follow the directions carefully, the result is the same--or even better. The self-baked pizza will be fresher, you can adjust the toppings to your preferences, and you'll know a lot more about your pizza and how it "works".

2.1.2. Tarball vs. OS-specific package

Some operating systems provide a mechanism for automating source code installations. Returning to the pizza analogy, they make it possible to package the ingredients and directions in such a way that you can just push a button and have the pizza bake itself.

Sounds great, doesn't it?

In practice, it might not be such a good idea. Assembling these packages is pretty difficult, and they might not do things the way they're supposed to. They're software, and like any software, they can have bugs. But even if they're bug free, the convenience they provide comes at a cost. You lose most of the advantages of the self-baked pizza: the ability to adjust the toppings to your personal preferences, and the knowledge of how the pizza was made and how it works.

If qmail was a pizza, the self-building approach might still be the way to go. But it's not: it's a fairly complicated system that the installer/maintainer needs to understand pretty well in order to be able to keep it working smoothly. The self-installing qmail is easier to install than the user-installed version, but the user-installed version is easier to configure and troubleshoot. You install qmail once on a system, but you will probably have several opportunities to reconfigure it or try to figure out why mail isn't flowing the way you think it should.

For this reason, I suggest installing qmail from scratch using the source code tarball, not a Red Hat "RPM" or other "self-installing" bundle.

2.2. Preparation

Before installing qmail on a system, especially if this is your first qmail installation, there are a few things you need to think about.

2.3. System requirements

qmail will install and run on most UNIX and UNIX-like systems, but there are few requirements:

2.4. Download the source

OK, so you've got a system meeting the requirements ready for installing qmail. The first step is to download the source code for qmail and any other add-ons. You'll need qmail, of course, and you should probably also get ucspi-tcp and daemontools:

Retrieve these files using your web browser or FTP client.


Note: If any of the links fail, it's probably because the package has been updated. In that case, you should go to http://cr.yp.to/software.html and follow the links to download the current version. It's possible that upgraded versions aren't compatible with the following instructions, so be sure to read the release notes in the "Upgrading from previous versions..." sections.

2.5. Build the source

2.5.1. Verify build environment

The first thing you need to do is make sure that you have the necessary tools to compile a program. How you determine this depends on what flavor of UNIX you're using. The easiest way to tell, although it's not guaranteed, is to try it.


Note: if any one of these tests passes, you can stop and go on to the next section.

    $ cc
    cc: No input files specified
    $

In this section we'll go through the actual steps of compiling qmail. A way to cut-n-paste will come in handy here, but isn't really necessary.

2.5.2. Unpack the distribution

If you made it this far, you have a working C compiler and copies of the tarballs. Copy or move the tarballs to the directory you want to do the work in. /usr/local/src is a good choice, and in this case you can use /usr/local/src/qmail for all three packages.

    mkdir -p /usr/local/src/qmail
    mv *.tar.gz /usr/local/src/qmail

You've got all three packages in /usr/local/src/qmail, so now you can unpack them. At this time you probably want to become root, if you're not already. At a prompt, type the following:

    su -
    cd /usr/local/src/qmail
    gunzip qmail-1.03.tar.gz
    tar xvf qmail-1.03.tar
    gunzip ucspi-tcp-0.88.tar.gz
    tar xvf ucspi-tcp-0.88.tar
    gunzip daemontools-0.70.tar.gz
    tar xvf daemontools-0.70.tar
    rm *.tar    # optional, unless space is very tight

There should now be subdirectories called qmail-1.03, ucspi-tcp-0.88, and daemontools-0.70. Change to the qmail-1.03 directory and let's get started:

    cd qmail-1.03

2.5.3. Create directories

Since qmail's installation program creates the subdirectories as they're needed, you only need to create the qmail "home" directory:

    mkdir /var/qmail

And on to the next section.


Note: If you want some or all of the qmail files to reside elsewhere than /var, this can be accomplished by creating symbolic links under /var/qmail pointing to the other locations.

For example, a more distributed layout can be achieved by doing:

    mkdir /var/qmail
    ln -s /usr/man /var/qmail/man
    mkdir /etc/qmail
    ln -s /etc/qmail /var/qmail/control
    ln -s /usr/sbin /var/qmail/bin


2.5.4. Create users and groups

The easiest way to create the necessary users and groups is to create a little script file to do it for you. In the source directory you'll find a file called INSTALL.ids. It contains the command lines for many platforms, so copying the file to another name and editing that is quick and easy.

    cp INSTALL.ids  IDS

Then, using your favorite editor, remove all of the file except the lines you want. For example, here's what IDS would look like for FreeBSD after editing:

    pw groupadd nofiles
    pw useradd alias -g nofiles -d /var/qmail/alias -s /nonexistent
    pw useradd qmaild -g nofiles -d /var/qmail -s /nonexistent
    pw useradd qmaill -g nofiles -d /var/qmail -s /nonexistent
    pw useradd qmailp -g nofiles -d /var/qmail -s /nonexistent
    pw groupadd qmail
    pw useradd qmailq -g qmail -d /var/qmail -s /nonexistent
    pw useradd qmailr -g qmail -d /var/qmail -s /nonexistent
    pw useradd qmails -g qmail -d /var/qmail -s /nonexistent

Then to run it, either use chmod to make it executable or run it with sh:

First method:

    chmod 700 IDS
    ./IDS

Second method:

    /bin/sh IDS

When the script finishes, all of your users and groups will be created and you can go on to the next section.

But what do you do if your system isn't listed in INSTALL.ids? You'll have to create them manually. Start by using your favorite editor and editing /etc/group. You need to add the following two lines to the end of the file:

    qmail:*:2107:
    nofiles:*:2108:


Note: Make sure that 2107 and 2108 aren't already used.

Next, using vipw (most systems have it, if not you'll need to use your editor again but this time on /etc/passwd) add these lines to the end of the file:

    alias:*:7790:2108::/var/qmail/alias:/bin/true
    qmaild:*:7791:2108::/var/qmail:/bin/true
    qmaill:*:7792:2108::/var/qmail:/bin/true
    qmailp:*:7793:2108::/var/qmail:/bin/true
    qmailq:*:7794:2107::/var/qmail:/bin/true
    qmailr:*:7795:2107::/var/qmail:/bin/true
    qmails:*:7796:2107::/var/qmail:/bin/true


Note: Make sure 7790-7796 aren't already in use and that 2107 and 2108 are the same group ids you used above.

You don't specifically need to add any of these lines to the end of the file, that's just the easiest way to explain it here.

You're now ready to continue on to the next section.

2.5.5. Do the build

You're now ready to start building qmail.

In the Verify Build Environment section, you located your C compiler. If it's not called cc or the directory it resides in isn't in your PATH environment variable, you'll need to edit conf-cc and conf-ld. Say your compiler is gcc, and it's in your PATH. Simply edit conf-cc and conf-ld and replace "cc" with "gcc".

Now type the following:

    make setup check

After the build is complete, you'll need to do your post installation configuration. A couple of scripts are provided to make this job a lot easier.

If your DNS is configured properly, this script should be all you need at this point:

    ./config

If, for some reason, config can't find your hostname in DNS, you'll have to run the config-fast script:

    ./config-fast the.full.hostname

For example, if your domain is example.com and the hostname of your computer is dolphin, your config-fast line would look like this:

    ./config-fast dolphin.example.com

qmail is now installed on your system and is ready to be run! The next section will guide you through the steps of starting and testing qmail.

2.6. Install ucspi-tcp

Earlier, you unpacked the qmail, ucpsi-tcp, and daemontools tarballs. In our example, we unpacked them into /usr/local/src/qmail. Now change to the ucpsi-tcp directory:

    cd /usr/local/src/qmail/ucspi-tcp-0.88

In the Do the build section, if you modified conf-cc and conf-ld, you'll need to make the same changes in this directory.

Then do:

    make
    make setup check

That's it. ucpsi-tcp is installed.

2.7. Install daemontools

Change to the daemontools build directory:

    cd /usr/local/src/qmail/daemontools-0.70

Once again, if you modified conf-cc and conf-ld during the qmail and ucspi-tcp builds, you'll need to make the same changes in this directory.

Then do:

    make
    make setup check

Test the build by following the directions in http://cr.yp.to/daemontools/install.html.

2.8. Start qmail

2.8.1. /var/qmail/rc

The /var/qmail/boot directory contains example qmail boot scripts for different configurations: /var/spool/mail vs. $HOME/Mailbox, using procmail or dot-forward, and various combinations of these. Feel free to examine these, but for our installation, we'll use the following:

#!/bin/sh

# Using stdout for logging
# Using control/defaultdelivery from qmail-local to deliver messages by default

exec env - PATH="/var/qmail/bin:$PATH" \
qmail-start "`cat /var/qmail/control/defaultdelivery`"

Use your editor to create the above /var/qmail/rc, then execute these commands:

    chmod 755 /var/qmail/rc
    mkdir /var/log/qmail

At this point you need to decide the default delivery mode for messages that aren't delivered by a .qmail file. The following table outlines some common choices.

Mailbox format Name Location defaultdelivery Comments
mbox Mailbox $HOME ./Mailbox most common, works with most MUA's
maildir Maildir $HOME ./Maildir/ more reliable, less MUA support
mbox  username /var/spool/mail See INSTALL.vsm traditional UNIX mailbox

See INSTALL.mbox, INSTALL.maildir, and INSTALL.vsm for more information.

To select your default mailbox type, just enter the defaultdelivery value from the table into /var/qmail/control/defaultdelivery. E.g., to select the standard qmail Mailbox delivery, do:

    echo ./Mailbox >/var/qmail/control/defaultdelivery


Note: defaultdelivery isn't a standard qmail control file. It's a feature of the /var/qmail/rc file above.

2.8.2. System start-up files

2.8.2.1. The qmail script

If you were to manually execute the /var/qmail/rc script, qmail would be partially started. But we want qmail started up automatically every time the system is booted and we want it shut down cleanly when the system is halted.

This is accomplished by creating a startup/shutdown script like the following:

#!/bin/sh

PATH=/var/qmail/bin:/usr/local/bin:/usr/bin:/bin
export PATH

case "$1" in
  start)
    echo -n "Starting qmail: svscan"
    cd /var/qmail/supervise
    env - PATH="$PATH" svscan &
    echo $! > /var/run/svscan.pid
    echo "."
    ;;
  stop)
    echo -n "Stopping qmail: svscan"
    kill `cat /var/run/svscan.pid`
    echo -n " qmail"
    svc -dx /var/qmail/supervise/*
    echo -n " logging"
    svc -dx /var/qmail/supervise/*/log
    echo "."
    ;;
  stat)
    cd /var/qmail/supervise
    svstat * */log
    ;;
  doqueue|alrm)
    echo "Sending ALRM signal to qmail-send."
    svc -a /var/qmail/supervise/qmail-send
    ;;
  queue)
    qmail-qstat
    qmail-qread
    ;;
  reload|hup)
    echo "Sending HUP signal to qmail-send."
    svc -h /var/qmail/supervise/qmail-send
    ;;
  pause)
    echo "Pausing qmail-send"
    svc -p /var/qmail/supervise/qmail-send
    echo "Pausing qmail-smtpd"
    svc -p /var/qmail/supervise/qmail-smtpd
    ;;
  cont)
    echo "Continuing qmail-send"
    svc -c /var/qmail/supervise/qmail-send
    echo "Continuing qmail-smtpd"
    svc -c /var/qmail/supervise/qmail-smtpd
    ;;
  restart)
    echo "Restarting qmail:"
    echo "* Stopping qmail-smtpd."
    svc -d /var/qmail/supervise/qmail-smtpd
    echo "* Sending qmail-send SIGTERM and restarting."
    svc -t /var/qmail/supervise/qmail-send
    echo "* Restarting qmail-smtpd."
    svc -u /var/qmail/supervise/qmail-smtpd
    ;;
  cdb)
    tcprules /etc/tcp.smtp.cdb /etc/tcp.smtp.tmp < /etc/tcp.smtp
    chmod 644 /etc/tcp.smtp*
    echo "Reloaded /etc/tcp.smtp."
    ;;
  help)
    cat <<HELP
   stop -- stops mail service (smtp connections refused, nothing goes out)
  start -- starts mail service (smtp connection accepted, mail can go out)
  pause -- temporarily stops mail service (connections accepted, nothing leaves)
   cont -- continues paused mail service
   stat -- displays status of mail service
    cdb -- rebuild the tcpserver cdb file for smtp
restart -- stops and restarts smtp, sends qmail-send a TERM & restarts it
doqueue -- sends qmail-send ALRM, scheduling queued messages for delivery
 reload -- sends qmail-send HUP, rereading locals and virtualdomains
  queue -- shows status of queue
   alrm -- same as doqueue
    hup -- same as reload
HELP
    ;;
  *)
    echo "Usage: $0 {start|stop|restart|doqueue|reload|stat|pause|cont|cdb|queue|help}"
    exit 1
    ;;
esac

exit 0

This script is also available via http://Web.InfoAve.net/~dsill/qmail-script-dt61.exe. The ".exe" tricks the web server into thinking the script is an executable, which prevents it from converting the file to DOS format.


Note: If you find that qmail exits shortly after the system is rebooted, you can prefix the env command in the "start" section of the script with nohup. E.g.:

    nohup env - PATH="$PATH" svscan &


Create the script using your editor or by downloading it with your web browser, then install it into your system's init.d directory, which should be in one of the following locations:

Name the script qmail. You'll also need to link the script into a couple of "rc" directories. These directories are named like rcN.d, where N is the runlevel they apply to. The intricacies of the startup directory tree are beyond the scope of this document, so if these simplified instructions don't suffice, consult your system documentation. Your rc directories will probably be in one of:

To create the links, execute the following commands, replacing RCDIR with the location of your system's rc directories:

    ln -s ../init.d/qmail RCDIR/rc0.d/K30qmail
    ln -s ../init.d/qmail RCDIR/rc1.d/K30qmail
    ln -s ../init.d/qmail RCDIR/rc2.d/S80qmail
    ln -s ../init.d/qmail RCDIR/rc3.d/S80qmail
    ln -s ../init.d/qmail RCDIR/rc4.d/S80qmail
    ln -s ../init.d/qmail RCDIR/rc5.d/S80qmail
    ln -s ../init.d/qmail RCDIR/rc6.d/K30qmail


Note: the numbers in the previous step are highly system dependent, but somewhat flexible. If Sendmail is currently installed, running the command "find RCDIR -name "*sendmail" -print" will give you numbers that should work for your system.

Make the startup script executable and link it to a directory in your path:

    # substitute the correct location of your rc dir on the next two lines
    chmod 755 /etc/init.d/qmail
    ln -s /etc/init.d/qmail /usr/local/sbin

2.8.2.2. The supervise scripts

Now create the supervise directories for the qmail services:

    mkdir -p /var/qmail/supervise/qmail-send/log
    mkdir -p /var/qmail/supervise/qmail-smtpd/log
    chmod +t /var/qmail/supervise/qmail-send
    chmod +t /var/qmail/supervise/qmail-smtpd

Create the /var/qmail/supervise/qmail-send/run file:

#!/bin/sh
exec /var/qmail/rc

Create the /var/qmail/supervise/qmail-send/log/run file:

#!/bin/sh
exec /usr/local/bin/setuidgid qmaill /usr/local/bin/multilog t /var/log/qmail

Create the /var/qmail/supervise/qmail-smtpd/run file:

#!/bin/sh
QMAILDUID=`id -u qmaild`
NOFILESGID=`id -g qmaild`
MAXSMTPD=`cat /var/qmail/control/concurrencyincoming`
exec /usr/local/bin/softlimit -m 2000000 \
    /usr/local/bin/tcpserver -v -p -x /etc/tcp.smtp.cdb -c "$MAXSMTPD" \
        -u "$QMAILDUID" -g "$NOFILESGID" 0 smtp /var/qmail/bin/qmail-smtpd 2>&1


Note: concurrencyincoming isn't a standard qmail control file. It's a feature of the above script.


Note: Under Solaris, the normal id program won't work right in this script. Instead of id, use /usr/xpg4/bin/id, e.g.:

    QMAILDUID=`/usr/xpg4/bin/id -u qmaild`
    NOFILESGID=`/usr/xpg4/bin/id -g qmaild`



Note: the memory limit specified in the softlimit command may need to be raised depending upon your operating system and hardware platform. If attempts to connect to port 25 fail, or remote systems are unable to send you mail, try raising it to 3000000 or 4000000.

Create the concurrencyincoming control file:

    echo 20 > /var/qmail/control/concurrencyincoming
    chmod 644 /var/qmail/control/concurrencyincoming

Create the /var/qmail/supervise/qmail-smtpd/log/run file:

#!/bin/sh
exec /usr/local/bin/setuidgid qmaill /usr/local/bin/multilog t /var/log/qmail/smtpd

Make the run files executable:

    chmod 755 /var/qmail/supervise/qmail-send/run
    chmod 755 /var/qmail/supervise/qmail-send/log/run
    chmod 755 /var/qmail/supervise/qmail-smtpd/run
    chmod 755 /var/qmail/supervise/qmail-smtpd/log/run

Then set up the log directories:

    mkdir -p /var/log/qmail/smtpd
    chown qmaill /var/log/qmail /var/log/qmail/smtpd

2.8.2.3. SMTP Access Control

Allow the local host to inject mail via SMTP:

    echo '127.:allow,RELAYCLIENT=""' >>/etc/tcp.smtp
    /usr/local/sbin/qmail cdb

2.8.3. Stop and disable the installed MTA

Although it's possible to run both qmail and your existing MTA, which is probably Sendmail, simultaneously, I don't recommend it unless you know what you're doing. And, frankly, if you're reading this, you probably don't know what you're doing. :-)

If your existing MTA is Sendmail, you should be able to stop it by running the init.d script with the "stop" argument. E.g., one of these should work:

    /etc/init.d/sendmail stop
    /sbin/init.d/sendmail stop
    /etc/rc.d/init.d/sendmail stop

If you can't find an init.d/sendmail script, you can locate sendmail's PID using "ps -ef|grep sendmail" or "ps waux|grep sendmail" and stop it using:

    kill PID-of-sendmail

If your MTA isn't Sendmail, check its documentation for the correct shutdown procedure.

You should also consider removing the old MTA completely from the system. At least disable the init.d script so it doesn't try to start up again when the system is rebooted.

For Red Hat Linux, removing Sendmail can be accomplished by:

    rpm -e --nodeps sendmail

Lastly, replace any existing /usr/lib/sendmail with the qmail version:

    mv /usr/lib/sendmail /usr/lib/sendmail.old                  # ignore errors
    mv /usr/sbin/sendmail /usr/sbin/sendmail.old                # ignore errors
    chmod 0 /usr/lib/sendmail.old /usr/sbin/sendmail.old        # ignore errors
    ln -s /var/qmail/bin/sendmail /usr/lib
    ln -s /var/qmail/bin/sendmail /usr/sbin

We're this close to being able to start qmail. The last step is to create a couple system aliases.

2.8.4. Create System Aliases

There are three system aliases that should be created on all qmail installations:

Alias Purpose
postmaster RFC 821 required, points to the mail adminstrator (you)
mailer-daemon de facto standard recipient for some bounces
root redirects mail from privileged account to the system administrator

To create these aliases, decide where you want each of them to go (a local user or a remote address) and create and populate the appropriate .qmail files. For example, say local user dave is both the system and mail administrator:

    echo dave > /var/qmail/alias/.qmail-root
    echo dave > /var/qmail/alias/.qmail-postmaster
    ln -s .qmail-postmaster /var/qmail/alias/.qmail-mailer-daemon
    chmod 644 /var/qmail/alias/.qmail-root /var/qmail/alias/.qmail-postmaster

See INSTALL.alias for more details.

2.8.5. Start qmail

Finally, you can start qmail:

    /usr/local/sbin/qmail start

2.9. Test the Installation

qmail should now be running. Follow the instructions in TEST.deliver and TEST.receive to verify that it's working correctly. Note that using these instructions, logging will be accomplished by multilog, not splogger.


3. Configuration

You've got qmail installed, either from the recommended source tarball method, or one of the self-compiling packages. This section contains information the mail administrator or system administrator will need to configure qmail to make it work the way they want it to.

3.1. Configuration Files

All of qmail's system configuration files, with the exception of the .qmail files in ~alias, reside in /var/qmail/control. The qmail-control man page contains a table like the following:

Control Default Used by Purpose
badmailfrom none qmail-smtpd blacklisted From addresses
bouncefrom MAILER-DAEMON qmail-send username of bounce sender
bouncehost me qmail-send hostname of bounce sender
concurrencylocal 10 qmail-send max simultaneous local deliveries
concurrencyremote 20 qmail-send max simultaneous remote deliveries
defaultdomain me qmail-inject default domain name
defaulthost me qmail-inject default host name
databytes 0 qmail-smtpd max number of bytes in message (0=no limit)
doublebouncehost me qmail-send host name of double bounce sender
doublebounceto postmaster qmail-send user to receive double bounces
envnoathost me qmail-send default domain for addresses without "@"
helohost me qmail-remote host name used in SMTP HELO command
idhost me qmail-inject host name for Message-ID's
localiphost me qmail-smtpd name substituted for local IP address
locals me qmail-send domains that we deliver locally
me FQDN of system various default for many control files
morercpthosts none qmail-smtpd secondary rcpthosts database
percenthack none qmail-send domains that can use "%"-style relaying
plusdomain me qmail-inject domain substituted for trailing "+"
qmqpservers none qmail-qmqpc IP addresses of QMQP servers
queuelifetime 604800 qmail-send seconds a message can remain in queue
rcpthosts none qmail-smtpd domains that we accept mail for
smtpgreeting me qmail-smtpd SMTP greeting message
smtproutes none qmail-remote artificial SMTP routes
timeoutconnect 60 qmail-remote how long, in seconds, to wait for SMTP connection
timeoutremote 1200 qmail-remote how long, in seconds, to wait for remote server
timeoutsmtpd 1200 qmail-smtpd how long, in seconds, to wait for SMTP client
virtualdomains none qmail-send virtual domains and users

For more information about a particular control file, see the man page for the module listed under "Used by".

3.2. Relaying

3.2.1. Introduction

What is relaying? It's when an MTA accepts a message via SMTP that doesn't appear to be either for a local address or from a local sender.

In the pre-spam days, it was common for MTA's to be configured as open relays: promiscuous servers that would accept mail from anyone, for anyone.

Most MTA's now are configured to either completely disable relaying, or to only a allow certain trusted users or systems to use them as a relay.

Chris Johnson has written a very nice document on the topic for qmail users. I encourage you to visit http://www.palomine.net/qmail/relaying.html.

3.2.2. Disabling relaying

If you follow the official directions for installing qmail, relaying will be turned off by default. This is accomplished by populating the file /var/qmail/control/rcpthosts with the fully-qualified domain names listed in locals and virtualdomains (the local hosts). The name of the control file, rcpthosts, comes from the SMTP RCPT (recipient) command. In an SMTP session, RCPT is used to specify the addresses of the recipients of a message. rcpthosts, then, lists the valid hostnames that can appear in a RCPT address.

3.2.3. Allowing selective relaying

Most single-user and small workgroup servers can disable relaying completely, but if you have to support a distributed user community, you'll need a way to allow your users, and only your users, to use your system as a relay. This is accomplished by using tcpserver to set the RELAYCLIENT environment variable, which tells qmail-smtpd to override the rcpthosts file.

If you follow the installation instructions in this document, selective relaying will be enabled by default. To give a client relay access, add an entry to /etc/tcp.smtp like:

    IP address of client:allow,RELAYCLIENT=""

Then rebuild the SMTP access database by doing:

    tcprules /etc/tcp.smtp.cdb /etc/tcp.smtp.tmp < /etc/tcp.smtp
    chmod 644 /etc/tcp.smtp*

If you followed the official installation instructions, Chris Johnson has written another very nice document on how to configure qmail to allow selected hosts to relay. See http://www.palomine.net/qmail/selectiverelay.html.

3.3. Multiple host names

If your system is known by more than one name, e.g., all addresses of the form user@host1.example.com can also be written as user@example.com or user@mail.example.com, then you need to tell qmail this so it'll know which addresses it should deliver locally and which messages it should accept from remote systems.

To do this, just add all of the names to two control files:

3.4. Virtual domains

Virtual domains are similar to the multiple host names discussed in the previous section, but there are some important differences. First, if example.net hosts the virtual domain virtual.example.com, it's generally not true that messages sent to joe@example.net will end up in the same mailbox as messages sent to joe@virtual.example.com. The namespace for each virtual domain is distinct.

With qmail, virtual domains are configured in the virtualdomains file, which consists of one or more entries of the form:

    user@domain:prepend

qmail converts user@domain to prepend-user@domain and treats the result as if domain was local. The user@ part is optional. If it's omitted, the entry matches all @domain addresses.

Returning to the example scenario above, if the example.net mail administrator wanted to create a virtual domain, virtual.example.com, under the administrative control of user john, the following entry in virtualdomains would accomplish that:

    virtual.example.com:john

An incoming message to joe@virtual.example.com would be rewritten as john-joe@virtual.example.com and delivered locally. See the .qmail section, and the extension addresses subsection for more information about how john can manage his virtual domain.

As with multiple host names, all virtual domains must be listed in rcpthosts so qmail-smtpd will know to accept messages addressed to them. However, unlike multiple host names, virtual domains must not be added to locals.


Note: domain name server (DNS) mail exchanger (MX) records must be set up to direct messages for virtual domains to the appropriate mail server. This is a job for the name server administrator and is beyond the scope of this guide.

3.5. Aliases

qmail's standard aliasing mechanism is a natural outgrowth of qmail's local delivery mechanism. qmail-local attempts to deliver a message addressed to localpart@host to a local user named localpart. If no matching user is found, the message is delivered to the alias user, a pseudo-user on all qmail systems whose home directory is /var/qmail/alias.

For example, say you want to create an info@example.com alias that forwards messages to user tom. On example.com, do, as user root:

    echo tom > /var/qmail/alias/.qmail-info

The .qmail section and extension addresses subsection describe how to create .qmail files that specify which aliases exist, and what to do with messages sent to them.

Note that because of the way aliases are implemented in qmail, an alias can never override a valid user's deliveries. E.g., if rachel is a normal user, ~alias/.qmail-rachel will not be used.

The fastforward package provides an alternative aliasing mechanism that puts multiple aliases in a single file compatible with Sendmail's alias database.

The next section, qmail-users, describes another mechanism that can be used to implement aliases.

3.6. qmail-users

qmail-users is a system for assigning addresses to users. A series of configuration files resides under /var/qmail/users. The assign file is a table of assignments. There are two kinds of assignments: simple and wildcard.


Note: assign contains a series of assignments, one per line, followed by a line containing a single dot (.). If you create assign manually, don't forget the dot line.

3.6.1. Simple assignment

A simple assignment looks like:

=address:user:uid:gid:directory:dash:extension:

What this means is that messages received for address will run as user user, with the specified uid and gid, and the file directory/.qmaildashextension will specify how the messages are to be delivered.

3.6.2. Wildcard assignment

A wildcard assignment looks like:

+prefix:user:uid:gid:directory:dash:prepend:

What this means is that messages received for addresses of the form prefixrest will run as user user, with the specified uid and gid, and the file directory/.qmaildashprependrest will specify how the messages are to be delivered.

3.6.3. qmail-user programs

qmail-user has two helper programs: qmail-newu and qmail-pw2u.

qmail-newu processes the assign file and generates a constant database (CDB) file called cdb in /var/qmail/users. CDB is binary format that can be accessed quickly by qmail-lspawn, even when there are thousands of assignments.

qmail-pw2u converts the system user database, /etc/passwd, into a series of assignments suitable for assign. qmail-pw2u uses a set of files to modify the translation rules.


Note: if you use qmail-pw2u, don't forget to re-run qmail-pw2u and qmail-newu whenever you add users, remove users, or change UID's or GID's.

3.7. Spam Control

Chris Hardie has written a good qmail Anti-Spam HOWTO. It's available from http://www.summersault.com/chris/techno/qmail/qmail-antispam.html.


4. Usage

This section covers the usage of qmail by normal users. If you read or send mail on a qmail system, this is where you'll find information about how to do that with qmail.

4.1. .qmail files

Delivery of a user's mail is usually controlled by one or more ".qmail" (pronounced dot kyoo mail) files--files in the user's home directory with names beginning with .qmail. The dot-qmail man page describes .qmail file usage.

.qmail files contain a list of delivery instructions, one instruction per line. The first character of the line determines what kind of delivery is involved:

Character Delivery Type Value
# none (comment) ignored
| program command to be run by shell
/ or . mbox (if last char isn't a /) pathname of mbox (including the / or .)
/ or . maildir (if last char is a /) pathname of maildir (including the / or .)
& forward address to forward message
letter or number forward address to forward message (including the first char)

4.1.1. program delivery

When a program delivery instruction is encountered, qmail starts a shell (/bin/sh) to execute the command and feeds the command a copy of the incoming message on standard input. The qmail-command man page documents the details of this process.

Program delivery is very powerful, and can be used to implement a wide range of functionality such as message filtering, automatically responding to messages, and delivery via third-party delivery agents such as procmail.

E.g.:

    |preline /usr/ucb/vacation djb

This causes qmail to start preline, pass it /usr/ucb/vacation and djb as arguments, and provide a copy of the message on standard input.

4.1.2. mbox delivery

"Mbox" is qmail-speak for the standard UNIX mailbox format, in which multiple messages are stored in a single file and messages are headed with a "From " line. This line looks like a header field, but it isn't one: it's just something the delivery agent adds so mail readers can tell where each message begins.

E.g.:

    ./Mailbox

This causes messages to be appended to $HOME/Mailbox, with a "From " line prepended. A simple mbox mailbox with a single message looks like:

    From user1@example.net Thu May 13 18:34:50 1999
    Received: (qmail 1287205 invoked from network); 13 May 1999 18:34:49 -0000
    From: user1@example.net
    To: user2@example.com
    Subject: hey

    What's up?

The first line was added at delivery by qmail.

4.1.3. maildir delivery

"Maildir" is a mailbox format created by Dan Bernstein to address the shortcomings of the mbox format. A maildir mailbox is a directory containing three subdirectories, new, cur, and tmp. Each message in a maildir mailbox is in a separate file in one of the subdirectories, depending upon its status: new is for unread messages, cur is for messages that have been seen, and tmp is for messages in the process of being delivered. The maildir man page describes the format of a maildir in detail.

One of the benefits of the maildir format is that, even though it doesn't use locking to prevent simultaneous updates from different delivery agents, it's reliable. This means maildir mailboxes can safely reside on NFS-mounted filesystems.

E.g.:

    ./Maildir/

This causes messages to be saved in $HOME/Maildir, a maildir-format mailbox.


Note: qmail-local can deliver mail to maildir mailboxes, but it can't create them. Maildir mailboxes should be created with the maildirmake program that comes with qmail. E.g., "maildirmake ~/Maildir".

4.1.4. forward delivery

Forward deliveries causes the message to be resent to the specified address. Addresses specified in .qmail files can't contain comment fields or extra spaces.

These are wrong:

    &<user@example.com>
    & user@example.com
    &Joe User <user@example.com>

These are correct:

    &user@example.com
    user@example.com
    &user

The first two cause user@example.com to receive a copy of the message. The last sends a copy to the local user user.

4.1.5. extension addresses

qmail supports user-controlled extension addresses. In addition to the base address, username@hostname.domain, users can receive mail at username-extension@hostname.domain. For the remainder of this section, I'll leave off the "@hostname.domain" part since we're considering actions that take place on the local system.

The delivery instructions for username-extension are in ~username/.qmail-extension.

For example, dave-lwq@sparge.example.com is controlled by ~dave/.qmail-lwq on host sparge.

Extensions can have multiple fields, e.g., dave-list-qmail, controlled by ~dave/.qmail-list-qmail. In this example, dave-list-qmail is subscribed to the qmail mailing list, and ~dave/.qmail-list-qmail files the list messages in a separate mailbox.

.qmail files can be wildcarded using -default. So dave-list-qmail could also be handled by ~dave/.qmail-list-default. This would allow one catch-all .qmail file to handle all dave-list-whatever addresses. Note that dave-list wouldn't be handled by ~dave/.qmail-list-default because it doesn't match the "-" after "list".

qmail uses the closest match it finds. E.g., when a message comes in addressed to dave-list-qmail, it'll use the first one of the following that it finds:

    .qmail-list-qmail
    .qmail-list-default
    .qmail-default

If no matching .qmail file is found, the delivery fails and the message bounces back to the sender.

4.2. Sending messages

Mail users don't usually use the MTA directly to send messages. Typically, messages are composed and sent using a Mail User Agent (MUA) such as pine or mutt, which then calls the MTA to deliver the message. The process of handing a message to the MTA is called injection.

There are two ways to inject messages into most MTA's: via the Simple Mail Transfer Protocol, SMTP, or using a program provided by the MTA for that purpose.

4.2.1. SMTP

MUA's can open a TCP connection to port 25, the standard SMTP port, on the local host or a designated mail server. The MUA and the MTA then engage in a dialogue that results in either:

SMTP has no mechanism for authentication, so no username or password is required to send a message. However, many MTA's refuse to accept messages that don't appear to be either from or for a local user. If a properly formatted message is rejected, relaying restrictions are the most likely cause. See the Relaying section for more information about relay configuration.

4.2.2. /var/qmail/bin/sendmail

For many years, Sendmail was theUNIX MTA. It was so ubiquitous, that many programmers just assumed that it was the MTA. As a result, Sendmail's local injection mechanism became the standard Application Programmer's Interface (API) for local mail injection. qmail and other non-Sendmail MTA's provide a sendmail program that works the same way as the real Sendmail's sendmail for local injection.

The qmail sendmail, which is normally in /var/qmail/bin/sendmail, usually replaces the Sendmail sendmail on qmail systems. Typical locations of the sendmail program include:

On a qmail system, "ls -l path-to-sendmail" should show that sendmail is a symbolic link to /var/qmail/bin/sendmail:

  $ ls -l /usr/lib/sendmail
  lrwxrwxrwx   1 root     root           29 Feb 19 11:04 /usr/lib/sendmail -> /var/qmail/bin/sendmail

The sendmail man page provided with qmail describes how to use the program.

4.2.3. qmail-inject

In addition to emulating the sendmail API, i<qmail> has its own injection program: qmail-inject. In fact, sendmail is just a wrapper around qmail-inject.

As an API, sendmail is probably better because it's much more widely available. The qmail API provided by qmail-inject will only work on systems with qmail, but the sendmail interface is nearly universal.

For example, to send a blank message to joe@example.com:

 echo To: joe@example.com | /var/qmail/bin/qmail-inject

4.3. Environment Variables

Some qmail programs set or use environment variables. The following table lists these variables and describes their use.

Name Man page Set or used Purpose
DATABYTES qmail-smtpd used Overrides control/databytes
DEFAULT qmail-command set Portion of address matching "-default" in a .qmail file name.
DTLINE qmail-command set Delivered-To header field
EXT qmail-command set The address extension
EXT2 qmail-command set Portion of EXT following first dash
EXT3 qmail-command set Portion of EXT following second dash
EXT4 qmail-command set Portion of EXT following third dash
HOME qmail-command set The user's home directory
HOST qmail-command set The domain part of the recipient address
HOST2 qmail-command set Portion of HOST preceding last dot.
HOST3 qmail-command set Portion of HOST preceding second-to-last dot
HOST4 qmail-command set Portion of HOST preceding third-to-last dot
LOCAL qmail-command set The local part of the recipient address
LOGNAME qmail-inject used User name in From header field (4)
MAILHOST qmail-inject used Host name in From header field (2)
MAILNAME qmail-inject used Personal name in From header field (2)
MAILUSER qmail-inject used User name in From header field (2)
NAME qmail-inject used Personal name in From header field (3)
NEWSENDER qmail-command set Forwarding sender address (see "man dot-qmail")
QMAILDEFAULTDOMAIN qmail-inject used Overrides control/defaultdomain
QMAILDEFAULTHOST qmail-inject used Overrides control/defaulthost
QMAILHOST qmail-inject used Host name in From header field (1)
QMAILIDHOST qmail-inject used Overrides control/idhost
QMAILINJECT qmail-inject used Specify various options (see next table)
QMAILMFTFILE qmail-inject used File containing list of mailing list addresses for Mail-Followup-To generation
QMAILNAME qmail-inject used Personal name in From header field (1)
QMAILPLUSDOMAIN qmail-inject used Overrides control/plusdomain
QMAILSHOST qmail-inject used Host name in envelope sender address
QMAILSUSER qmail-inject used User name in envelope sender address
QMAILUSER qmail-inject used User name in From header field (1)
RECIPIENT qmail-command set Envelope recipient address
RELAYCLIENT qmail-smtpd used Ignore control/rcpthosts and append value to recipient address
RPLINE qmail-command set Return-Path header field
SENDER qmail-command set Envelope sender address
UFLINE qmail-command set UUCP-style "From " line
USER qmail-command set The current user
USER qmail-inject used User name in From header field (3)
QMAILINJECT Flags
Letter Purpose
c Use address-comment style for the From field
s Do not look at any incoming Return-Path field
f Delete any incoming From field
i Delete any incoming Message-ID field
r Use a per-recipient VERP
m Use a per-message VERP

5. Advanced Topics

5.1. procmail

procmail is a popular Message Delivery Agent (MDA). The function of an MDA is to accept a message from the MTA for a specific user or mailbox, and deliver the message according to the user's desires. procmail can be used to "filter" messages by the content of various header fields or the body of the message. For example, messages from a particular person can be directed to a mailbox for just that person.

There are a couple tricks to running procmail with qmail. First, procmail is usually built to deliver to an mbox mailbox in /var/spool/mail. You can rebuild procmail to default to $HOME or you can instruct users not to rely on procmail to default the location of the mbox. Unless you patch it for $HOME delivery, procmail will still use /var/spool/mail for temporary files.

Another problem is that qmail-command and procmail don't have a common understanding of which exit codes mean what. procmail uses the standard UNIX exit codes: zero means success, nonzero means failure, and the cause of the failure is indicated by /usr/include/sys/errno.h. qmail-command uses certain nonzero codes to indicate permanent errors and the rest are considered temporary. A small shell script wrapper can be used to translate the exit codes for qmail-command. Such a wrapper was posted to the qmail list and is available from the archives at http://www.ornl.gov/its/archives/mailing-lists/qmail/1998/04/msg00487.html.

Also, older versions of procmail (prior to 3.14) don't deliver directly to maildir-format mailboxes. Your best bet is to upgrade to the current version of procmail. Another approach is safecat, a program that writes a message on standard input to a specified maildir. Users can write procmail recipes (delivery instructions) that use safecat to file the message. You can also skip procmail altogether, and use maildrop.

Finally, procmail expects the messages it receives to be in mbox format. Normal qmail program deliveries include only the actual mail message, not including a "From " line. The preline command can be used to format the message as procmail expects.

For example, let's say user "dave" wants his mail to be processed by procmail. His system administrator has built procmail to deliver to $HOME by default, and has provided an exit code wrapper, called /usr/local/bin/qmail-procmail. His .qmail file should look like:

|/var/qmail/bin/preline /usr/local/bin/qmail-procmail dave

5.2. POP and IMAP servers

qmail includes a POP server, qmail-pop3d, but it's not configured and installed as part of the qmail installation process. You can also use one of the other POP or IMAP servers available, although most of them were written for Sendmail and will require some work to use with qmail.

5.2.1. qmail-pop3d

qmail-pop3d is the POP server included with qmail. It's a fine POP server, and many qmail sites use it. It's modular, and supports multiple authentication schemes via alternative authentication modules.


Note: qmail-pop3d supports only maildir-format mailboxes, so if you have users logging into the POP server and running MUA's locally, they all have to support maildir. If all of your users read mail via POP, the mailbox format on the server is not an issue.

5.2.1.1. Architecture of qmail-pop3d

A qmail-pop3d server consists of three modules:

Typically, qmail-popup is run via inetd or tcpserver, listening to port 110, the POP3 port. When a connection is made, it prompts for the username and password. Then it invokes checkpassword, which verifies the username/password and invokes qmail-pop3d if they match.

5.2.1.2. Installation of qmail-pop3d

  1. Completely install and test qmail. If you want all users to have POPable mailboxes, make sure defaultdelivery is set to ./Maildir/. If you installed the qmail script from the Installation section, this is configured in control/defaultdelivery. If not, it's probably in /var/qmail/rc on the qmail-start command line.
  2. Download a checkpassword program from http://www.qmail.org/top.html#checkpassword. The standard checkpassword, http://cr.yp.to/checkpwd.html, is a good choice if you don't need anything fancy.
  3. Compile and install checkpassword according to the directions. Make sure you install it as /bin/checkpassword.
  4. For a lightly-used POP server, add an entry to /etc/inetd.conf like the following, all on one line:
pop3   stream  tcp     nowait  root    /var/qmail/bin/qmail-popup qmail-popup
    hostname.domain /bin/checkpassword /var/qmail/bin/qmail-pop3d Maildir


Note: Some systems, notably Red Hat Linux, don't call the POP3 port "pop3". Check /etc/services for the name of the service on port 110. Also, check your inetd man page to ensure the entry is formatted correctly. One tricky part is that some inetd's require the first argument to the program (qmail-popup in this example) to be the name of the program. Other inetd's want only the "real" arguments.

  1. "kill -HUP PID of inetd" to tell inetd to reread /etc/inetd.conf.
  2. For a busier service, use tcpserver instead.

To use tcpserver, add the following to your qmail startup script (not inetd.conf):

    tcpserver -v -R 0 pop3 /var/qmail/bin/qmail-popup FQDN \
        /bin/checkpassword /var/qmail/bin/qmail-pop3d Maildir 2>&1 | \
        /var/qmail/bin/splogger pop3d &

where pop3 is the name of the POP3 service listed in /etc/services and FQDN is the fully qualified domain name of the POP server you're setting up, e.g., pop.example.net.

5.2.2. qpopper

If you need a POP daemon that works with mbox-format mailboxes, you can use Qualcomm's qpopper. Vince Vielhaber has a patch available from http://www.qmail.org/qpopper2.53.patch.tar.gz that makes it work with mailboxes in user home directories. qpopper is available from http://www.eudora.com/freeware/qpop.html.

5.2.3. Solid

The Solid POP3 server supports both maildir and mbox mailboxes. It's available from http://solidpop3d.pld.org.pl/.

5.2.4. imap-maildir

David R. Harris has cleaned up the patch that adds maildir support to the University of Washington IMAP server and documented the installation process. See http://www.davideous.com/imap-maildir/.

5.2.5. Courier-IMAP

Sam Varshavchik has written an IMAP server that supports maildir mailboxes only. It's available from http://www.inter7.com/courierimap/.

5.3. POP and IMAP clients

5.3.1. fetchmail

fetchmail is a program that retrieves mail from a POP or IMAP server and re-injects it locally. fetchmail has no trouble retrieving mail from qmail servers, but there are a couple tricks for making it work well on a qmail client.

Here's a sample .fetchmailrc for a user on a qmail system:

poll mail.example.net proto pop3 nodns
    user dsill with password flubgart is dave here
    fetchall forcecr to * here

This instructs fetchmail to connect to mail.example.net via POP3, log in as user dsill, password flubgart, retrieve all messages, and deliver them to dave@localhost. The forcecr causes fetchmail to end each line with a carriage return when injecting the message on the local system via SMTP. qmail requires this.


Note: fetchmail is not very reliable. If a re-injection fails for any reason (such as a formatting error that causes a bounce or there's no SMTP server running), the message will be lost.

5.3.2. getmail

getmail is a program that retrieves mail from a POP server and delivers it to a maildir mailbox. It's actually a Python script, so you may need to install the Python interpreter before you can use getmail

getmail was written by Charles Cazabon, who maintains a web page for it at http://www.qcc.sk.ca/~charlesc/software/getmail/.

5.4. Multi-RCPT vs. Single RCPT delivery

Say you're an MTA, and one of your users sends a message to three people on hostx.example.com. There are several ways you could do this.

  1. You could open an SMTP connection to hostx, send a copy of the message to the first user, send a copy to the second user, send a copy to the third user, then close the connection.
  2. You could start three processes, each of which opens an SMTP connection to hostx, sends a copy of the message to one of the users, then closes the connection.
  3. You could open an SMTP connection to host, send a copy of the message addressed to all three users, then close the connection.

The first method is clearly inferior to the third. Even if the message is tiny, it'll take at least as long. And if the message is large, it'll take a lot longer *and* use more network bandwidth.

So scratch that one.

The second and third methods are a little more interesting.

The third method only opens one connection to hostx, and only sends one copy of the message. That makes for efficient use of bandwidth.

The second method uses multiple connections and sends multiple copies of the message. That "wastes" bandwidth, but due to the nature of the SMTP protocol, requires fewer round-trip delays, and is faster than the third method. It's also simpler than the third method, so the MTA can be coded in a more straightforward manner. And finally, because each recipient gets their own copy of the message, it's possible for the MTA to implement VERPs (see next section).

qmail always uses the second method (single RCPT). There are no patches to implement the third method (multiple RCPT)--it would require major work.

Although there are pathological cases where it can be slower than multiple RCPT, the simplicity and VERP advantages outweigh that.

Single RCPT delivery does use more bandwidth than multiple RCPT delivery, but the difference is often exaggerated. Most messages have, at most, a couple recipients, and they're usually on separate hosts, so multi-RCPT delivery buys them nothing. Even on a list server, where multi-RCPT delivery could help, the potential gains are small because SMTP uses only a fraction of the bandwidth over most links--HTTP usually gets the lion's share.

For example, if 10% of your uplink's bandwidth goes to SMTP, and your SMTP bandwidth could be reduced by, say, 25%, by using multi-RCPT delivery, that would only drop your SMTP bandwidth to 7.5%.

5.5. VERP

When a message is undeliverable, the MTA that determines that is supposed to return a bounce message to the envelope return path (ERP). The bounce message should include the address of the recipient, the reason the message is undeliverable, and whether the problem is temporary or permanent. Some MTA's don't do the right thing, though. They might send the bounce the address in the From header field, or the bounce might not identify the recipient.

For most user-to-user messages, these problems aren't too bad. One can usually figure things out based on the timing of the bounce or the contents. For mailing lists, the problem of bad bounces is more serious. Subscribers move, forwarding mail to their new address. If the new address starts having delivery problems, it can be impossible to tell which subscriber's mail is bouncing if the bounce message only includes the new address.

Dan Bernstein came up with something called VERP (Variable Envelope Return Path). Using VERPs, each message sent to each subscriber to a list has a unique return path. This allows a bounce handler to identify the problem subscriber.

For example, a typical non-VERP'ed mailing list has a return address of the form listname-owner@domain. For a VERP'ed list, the return address would look like listname-owner-subscriber=sdomain@ldomain, where the subscriber's address, subscriber@sdomain, is embedded between the "owner" and the "@". (The "@" in the subscriber's address is replaced with an "=".)

The ezmlm list manager uses VERPs to automatically handle bounces. It even provides subscribers with temporary delivery problems with a list of the messages they missed so they can retrieve them from the archive.

Russell Nelson wrote a bounce manager for Majordomo under qmail, but he no longer maintains it. It's available from http://www.qmail.org/bounceman-0.4.shar.

5.6. Troubleshooting

5.6.1. Processes

A properly-running, complete, but minimal qmail installation should always have the following four processes:

Depending upon your flavor of UNIX, one of the following two commands should list these processes, and possibly a few more:

    ps -ef | grep qmail
    ps waux | grep qmail

For example:

[dave@sparge dave]$ ps waux|grep qmail
dave      2222  0.0  0.8   836   348  p4 S    10:25   0:00 grep qmail
qmaild     351  0.0  1.0   840   400  ?  S N  12:43   0:00 /usr/local/bin/tcpserver -v -x /etc/tcp.smtp.cdb -u 49491 -g 31314 0 smtp /var/qmail/bin/qmail-smtpd-
qmaild    2220  0.0  1.0   844   420  ?  S N  10:25   0:00 /usr/local/bin/tcpserver -v -x /etc/tcp.smtp.cdb -u 49491 -g 31314 0 smtp /var/qmail/bin/qmail-smtpd-
qmaill     365  0.0  0.8   748   344  ?  S N  12:43   0:00 splogger qmail
qmailq     368  0.0  0.7   736   292  ?  S N  12:43   0:00 qmail-clean
qmailr     367  0.0  0.6   732   272  ?  S N  12:43   0:00 qmail-rspawn
qmails     350  0.0  0.8   776   336  ?  S N  12:43   0:00 qmail-send
root       340  0.0  0.6   724   252  ?  S N  12:43   0:00 /usr/local/sbin/supervise /var/supervise/qmail-send /var/qmail/rc
root       341  0.0  0.6   724   252  ?  S N  12:43   0:00 /usr/local/sbin/supervise /var/supervise/tcpserver-qmail /usr/local/bin/tcpserver -v -x /etc/tcp.smtp
root       366  0.0  0.7   736   276  ?  S N  12:43   0:00 qmail-lspawn ./Mailbox
[dave@sparge dave]$

If you run qmail or qmail-smtpd under supervise, as in the example above, you should see those processes as well. And if run qmail-smtpd under tcpserver, you should see a parent tcpserver process plus an additional tcpserver process for each active incoming SMTP connection.

If you use splogger (or multilog or cyclog) to handle logging, you'll have a splogger (or multilog or cyclog) process or two running as user qmaill.

Also, if qmail is busy delivering messages locally or remotely, you'll see up to concurrencylocal qmail-local processes and up to concurrencyremote qmail-remote processes.

5.6.2. Logs

5.6.2.1. splogger

splogger uses the syslog logging system to timestamp messages and send them to the syslog daemon. Syslog is configured in /etc/syslog.conf. Messages sent to syslog have a facility and priority. Entries in /etc/syslog.conf filter on the facility and priority to direct the messages to the desired log file, remote log host, or the console. splogger logs to the mail facility, by default, so grep'ing the syslog.conf file for "mail" should show the disposition of qmail's log messages.

Typical locations include:

A typical syslog log entry looks like:

Jun  3 11:35:23 sparge qmail: 928424123.963558 delivery 153: success: did_1+0+0/

"Jun 3 11:35:23" is the syslog timestamp.

"sparge" is the name of the system that sent the message.

"qmail:" is the tag splogger places on all qmail log entries.

"928424123.963558" is an optional TAI timestamp (see next section).

"delivery 153: success: did_1+0+0/" is the log message itself.

5.6.2.2. multilog

multilog, which is part of the daemontools package, logs messages to a series of files in a specified directory.

The log directory is specified on the multilog command line, so you can find it by examining your qmail startup script.

The number of files in the log directory, and the maximum size of each file, are determined by multilog options. The log file names are the TAI (Temps Atomique International) timestamps of the time at which the file was started. The tai64nlocal command, also from daemontools, converts TAI timestamps into local, human-readable timestamps.

A typical multilog log entry looks like:

@4000000038c3eeb104a6ecf4 delivery 153: success: did_1+0+0/

"@4000000038c3eeb104a6ecf4" is the optional, but recommended, TAI timestamp. "delivery 153: success: did_1+0+0/" is the log message itself.

5.6.2.3. Log messages

Here's a typical log sequence for a message sent to a remote system from the local system:

1 @4000000038c3eeb027f41c7c new msg 93869
2 @4000000038c3eeb027f6b0a4 info msg 93869: bytes 2343 from <dave@sill.org> qp 18695 uid 49491
3 @4000000038c3eeb02877ee94 starting delivery 2392: msg 93869 to remote lwq@w3.to
4 @4000000038c3eeb0287b55ac status: local 0/10 remote 1/20
5 @4000000038c3eeb104a13804 delivery 2392: success: 209.85.127.177_accepted_message.
   /Remote_host_said:_250_CAA01516_Message_accepted_for_delivery/
6 @4000000038c3eeb104a4492c status: local 0/10 remote 0/20
7 @4000000038c3eeb104a6ecf4 end msg 93869

Line 1 indicates that qmail has received a new message, and its queue ID is 93869. The queue ID is the i-node number of the /var/qmail/queue/mess/NN/ file--the queue file that contains the message. The queue ID is guaranteed to be unique as long as the message remains in the queue.

Line 2 says that the message is from dave@sparge.sill and is 189 bytes.

Line 3 says qmail-remote is starting to deliver the message to lwq@w3.to, and it's assigning the ID 2392 to the delivery.

Line 4 says 0 local deliveries and 1 remote delivery are pending.

Line 5 says delivery 2392 is complete and successful, and it returns the remote server's response, which often contains information the remote mail administrator would find helpful in tracking a delivery. In this case, the "CAA01516" is the remote system's delivery ID.

Line 6 says 0 local deliveries and 0 remote deliveries are pending, i.e., the delivery is complete.

Line 7 says that the message has been delivered completely and removed from the queue. At this point, the queue ID, 93869, is reusable for another delivery.

5.7. Big Servers

See also qmail-ldap.

5.7.1. Scalable parallelism

Use a fast NFS network file server to store user directories. Set up multiple equal-preference SMTP servers delivering to maildir mailboxes on the file server.

5.8. Migrating from Sendmail to qmail

First, check Dan Bernstein's Sendmail->qmail page at http://cr.yp.to/qmail/sendmail.html.

5.9. Mailing List Managers

Mailing list managers (MLM's) are systems that help list owners run mailing lists. Their duties fall into two main divisions: managing the lists of subscribers, and controlling the resending of messages to the subscribers.

Most (all?) UNIX mailing list managers can be made to work with qmail.

5.9.1. ezmlm

ezmlm was written by Dan Bernstein, the author of qmail. It was written for use with qmail, and relies on several features of qmail. Most notably, it uses VERPs to reliably process bounce messages. ezmlm is somewhat unique among MLM's in that it doesn't process commands sent to a central MLM address: it appends the command to the name of the list. E.g., to subscribe to the "foo@list.example.net" list, one sends a message to "foo-subscribe@list.example.net".

For more information about ezmlm, see http://www.ezmlm.org, the unofficial ezmlm web site, and the official home of ezmlm-idx, a very nice add-on that includes many useful features.

5.9.2. Majordomo

Majordomo is the most popular UNIX MLM. It works fine with qmail provided a few simple changes are made. Russ Allbery has written a FAQ about qmail/Majordomo available from http://www.eyrie.org/~eagle/faqs/mjqmail.html.

5.10. Patches

Various source code patches are available for qmail. To install a patch, download it, cd to the qmail source tree, and apply it using the patch command.

    cd /usr/local/src/qmail/qmail-1.03
    patch -p0 </tmp/patchfile

Stop qmail by killing qmail-send or, if you installed the qmail script in the Installation section, do:

    /usr/local/sbin/qmail stop

Then rebuild and install the new binaries:

    make setup check

5.10.1. DNS

Historically, DNS responses have been limited to 512 bytes. Some large sites have started returning MX responses longer than that. qmail and many other programs have a problem with Domain Name Server (DNS) queries that return very large results. There are two ways to fix this in qmail:

5.10.1.1. Bump the packet buffer size up to 65536.

Works with recent BIND resolver libraries, which will automatically do a TCP query within the library code if the reply comes back with the truncation bit set. This is the simplest fix, though it's also potentially the most wasteful of memory, depending on how your system handles paging. To do this, just replace PACKETSZ with 65536 in dns.c and rebuild qmail.

5.10.1.2. Christopher K. Davis' patch http://www.ckdhr.com/ckd/qmail-103.patch.

This is an adaptation of a patch by Chuck Foster's which should work with any resolver library, no matter how old, and uses a guard byte to avoid the "number of bytes placed in the buffer" library bug. It reallocates only once, to 65536, rather than just to the size needed, so it can be less memory-efficient than Chuck's patch (though, like his patch, it only reallocates if the response is larger than PACKETSZ, which defaults to 512 bytes). After reallocating, it forces a TCP query, rather than requiring the resolver library to do so (avoiding an extra round-trip between qmail and the name server, though if they're on the same machine or local network this is not a big worry).

5.10.2. qmail-ldap

This patch, by Andre Oppermann, et al, implements Lightweight Directory Access Protocol (LDAP) support in qmail. LDAP is like a network phone book. Using qmail-ldap, it should be possible for a POP server to serve many thousands of users. See http://www.nrg4u.com/.

5.11. QMTP

QMTP is the Quick Mail Transfer Protocol, an SMTP replacement protocol designed by Dan Bernstein. The protocol is defined at http://cr.yp.to/proto/qmtp.txt. QMTP is similar to SMTP, but is simpler, faster, and incompatible with SMTP. qmail includes a QMTP server, qmail-qmtp, which is run very much like qmail-smtp. QMTP usually uses port 209.

qmail doesn't include a QMTP client, but the serialmail package does. maildir2qmtp takes a maildir mailbox and delivers the messages it contains to designated QMTP server via QMTP.

QMTP is not a drop-in replacement for SMTP, and is not yet in widespread use across the Internet.


A. Acknowledgments

First, thanks to Dan Bernstein for designing and writing such a powerful and elegant system. After four years of use, qmail still impresses me.

I'd also like to thank the members of the qmail mailing list. Russell Nelson deserves special mention as one of the most helpful, patient, knowledgeable, and funny contributors. His contributions to the qmail community are second only to DJB's.

Thanks also to everyone who reviewed or contributed to this document, including:

Life with qmail was written using Simple Document Format (SDF), a very cool Perl-based markup language that generates HTML, plain text, PostScript, POD, and other formats. It made the job much easier. See http://www.mincom.com/mtr/sdf/ for more information.


B. Related Packages

B.1. dot-forward

Sendmail uses .forward files, pronounced dot forward, to allow users to control the delivery of messages they receive. qmail uses a similar mechanism: .qmail files. The dot-forward package gives qmail the ability to use .forward files. Systems running Sendmail or any other MTA that uses .forward files might want to consider using dot-forward to avoid having to convert existing .forward files to their .qmail equivalents--or simply to make the transition to qmail less visible to their users.

dot-forward is a small package: easy to install and configure. The source is available from ftp://cr.yp.to/software/dot-forward-0.71.tar.gz.

dot-forward was written by Dan Bernstein, who maintains a web page for it at http://cr.yp.to/dot-forward.html.

B.2. fastforward

fastforward is another Sendmail compatibility add-on. Sendmail uses a central alias database kept in a single file, usually /etc/aliases. qmail uses a series of dot-qmail files in /var/qmail/alias, one file per alias. If you're migrating to qmail, and you've got a Sendmail-format aliases file you don't want to convert, fastforward gives qmail the ability to use the aliases file as-is.

The source is available from ftp://cr.yp.to/software/fastforward-0.51.tar.gz.

fastforward was written by Dan Bernstein, who maintains a web page for it at http://cr.yp.to/fastforward.html.

B.3. ucspi-tcp

qmail's SMTP server doesn't run as a stand alone daemon. A helper program such as inetd, xinetd, or tcpserver runs as a daemon. When it receives a TCP connection to port 25, the SMTP port, it executes a copy of qmail-smtpd.

Inetd is the standard network server "super-server". It can be configured through /etc/inetd.conf to run qmail-smtpd, but the recommended tool is tcpserver, which is part of the ucspi-tcp package. ucspi-tcp is an acronym for UNIX Client-Server Program Interface for TCP, and it's pronounced ooks-pie tee see pee.

tcpserver is preferred over inetd because:

The source is available from ftp://cr.yp.to/ucspi-tcp/ucspi-tcp-0.88.tar.gz.

ucspi-tcp was written by Dan Bernstein, who maintains a web page for it at http://cr.yp.to/ucspi-tcp.html.

B.4. daemontools

The daemontools package contains a set of utilities for controlling and monitoring services. It's not mandatory, but it's highly recommended, especially for busy systems. It includes:

The source for daemontools is available from: http://cr.yp.to/daemontools/daemontools-0.70.tar.gz.

daemontools was written by Dan Bernstein, who maintains a web page for it at http://cr.yp.to/daemontools.html.

B.5. qmailanalog

qmailanalog processes qmail's log file and produces a series of reports that tell one how much and what kind of work the system is doing. If you need statistics about how many messages are being sent or received, how big they are, and how quickly they're being processed, qmailanalog is what you need.

As a bonus, the matchup program combines qmail's multiple log lines per delivery into one--not unlike the familiar Sendmail logs.

The source for qmailanalog is available from http://cr.yp.to/software/qmailanalog-0.70.tar.gz.

qmailanalog was written by Dan Bernstein, who maintains a web page for it at http://cr.yp.to/qmailanalog.html.


Note: qmailanalog relies on log entry timestamps in the fractional second format used by accustamp. In order to use it with logs generated by multilog, which are in TAI64N format, you'll need to translate them into the old format. One program to do that is available from http://www.qmail.org/tai64nfrac.

B.6. rblsmtpd

If you've never been spammed, consider yourself very lucky. Most e-mail users are all to familiar with Unsolicited Bulk E-mail (UBE), aka "spam". Most of it is advertisements for sex sites, chain letters, and other scams. Back in the days of old, up until around 1998 or so, most MTA's on the Internet were open relays, i.e., they would accept mail from anyone for anyone, even if neither sender nor recipient was local. Spammers use open relays, if they can find any, to deliver their spam. It covers their tracks, redirects the backlash toward the "innocent" relay site, and saves them lots of CPU time and network bandwidth.

Such open relays are considered very bad form these days, and several anti-spam vigilante groups have created a mechanism for identifying open relays and other common sources of spam so they can avoid accepting SMTP connections from them. These include the Realtime Blackhole List (RBL), ORBS (Open Relay Behavior-modification System), and DUL (Dial-up User List).

rblsmtpd is an RBL SMTP Daemon. It sits between tcpserver and qmail-smtpd and rejects connections from systems identified on one of these lists.

For example, to run rblsmtpd under tcpserver, try something like:

    #!/bin/sh
    QMAILDUID=`id -u qmaild`
    NOFILESGID=`id -g qmaild`
    MAXSMTPD=`cat /var/qmail/control/concurrencyincoming`
    exec /usr/local/bin/softlimit -m 2000000 \
    /usr/local/bin/tcpserver -v -p -x /etc/tcp.smtp.cdb -c "$MAXSMTPD" \
        -u $QMAILDUID -g $NOFILESGID 0 smtp /var/qmail/bin/rblsmtpd\
        /var/qmail/bin/qmail-smtpd 2>&1

rblsmtpd was previously available as a separate utility, but is now bundled with ucspi-tcp.

rblsmtpd was written by Dan Bernstein, who maintains a web page for it at http://cr.yp.to/ucspi-tcp/rblsmtpd.html.

B.7. serialmail

qmail was designed for systems with full time, high speed connectivity. serialmail is a set of tools that make qmail better suited to intermittent, low speed connectivity. With serialmail on such a system, qmail is configured to deliver all remote mail to a single maildir. The serialmail maildir2smtp command is used to upload the maildir to the ISP's mail hub when the connection is brought up. If the ISP supports QMTP (see QMTP under Advanced Topics), maildir2qmtp can also be used.

serialmail can be used on the ISP side of the connection to implement AutoTURN: an SMTP connection by a client causes the server to initiate a connection back to the client for sending messages queued on the server for the client. This is similar to the ETRN SMTP function.

The source for serialmail is available from http://cr.yp.to/software/serialmail-0.75.tar.gz.

serialmail was written by Dan Bernstein, who maintains a web page for it at http://cr.yp.to/serialmail.html.

B.8. mess822

mess822 is a library and set of applications for parsing RFC 822 compliant mail messages. The applications include: