http:// / scripts /

qmail Scripts

I do lots of scripts... scripts rock.

Major scripts

These scripts are documented on pages of their own.

Service Control Scripts

I run qmail under daemontools on all of my systems. Because the qmail that I run has an entire collection of patches applied to it, and because I run several different SMTP services on the same machine, I need a more customizable set of "run" scripts to start the services, especially the SMTP services.

I have found "run" scripts for qmail on other web sites, and while the ones on Life with qmail come close, they aren't clear enough or customizable enough for my needs.


The qmail-send process is the queue manager for a qmail system. It looks at each new message added to the queue and decides whether the message should be handled locally or sent to a remote server, and updates the queue's status files to reflect that choice. It also triggers local and remote deliveries as needed, including retrying unsuccessful deliveries.

Many people, myself included, call this "/service/qmail-send", although it can have any name you want. Whatever name you give it, the run script is fairly simple.

File: service-qmail-send-run
Size: 1,503 bytes
MD5: f601fa8129bcfaf38e1f5c8f0eca6111
SHA-1: ad7bcbb601ed260d7a8917d7864013963908bddc
RIPEMD-160: df57aedda45ea3d03e741753912a8d9524f1b119
PGP Signature: service-qmail-send-run.asc

SMTP service

I am in the process of re-organizing the script, and am making a separate web page which documents all of the options. The page isn't finished yet, but it already contains a LOT more information than you will find here.

courier-imap services

I already have a web page which tells how to run courier-imap services under daemontools. These are simply download links for the "run" scripts needed for each service. Note that the courier-imap services can use the same "log" script as the qmail services (listed below.)

2008-05-08 I've added a line at the end of the script which makes it log the final command line just before exec'ing it, just as I did with the SMTP service script.

File: service-imap-run
Size: 1,792 bytes
Date: 2008-05-08 16:58:41 +0000
MD5: 4dda3b3a40881855744858623b02f6fb
SHA-1: 366f7ed15754acd1b2c5185b2066cf09d6ed5e7c
RIPEMD-160: eeb48a620221f774e83c9c0727e69c20f537a529
PGP Signature: service-imap-run.asc
File: service-imapssl-run
Size: 2,009 bytes
Date: 2008-05-08 17:02:32 +0000
MD5: d9a7b90bafa3187c039ca66e67498c86
SHA-1: 3ec0571daa4fbd6c151f751e6f13beabaff6eda5
RIPEMD-160: 6aa5b85821cd1574b33fc3a01a3e8e7709946d10
PGP Signature: service-imapssl-run.asc
File: service-pop3-run
Size: 1,784 bytes
Date: 2008-05-08 17:03:41 +0000
MD5: e5da55c2f06f08f9a23d9cb87e115e87
SHA-1: e9eaeeba8e5b3cd70cb8b6e3ddced6e9f6f3f9d6
RIPEMD-160: a6ce7f5e5d9a49e0f41023cbe92450a6d2c9eaef
PGP Signature: service-pop3-run.asc
File: service-pop3ssl-run
Size: 1,884 bytes
Date: 2008-05-08 17:05:05 +0000
MD5: 5353b0588f23c6e8e4428ff4d521bdf6
SHA-1: 7fb84291b57695c58929b77c9e8dba5fb17f049f
RIPEMD-160: 38daf9946610864ae2e36bd11d39471e6f0f8ccf
PGP Signature: service-pop3ssl-run.asc

Logging services

service-any-log-run is a generic "run" script for any logging service managed by daemontools. When you create a service, you should also create a log service with it- otherwise your logs will disappear without a trace.

This script sets the auto-rotation parameters so that each log file is allowed to grow to 1MB, and the program is allowed to keep up to 1024 old log files laying around. These changes were made for a high-volume server at an ISP, and I use it everywhere because it doesn't really hurt anything (as long as the logs are rotated out of the way regularly, keep reading...) djb's multilog instructions explain how to change these numbers, and I have written a page which explains more detail about how daemontools log files work.

File: service-any-log-run
Size: 1,845 bytes
Date: 2006-08-11 22:48:48 +0000
MD5: 54a2d0a1d1ec77e7c737f5b65a9d876a
SHA-1: f7d6e683bcba52ebc3d8104201d43c49e2e64c94
RIPEMD-160: 501241a75dbe44121921582a10662ef926ffa32f
PGP Signature: service-any-log-run.asc

And speaking of rotating logs out of the way, I have written a program called convert-multilog which finds the log files created by multilog, converts their timestamps to a human-readable format, and adds them to log files in "/var/log" whose filenames are the service plus the date (i.e. all "/service/qmail-send/log/main/@*" files are combined into /var/log/qmail-send.YYYY-MM-DD.)

2007-08-14 Received a bug report. If an input file starts with a line which is all whitespace, no output file is opened. Changed the logic so that, unless multilog starts spitting out NUL bytes (which I don't think it can, since it's written in C) an output file will still be created, even if the name is a bit strange. Thanks to John Coryat for letting me know about the problem.

2007-09-04 Added the @exclude array, which holds the names of any services for which you may not want the logs to be rotated. Note that if you wish to exclude "/service/blah", the word in this array should just be "blah". Thanks to Patrick "marlowe" McDonald for the idea.

2009-11-15 Receieve a bug report. Apparently, the output from tai64nlocal doesn't always start with YYYY-MM-DD. I'm not sure what causes it, but I suspect it's embedded CR characters within the raw log lines sent to multilog. If the script sees a line like this, it will assume that the line is a continuation of the previous line, and just write it to whatever output file is currently open. If there is no output file (i.e. if the log file starts with a mis-formed line) then that line will be discarded.

2012-08-24 Found a bug on my own. Apparently it wasn't parsing the output from tai64nlocal correctly, and the copy on the web site wasn't working.

File: convert-multilog
Size: 6,016 bytes
Date: 2012-08-25 03:13:19 +0000
MD5: 04e4469aac72d5bc00d0aee16fd427d3
SHA-1: 726dcdd19247afc14cf854451f8295a51be848ad
RIPEMD-160: 4b1988211e739decfdf6f2b4f1e4477886a32f90
PGP Signature: convert-multilog.asc

courierpassd service

service-courierpassd-run is a "run" script which runs the courierpassd program on localhost port 106. This program is used on some systems to allow users to change their passwords from a webmail interface. This page explains in more detail.

File: service-courierpassd-run
Size: 1,248 bytes
MD5: bd834c276a2426dacff0d6ad86aea2c8
SHA-1: be2439084497ac36f178c5933f7385dba1727520
RIPEMD-160: 92dc8a4979ec6704b80014ce92df9d4aef4a46aa
PGP Signature: service-courierpassd-run.asc

vpopmaild service

service-vpopmaild-run is a "run" script for a vpopmaild service. vpopmaild is a server which allows properly authorized clients to perform most of the actions you can do with the vpopmail command line tools. A very simple use of such a service might be to support the SMTP AUTH command (which is something I plan to write a patch for, but haven't done yet.)

2012-07-19 Changing the service to run as the vpopmail user, and use port 8900.

File: service-vpopmaild-run
Size: 1,219 bytes
Date: 2012-07-19 22:05:06 +0000
MD5: 70a65a2cae67600c7723cb3dfe7ae2b6
SHA-1: ecb64df7003620090ffe48ab3175bb202eed67b5
RIPEMD-160: 1d4677e8eb7bb9a1694c193cd69cbb2114d028f6
PGP Signature: service-vpopmaild-run.asc

courierauthd service

service-courierauthd-run is a "run" script for a courierauthd service. courierauthd is a program I wrote to support the subset of vpopmaild's functions which are necessary to support the SMTP AUTH command (i.e. the login, quit, and help commands.) The idea is that this allows the (as yet un-written) SMTP AUTH patch for vpopmaild to be useful to people who may not be using vpopmail, but who are using courier-authlib (since courier-authlib can be used with any number of authentication methods.)

File: service-courierauthd-run
Size: 1,167 bytes
MD5: 9d3bfaf9b07b5ba691fa7a02acdf0e7f
SHA-1: dce2424889f18fa243e16fff8d0a1610bd1bb205
RIPEMD-160: 448d3ef32295b9b194468cd2ba0ed7e5afebb4b2
PGP Signature: service-courierauthd-run.asc

I originally used a shell script called cron.qmail to update my validrcptto.cdb file, and send a HUP to qmail-send when needed, and I relied on cron to run it periodically. However, on some systems cron doesn't always work correctly, so I wrote a perl script called qmail-updater which ran all the time and kept the files up to date. (Note that neither of these scripts is being updated. You are welcome to use them, but they will not be kept "up to date" when I come up with new features.)

File: cron.qmail
Size: 3,616 bytes
MD5: 711fb88618a83cd1a3db1dd8c1955696
SHA-1: dfa31ef6d37ed64cfb41444f5c959d09ad438206
RIPEMD-160: ab59717034677ee3d2009a2b38c8800a49ceff0d
PGP Signature: cron.qmail.asc
File: qmail-updater
Size: 6,392 bytes
MD5: 1a1bfa2d32a0840efe897e966556383e
SHA-1: 0a9bf1de178461e47b0dfd77c83bff8c157ff769
RIPEMD-160: bcf6179cf97d26276a692877a2e56e6f410c527c
PGP Signature: qmail-updater.asc

Secure qmail-pop3d service

I don't use the POP3 server which comes with qmail. To me it always seemed easier to use the POP3 server which came with courier-imap, and then later with dovecot. However, people still seem to be asking how to set it up to run under daemontools.

At one point, Niamh Holding sent a sample of a qmail-pop3d "run" script to the mailing list. I took her example, added a few comments, and made it a bit easier to configure. So here's an example of what the "run" script for a qmail-pop3d service should look like.

Note that I have not personally tested this myself, so if anybody does try it, please let me know if it works or not, and what problems (if any) you ran into while getting it to work.

#!/bin/sh # any script running as root should always specify its own PATH PATH="/var/qmail/bin:/usr/bin:/bin" # basic configuration IP="" # IP on which to listen PORT="995" # TCP port number, 995 is standard LOCAL="" # your local hostname CHECKPW="/bin/checkpassword" # checkpassword program to verify ID/PW # for vpopmail this would be "vchkpw" # SSL stuff (exported so sslserver can use it) export CERTFILE="/var/qmail/control/servercert.pem" export KEYFILE="" export DHFILE="" # do the deed exec sslserver -e -vRH -l $LOCAL $IP $PORT \ qmail-popup $LOCAL $CHECKPW qmail-pop3d Maildir 2>&1

You may notice that there are no "-u" or "-g" options for sslserver, as there would normally be for other services. This is because in order for it to work, a "checkpassword" program needs to start as root. It executes the "setuid()" function before exec()'ing the qmail-pop3d program (which actually works with the user's mailbox.) If qmail-popup were to run as a non-root user, and the owner of the mailbox happens to be some other user, then the checkpassword program wouldn't be able to setuid() to that other user, and therefore the mailbox wouldn't be accessible through the service.

Other Scripts

Over the past several years of building, running, and consulting for ISPs I have written and/or found a collection of scripts which have proven useful when working with qmail servers. They are presented below, in more-or-less alphabetical order.

Note: Any scripts listed below with a red background are dangerous. Make sure you read the directions for these scripts before running them, and understand what they do and when it's safe to use them.