the djb way


basic services: qmail-send and qmail-smtpd

The two basic components needed to get a qmail service going now are:

qmail is a highly modular system. The qmail queue daemons handle all activities related to monitoring and delivering messages from the queue. Meanwhile the qmail-smtpd daemon receives messages over the network via the SMTP protocol, listening on port 25.

Like other services in the djb way, these qmail services will rely on the daemontools and ucspi-tcp packages to start, run and log. So we will set up two services: one called qmail-send for the qmail queue daemons, and another called qmail-smtpd for the SMTP service.

First, then, the qmail-send service. Make the local service directories in the usual way:

# mkdir -p /var/svc.d/qmail-send/log

Then the daemontools run script for /var/svc.d/qmail-send/run:

# qmail-send/run
exec 2>&1
echo "*** Starting qmail-send..."
echo "*** >> default local delivery to ${DELIVERY}"
exec env -i PATH="/var/qmail/bin:$PATH"\
  qmail-start ${DELIVERY}

### that's all, folks!

Set the file executable with chmod 755.

Here the command qmail-start actually does all the work of firing off all the qmail queue daemons, including qmail-send, qmail-lspawn, qmail-rspawn, and qmail-clean. The qmail-start utility also sets up all the proper uids and gids for these daemons, so we don't need to use any setuidgid commands ourselves.

This script also sets up a $DELIVERY variable, used to provide the default delivery instructions. These instructions are ultimately passed to qmail-local(8) (by qmail-lspawn(8)), and are used for local delivery in the absence of any other instructions from users' dot-qmail(5) files.

The logging service for qmail-send is the familiar multilog setup in /var/svc.d/qmail-send/log/run:

# qmail-send/log/run
exec setuidgid multilog multilog t /var/multilog/qmail-send

Set executable with chmod 755. Then prepare the log directory in /var/multilog:

# mkdir -p /var/multilog/qmail-send
# chown multilog /var/multilog/qmail-send

That takes care of the setup for the qmail queue daemons. Now, on to the qmail-smtpd service.

Again, make the local service directories:

# mkdir -p /var/svc.d/qmail-smtpd/log

Then create the daemontools run script for /var/svc.d/qmail-smtpd/run:

# qmail-smtpd/run

exec 2>&1
echo "*** Starting qmail-smtpd..."
exec \
  envuidgid qmaild \
  softlimit -m 3000000 -f 10000000 \
  tcpserver -v -HR \
  -U \
  -c ${CONLIMIT} \
  -x /etc/tcprules/smtp.cdb \
  0 25 \

### that's all, folks!

Make sure the script is executable, chmod 755. We run the service with the envuidgid utility, using the specific unpriveleged user named "qmaild". This sets up for the -U option to tcpserver, to drop priveleges before running the qmail-smtpd executable.

The softlimit arguments provide some resource control. Note here we use the -f option to limit file size to a maximum of 10 million bytes. Even if you don't use a control/databytes limit, you can put an upper bound on the size of an individual message here.

The tcpserver invocation in this script also uses the -HR options to disable the effort to gather extra data about the remote host. If you would like to try to get the $TCPREMOTEHOST name into your log files, you can use the -h option instead of -H. You can even use the -p option, for paranoid, to verify the $TCPREMOTEHOST lookup. Just know that the use of these options will incur some additional bandwidth for the extra DNS lookups made for each connection.

By the way, while $TCPREMOTEHOST data may be pleasing and useful in the log files, but $TCPREMOTEINFO (with the -r option) is rarely obtained anyway. We stick to the -R option for this script, even if using other options involving -h and -p.

Next comes the usual logger in /var/svc.d/qmail-smtpd/log/run:

# qmail-smtpd/log/run
exec setuidgid multilog multilog t /var/multilog/qmail-smtpd

Set executable with chmod 755. Then prepare the log directory in /var/multilog:

# mkdir -p /var/multilog/qmail-smtpd
# chown multilog /var/multilog/qmail-smtpd

Now determine the tcpserver access rules you may want for your network in /etc/tcprules/smtp.rules:

# smtp.rules

These rules will allow SMTP connections from all hosts. In addition, they set the environmental variable $RELAYCLIENT for hosts connecting from (say) the local network. This allows clients on the local network to use this server as a relay for their outbound mail to any RCPT TO destination. Otherwise, incoming connections are limited to the definitions set up in control/rcpthosts. Finally --just to illustrate the fine-grained access control that is possible-- one host on the local network is allowed a larger $DATABYTES limit than has been set up in control/databytes.

Compile the rules:

# (cd /etc/tcprules; make smtp.cdb)

The qmail services are now ready for action. Before continuing, shutdown and disable any other mail server that may be running on the host. (See the sendmail configuration page for platform-specific instructions.)

Then the dramatic climax:

# ln -s /var/svc.d/qmail-send /service/qmail-send
# ln -s /var/svc.d/qmail-smtpd /service/qmail-smtpd

The qmail services are linked into /service, and daemontools svscan starts them up automatically within five seconds.

No other boot scripts are required. You've got qmail!

Copyright © 2002, 2003, 2004 Wayne Marshall.
All rights reserved.

Last edit 2004.10.04, wcm.