Apache Awk Bash C cftp daemontools DHCP djbdns DNS Emacs Email ezmlm Fetchmail find GDB Hardware HTML HTTP Intro ISDN less Make Math mc mirrordir MySQL Peripherals Perl PHP3 pppd qmail Regexps Shell System Tables test To do Typical ucspi-tcp Versions Index TCP/IP slides

How to recreate the trigger pipe

Qmail requires a pipe, named /var/qmail/queue/lock/trigger, with the correct permissions. If absent or with the wrong permissions, qmail does not detect new mail in a fast way. The pipe must have 0622 permissions ( thus showing up as prw--w--w- in ls -l ), and ownership qmails.qmail. To recreate the pipe, use the commands:

rm -f /var/qmail/queue/lock/trigger
mkfifo -m 0622 /var/qmail/queue/lock/trigger
chown qmails.qmail /var/qmail/queue/lock/trigger

It's a good idea to restart qmail after this.


How to clean the outbound queue

The only safe operation that can be done over the queued messages is to change the date. Therefore, one way to clean the message queue is to touch the messages to a timestamp that makes qmail think that they have been too long in the queue, and bounce them. This can be done as follows:

find /var/qmail/queue -type f -name '[0-9]*' -exec touch -d 19900101 '{}' ';'

Then, manually run the queue, as per instructions below. This line can be made into a shell script, of course.


How to define a upstream SMTP server

cp /var/qmail/control/me /var/qmail/control/helohost
echo :smtp.server > /var/qmail/control/smtproutes
/etc/init.d/qmail restart

(replace smtp.server by ISP's SMTP server)


How to forward messages

To forward messages for a specific user, eg. to other@somewhere.com, edit the user's ~/.qmail file, and add:

&other@somewhere.com

How to forward unrecognized user names

To forward unrecognized user names to another host (eg. turkopolis.com), edit ~alias/.qmail-default and add:

| /var/qmail/bin/forward "$LOCAL@turkopolis.com"

How to manually run the mail queue

Send an ALRM to the qmail-send process, as mentioned below.


How to check the queue contents

Use qmail-qread. It scans the outgoing queue, printing information for each message waiting for being sent.


.qmail

The qmail system follows delivery instructions based on the user's .qmail file.

Note that the name .qmail may be followed by dash separated sub-addressing. For example, given the user someone at someserver.com, the file ~someone/.qmail controls delivery for the address someone@someserver.com; the file ~someone/.qmail-logs controls delivery for the address someone-logs@someserver.com; a file ~someone/.qmail-default controls delivery for any address in the form someone-xxxx@someserver.com, that is, default acts as a wildcard.

Within a .qmail file, each line starts by a character that is a command, and the following commands are interpreted:

.qmail commands
prefix example meaning
# # this is a comment Comment: the line is ignored
| | /var/qmail/bin/forward "$LOCAL@turkopolis.com" Program: the given command is called, with a number of environment variables, and the message is delivered trough the program's stdin. See below for the environment settings
& &otherguy@otherplace.com Forwarding: the message is forwarded to the given address
/xxxxx
.xxxxx
/home/guy/mailbox Mailbox: the line defines the mailbox style file where the message should end up. Note that the line does not end in a slash. The line may start by a dot (in which case the address is taken relative to the .qmail file's location), or by a slash, in which case it is a absolute pathname
/xxxxx/
.xxxxx/
./Maildir/ Maildir: the line defines the maildir style directory where the message should end up. Note that the line ends with a slash. The starting dot or slash have the same meaning as in the Mailbox line

For the "Program" commands (the ones starting with a pipe), the message is fed trough stdin, and the return code of the program has the following meaning:

.qmail pipe error codes
code meaning
0 Delivery successful
99 Delivery successful, but the rest of the .qmail file should be ignored
100 Delivery failed permanently (hard error)
111 Delivery failed temporarily (soft error)

For the "Program" commands, the following environment variables are made available

.qmail pipe environment variables
variable contents
$SENDER Envelope sender address
$NEWSENDER Forwarding envelope sender address
$RECIPIENT Envelope recipient address (local@domain)
$USER The user
$HOME The home directory
$HOST The domain part of the recipient address
$HOST2 The portion of $HOST preceding the last dot
$HOST3 The portion of $HOST preceding the second-to-last dot
$HOST4 The portion of $HOST preceding the third-to-last dot
$LOCAL The local part of the recipient address
$EXT The address extension
$EXT2 The portion of $EXT following the first dash
$EXT3 The portion of $EXT following the second dash
$EXT4 The portion of $EXT following the third dash
$DEFAULT The portion corresponding to the default part of the .qmail-... filename
This is not set if the .qmail-... does not end in default
$DTLINE The Delivered-To: line, including newline
$RPLINE The Return-Path: line, including newline
$UFLINE The UUCP style From_ added to the mbox-format files

The qmail data flow

qmail data flow diagram

qmail-inject and qmail-smtpd send their output directly to qmail-queue, which places the messages in the output queue.

qmail-send scans the queue, locating messages that are to be sent. Messages are sent to qmail-lspawn if they are destined to the local host, or to qmail-rspawn if they are destined to a remote host.

qmail-lspawn passes the messages to be delivered locally to qmail-local, which places them in the appropriate maildir.

qmail-rspawn passes the messages to be delivered remotely to qmail-remote, which calls the remote hosts SMTP server.

qmail-clean is then called from qmail-send to clean the queue of messages already sent, or that have aged past queuelifetime.


qmail queue structure

Subdirectory of /var/qmail/queue Contents
bounce Permanent delivery errors
info/* Envelope sender address, after preprocessing
intd Envelope under construction by qmail-queue
local/* Local envelope recipient addresses, after preprocessing
lock Lock files
mess/* The message
pid Used by qmail-queue to get a PID from which a i-node number is obtained
remote/* Remote envelope recipient addresses, after preprocessing
todo Envelopes, from where the message came, where it is going

Control files

The qmail system is controlled by control files, as follows

qmail control files
control file default used by
badmailfrom (none) qmail-smtpd
bouncefrom MAILER-DAEMON qmail-send
bouncehost me qmail-send
concurrencylocal 10 qmail-send
concurrencyremote 20 qmail-send
defaultdomain me qmail-inject
defaulthost me qmail-inject
databytes 0 qmail-smtpd
doublebouncehost me qmail-send
doublebounceto postmaster qmail-send
envnoathost me qmail-send
helohost me qmail-remote
idhost me qmail-inject
localiphost me qmail-smtpd
locals me qmail-send
control file default used by
morercpthosts (none) qmail-smtpd
percenthack (none) qmail-send
plusdomain me qmail-inject
qmqpservers (none) qmail-qmqpc
queuelifetime 604800 seconds
(7 days)
qmail-send
rcpthosts (none) qmail-smtpd
smtpgreeting me qmail-smtpd
smtproutes (none) qmail-remote
timeoutconnect 60 seconds qmail-remote
timeoutremote 1200 seconds
(20 minutes)
qmail-remote
timeoutsmtpd 1200 seconds
(20 minutes)
qmail-smtpd
virtualdomains (none) qmail-send

Environment variables cross-reference and description

Variable Description Produced by Used by
$DATABYTES Overrides databytes, maximum number of bytes (as stored in disk) that a message is allowed, 0 if no limit   qmail-smtpd
$DEFAULT The portion corresponding to the default part of the .qmail-... filename, not set if the .qmail-... does not end in default qmail-local pipe environment in .qmail
$DTLINE The Delivered-To: line, including newline qmail-local pipe environment in .qmail
$EXT2 The portion of $EXT following the first dash qmail-local pipe environment in .qmail
$EXT3 The portion of $EXT following the second dash qmail-local pipe environment in .qmail
$EXT4 The portion of $EXT following the third dash qmail-local pipe environment in .qmail
$EXT The address extension qmail-local pipe environment in .qmail
$HOME The destination home directory qmail-local pipe environment in .qmail
$HOST2 The portion of $HOST preceding the last dot qmail-local pipe environment in .qmail
$HOST3 The portion of $HOST preceding the second-to-last dot qmail-local pipe environment in .qmail
$HOST4 The portion of $HOST preceding the third-to-last dot qmail-local pipe environment in .qmail
$HOST The domain part of the recipient address qmail-local pipe environment in .qmail
$LOCAL The local part of the recipient address qmail-local pipe environment in .qmail
$NEWSENDER Forwarding envelope sender address qmail-local pipe environment in .qmail
$PROTO The string "TCP" tcp-env
tcpclient
tcpserver
qmail-smtpd
$QMAILDEFAULTDOMAIN Overrides defaultdomain, added to any host name without dots   qmail-inject
$QMAILDEFAULTHOST Overrides defaulthost, added to any address without host name   qmail-inject
$QMAILIDHOST Overrides idhost, host name for message IDs   qmail-inject
$QMAILPLUSDOMAIN Overrides plusdomain, added to any host name ending in a plus sign   qmail-inject
$RECIPIENT Envelope recipient address (local@domain) qmail-local pipe environment in .qmail
$RELAYCLIENT Overrides rcpthosts, allows relayed message trough and is appended to the incoming recipient address   qmail-smtpd
$RPLINE The Return-Path: line, including newline qmail-local pipe environment in .qmail
$SENDER Envelope sender address qmail-local pipe environment in .qmail
$TCPLOCALHOST The domain name of the local host, with uppercase letters converted to lowercase. If there is no currently available domain name for the local IP address, TCPLOCALHOST is not set. Can contain arbitrary characters tcp-env
tcpclient
tcpserver
qmail-smtpd
$TCPLOCALIP The IP address of the local host, in dotted-decimal form tcp-env
tcpclient
tcpserver
qmail-smtpd
$TCPLOCALPORT The local TCP port number, in decimal tcp-env
tcpclient
tcpserver
qmail-smtpd
$TCPREMOTEHOST The domain name of the remote host, with uppercase letters converted to lowercase. If there is no currently available domain name for the remote IP address, TCPREMOTEHOST is not set. Can contain arbitrary characters tcp-env
tcpclient
tcpserver
qmail-smtpd
$TCPREMOTEINFO A connection-specific string, perhaps a username, supplied by the remote host via 931/1413/IDENT/TAP. If the remote host did not supply connection information, TCPREMOTEINFO is not set. Can contain arbitrary characters tcp-env
tcpclient
tcpserver
qmail-smtpd
$TCPREMOTEIP The IP address of the remote host tcp-env
tcpclient
tcpserver
qmail-smtpd
$TCPREMOTEPORT The remote TCP port number tcp-env
tcpclient
tcpserver
qmail-smtpd
$UFLINE The UUCP style From_ added to the mbox-format files qmail-local pipe environment in .qmail
$USER The user qmail-local pipe environment in .qmail

qmail-send

qmail-send handles messages placed into the outgoing queue by qmail-queue. It uses qmail-lspawn to deliver messages to local recipients and qmail-rspawn to deliver messages to remote recipients. If a message is temporarily undeliverable to one or more addresses, qmail-send leaves it in the queue and tries the addresses again later.

If qmail-send receives an ALRM signal, it will reschedule every message in the queue for immediate delivery.

qmail-send reads its control files only when it starts. If you change the control files, you must stop and restart qmail-send. Exception: If qmail-send receives a HUP signal, it will reread locals and virtualdomains.

qmail-send control files
bouncefrom Bounce username.
Default: MAILER-DAEMON
bouncehost Bounce host. If a message is permanently undeliverable, qmail-send sends a single-bounce notice back to the message's envelope sender. The notice is From: bouncefrom@bouncehost, although its envelope sender is empty.
Default: me
If not supplied the literal name bouncehost, which is probably not what you want.
concurrencylocal Maximum number of simultaneous local delivery attempts.
Default: 10
If 0, local deliveries will be put on hold. concurrencylocal is limited at compile time to 120 (unless conf-spawn if changed).
concurrencyremote Maximum number of simultaneous remote delivery attempts.
Default: 20
If 0, remote deliveries will be put on hold. concurrencyremote is limited at compile time to 120 (unless conf-spawn if changed).
doublebouncehost Double-bounce host.
Default: me
If not supplied the literal name doublebouncehost, which is probably not what you want.
doublebounceto User to receive double-bounces.
Default: postmaster
If a single-bounce notice is permanently undeliverable, qmail-send sends a double-bounce notice to doublebounceto@doublebouncehost. (If that bounces, qmail-send gives up.)
envnoathost Presumed domain name for addresses without @ signs.
Default: me
If not supplied the literal name envnoathost, which is probably not what you want. If qmail-send sees an envelope recipient address without an @ sign, it appends @envnoathost.
locals List of domain names that the current host receives mail for, one per line.
Default: me
If not supplied qmail-send refuses to run. An address user@domain is considered local if domain is listed in locals.
percenthack List of domain names where the percent hack is applied. If domain is listed in percenthack, any address of the form user%fqdn@domain is rewritten as user@fqdn.
user may contain %, so the percent hack may be applied repeatedly. qmail-send handles percenthack before locals.
queuelifetime Number of seconds a message can stay in the queue.
Default: 604800 (one week)
After this time expires, qmail-send will try the message once more, but it will treat any temporary delivery failures as permanent failures.
virtualdomains List of virtual users or domains, one per line. A virtual user has the form user@domain:prepend, without any extra spaces.
When qmail-send sees the recipient address user@domain, it converts it to prepend-user@domain and treats it as local.
A virtual domain has the form domain:prepend. It applies to any recipient address at domain. For example, if
nowhere.mil:joe-foo
is in virtualdomains, and a message arrives for info@nowhere.mil, qmail-send will rewrite the recipient address as joe-foo-info@nowhere.mil and deliver the message locally.
virtualdomains may contain wildcards:
.fax:uucp-fax:alias-catchall.nowhere.mil:joe-foo-host
virtualdomains may also contain exceptions: an empty prepend means that domain is not a virtual domain.
qmail-send handles virtualdomains after locals: if a domain is listed in locals, virtualdomains does not apply.

qmail-inject

qmail-inject reads a mail message from its standard input, adds appropriate information to the message header, and invokes qmail-queue to send the message to one or more recipients.

qmail-inject options
-a Send the message to all addresses given as recip arguments; do not use header recipient addresses.
-h Send the message to all header recipient addresses. For non-forwarded messages, this means the addresses listed under To, Cc, Bcc, Apparently-To. For forwarded messages, this means the addresses listed under Resent-To, Resent-Cc, Resent-Bcc. Do not use any recip arguments.
-A (Default.) Send the message to all addresses given as recip arguments. If no recip arguments are supplied, send the message to all header recipient addresses.
-H Send the message to all header recipient addresses, and to all addresses given as recip arguments.
-fsender Pass sender to qmail-queue as the envelope sender address. This overrides Return-Path and all environment variables.
-N (Default.) Feed the resulting message to qmail-queue.
-n Print the message rather than feeding it to qmail-queue.
qmail-inject control files
defaultdomain Default domain name.
Default: me
If not supplied the literal name defaultdomain, which is probably not what you want.
qmail-inject adds this name to any host name without dots, including defaulthost if defaulthost does not have dots. (Exception: see plusdomain.)
The QMAILDEFAULTDOMAIN environment variable overrides defaultdomain.
defaulthost Default host name.
Default: me
If not supplied the literal name defaulthost, which is probably not what you want.
qmail-inject adds this name to any address without a host name. defaulthost need not be the current host's name. For example, you may prefer that outgoing mail show just your domain name.
The QMAILDEFAULTHOST environment variable overrides defaulthost.
idhost Host name for Message-IDs.
Default: me
If not supplied the literal name idhost, which is certainly not what you want.
idhost need not be the current host's name. For example, you may prefer to use fake host names in Message-IDs. However, idhost must be a fully-qualified name within your domain, and each host in your domain should use a different idhost.
The QMAILIDHOST environment variable overrides idhost.
plusdomain Plus domain name.
Default: me
If not supplied the literal name plusdomain, which is probably not what you want.
qmail-inject adds this name to any host name that ends with a plus sign, including defaulthost if defaulthost ends with a plus sign. If a host name does not have dots but ends with a plus sign, qmail-inject uses plusdomain, not defaultdomain.
The QMAILPLUSDOMAIN environment variable overrides plusdomain.

qmail-remote

qmail-remote reads a mail message from its input and sends the message to one or more recipients at a remote host.

The remote host is qmail-remote's first argument, host. qmail-remote sends the message to host, or to a mail exchanger for host listed in the Domain Name System, via the Simple Mail Transfer Protocol (SMTP). host can be either a fully-qualified domain name:

silverton.berkeley.edu

or an IP address enclosed in brackets:

[128.32.183.163]

The envelope recipient addresses are listed as recip arguments to qmail-remote. The envelope sender address is listed as sender.

qmail-remote control files
helohost Current host name, for use solely in saying hello to the remote SMTP server.
Default: me
If not supplied qmail-remote refuses to run.
smtproutes Artificial SMTP routes.
Each route has the form domain:relay, without any extra spaces.
If domain matches host, qmail-remote will connect to relay, as if host had relay as its only MX. (It will also avoid doing any CNAME lookups on recip.) host may include a colon and a port number to use instead of the normal SMTP port, 25:
inside.af.mil:firewall.af.mil:26
relay may be empty; this tells qmail-remote to look up MX records as usual. smtproutes may include wildcards:
.af.mil::heaven.af.mil
Here any address ending with .af.mil (but not af.mil itself) is routed by its MX records; any other address is artificially routed to heaven.af.mil.
The qmail system does not protect you if you create an artificial mail loop between machines. However, you are always safe using smtproutes if you do not accept mail from the network.
timeoutconnect Number of seconds qmail-remote will wait for the remote SMTP server to accept a connection.
Default: 60
The kernel normally imposes a 75-second upper limit.
timeoutremote Number of seconds qmail-remote will wait for each response from the remote SMTP server.
Default: 1200
qmail-remote returns a number of report strings, 0 terminated, and started by a code letter, as follows:
Code letter Type of report Meaning
r Recipient Acceptance
h Recipient Permanent rejection
s Recipient Temporary rejection
K Message Success, destination host has taken responsibility for delivering the mail to the recipients
Z Message Temporary failure
D Message Permanent failure

qmail-qmqpc

qmail-qmqpc offers the same interface as qmail-queue, but it gives the message to a QMQP server instead of storing it locally.

qmail-qmqpc control files
qmqpservers IP addresses of QMQP servers, one address per line. qmail-qmqpc will try each address in turn until it establishes a QMQP connection or runs out of addresses.

qmail-smtpd

qmail-smtpd receives mail messages via the Simple Mail Transfer Protocol (SMTP) and invokes qmail-queue to deposit them into the outgoing queue. qmail-smtpd must be supplied several environment variables; see tcp-environ(5).

qmail-smtpd is responsible for counting hops. It rejects any message with 100 or more Received or Delivered-To header fields.

qmail-smtpd supports ESMTP, including the 8BITMIME and PIPELINING options.

qmail-smtpd control files
badmailfrom Unacceptable envelope sender addresses. qmail-smtpd will reject every recipient address for a message if the envelope sender address is listed in badmailfrom. A line in badmailfrom may be of the form @host, meaning every address at host.
databytes Maximum number of bytes allowed in a message, or 0 for no limit.
Default: 0
If a message exceeds this limit, qmail-smtpd returns a permanent error code to the client; in contrast, if the disk is full or qmail-smtpd hits a resource limit, qmail-smtpd returns a temporary error code.
databytes counts bytes as stored on disk, not as transmitted through the network. It does not count the qmail-smtpd Received line, the qmail-queue Received line, or the envelope.
If the environment variable DATABYTES is set, it overrides databytes.
localiphost Replacement host name for local IP addresses.
Default: me
qmail-smtpd is responsible for recognizing dotted-decimal addresses for the current host. When it sees a recipient address of the form box@[d.d.d.d], where d.d.d.d is a local IP address, it replaces [d.d.d.d] with localiphost. This is done before rcpthosts.
morercpthosts Extra allowed RCPT domains. If rcpthosts and morercpthosts both exist, morercpthosts is effectively appended to rcpthosts.
You must run qmail-newmrh whenever morercpthosts changes.
Rule of thumb for large sites: Put your 50 most commonly used domains into rcpthosts, and the rest into morercpthosts.
rcpthosts Allowed RCPT domains.
If rcpthosts is supplied, qmail-smtpd will reject any envelope recipient address with a domain not listed in rcpthosts.
Exception: If the environment variable RELAYCLIENT is set, qmail-smtpd will ignore rcpthosts, and will append the value of RELAYCLIENT to each incoming recipient address.
rcpthosts may include wildcards:
heaven.af.mil.heaven.af.mil
Envelope recipient addresses without @ signs are always allowed through.
smtpgreeting SMTP greeting message.
Default: me
If not supplied qmail-smtpd will refuse to run. The first word of smtpgreeting should be the current host's name.
timeoutsmtpd Number of seconds qmail-smtpd will wait for each new buffer of data from the remote SMTP client.
Default: 1200

qmail related links

Last update: Wed, 2 Nov 2005 10:16:21 GMT