Qmail is a very compartmentalized program. Its broken down into multiple tiny programs that govern a very specific piece of the MTA process. This guide documents how Qmail handles email in a nutshell.
Messages can enter the mail server in one of 2 ways, either the message came from a remote mailserver like hotmail.com, or the message is being sent from the local server (ie. imap, webmail, mail functions, etc) The 2 daemons that are responsible for this are:
1. qmail-smtpd –> handles mail coming from an outside mail server. ie. hotmail.com
2. qmail-inject –> handles any messages generated locally by the server. ie. imap, webmail, or php mail functions, etc. This service injects the messages directly into the mail queue.
The primary objective of qmail-smtpd and qmail-inject is to pass the message along to qmail-queue.
3. qmail-queue –> This is a complicated program. This writes all the messages to the central queue directory: /var/qmail/queue/. The qmail-queue program can be invoked by qmail-inject for locally generated messages, qmail-smtpd for messages received through SMTP, qmail-local for forwarded messages, or qmail-send for bounced messages. If this is confusing, just remember that this is the program that acually writes the messages to the mail queue. Now, if you are curious like me and want to know the nitty gritty, here it is. /var/qmail/queue is comprised of 5 directories. pid/, mess/, intd/, todo/, info/, and remote/.
Below is a diagram that shows how the message gets handled by qmail-queue during the various message “stages”. Next to each folder I also noted which program controls the message at that particular point in time.
pid/111 -- (S1) # qmail-queue \_ mess/111 (S2) # qmail-queue | | _ intd/111 (S3) # qmail-queue / todo/111 -- (S4) # qmail-queue | | info/111 -- local/111 (S4 - S5) # qmail-send | | remote/111 (S4 - S5) # qmail-send Key: # qmail-send --> responsible for this part of queue # qmail-queue --> responsible for this part of queue S1 --> -mess -intd -todo -info -local -remote -bounce S2 --> +mess -intd -todo -info -local -remote -bounce S3 --> +mess +intd -todo -info -local -remote -bounce S4 --> +mess ?intd +todo ?info ?local ?remote -bounce (queued) S5 --> +mess -intd -todo +info ?local ?remote ?bounce (preprocessed) Here are all possible states for a message. + means a file exists; - means it does not exist; ? means it may or may not exist in that folder
It is also well documented in the qmail src file called INTERNALS which explains it better than I can!
Short and sweet overview of qmail-queue: It is responsible for writing the message to the queue.
4. qmail-send –> This takes the message from qmail-queue and passes the message either to qmail-rspawn (for remote delivery) or it sends the message to qmail-lspawn (for local delivery)
5a. qmail-rspawn (remote delivery) –> This sends the message to the remote mail server (ie. yahoo.com)
– qmail-remote –> This transmits the message to the remote mail server.
5b. qmail-lspawn (local delivery) –> This sends the message for local delivery.
– qmail-local –> This passes the message off to a local delivery agent. It reads the users .qmail-default first, which basically just tells qmail-local that vdelivermail is going to handle delivery.
– vdelivermail -> This delivers the mail to the local users. It locates the users Maildir and passes the message off to preline. (preline passes teh mail to other filters or commands) In the users maildir, search for a .qmail file that relates to the user and cat the file. If a cat .qmail-USERNAME doesn’t exist, then it defaults to .qmail-default, which tells it to send the message to procmail.
– procmail -> Procmail performs the mail filtering and local delivery to the mailbox. In procmail, this is where you can send the message to spamassassin or another filtering agent for processing before delivery.
– spamassassin -> Spam filtering. Take special note of the spamassassin versions and permissions, and the spamd vs spamc methods.
Below are qmail’s configuration files, found within /var/qmail/control:
Control file Purpose badmailfrom blacklisted From addresses bouncefrom username of bounce sender bouncehost hostname of bounce sender concurrencyincoming max simultaneous incoming SMTP connections concurrencylocal max simultaneous local deliveries concurrencyremote max simultaneous remote deliveries defaultdomain domain name defaulthost host name databytes max number of bytes in message (0=no limit) doublebouncehost host name of double bounce sender doublebounceto user to receive double bounces locals domains that we deliver locally morercpthosts secondary rcpthosts database queuelifetime seconds a message can remain in queue rcpthosts domains that we accept mail for smtproutes artificial SMTP routes timeoutconnect how long, in seconds, to wait for SMTP connection timeoutremote how long, in seconds, to wait for remote server timeoutsmtpd how long, in seconds, to wait for SMTP client virtualdomains virtual domains and users