This document is a mirror of the OpenBSD Qmail howto originally located at http://www.sancho2k.net/filemgmt_data/files/qmail.html
This document describes the process for installation and configuration of qmail for a simple SMTP server on OpenBSD. The process described will accomodate basic mail delivery and relaying from trusted hosts. No effort will be made to accomodate mail retrieval through POP3 or IMAP; this requires seperate programs and will not be covered in this HOWTO (although there will be links to information on these subjects later on). qmail is a very powerful and secure MTA and as such, there are far more capable setups possible than described here; it would be recommended to the reader to investigate further information available online and in-print, namely Life with qmail (http://www.lifewithqmail.org/) and The qmail Handbook, (Apress, ISBN 1-893115-40-2) both authored by Dave Sill.
1.0 – Introduction
Internet email is one of the most popular uses for computers today. This holds true both on the desktop end, such as a home user reading the email from thier ISP, or the server end such as the mail server at the ISP. Setting up a reliable and efficent email server is simple today given that you have a connection to the internet and a system to install it on.
For many years, the de facto standard for routing mail on the Internet has been Sendmail. Sendmail has been freely available for many years and has been included with just about every free UNIX-like operating system available, such as *BSD or Linux. This availability has made Sendmail widely used, but often overlooked in terms of security. Past versions of Sendmail have been subsceptible to many severe security threats and exploits. Some argue that these security concerns are in the past, but to assume that current versions are different in this respect is naive; it would take a major recoding of Sendmail to make it as secure as such a widely used and prominent utility should be.
Several other mail programs (specifically MTAs, or Mail Transfer Agents) have cropped up in recent years; Postfix, Exim, and qmail being the most popular. Of the three, qmail holds the torch for the most secure implementation and offers many other features that make it worth investigating.
2.0 – Foreword
A couple of words in pretense of this guide.
Most of the information presented here has been obtained in one form or another from various informative sources, namely Dave Sills’ writings online and in his book (see text in red above). My purpose is to present this guide as a concise and direct HOWTO written for users of OpenBSD; experience has shown me that those new to an operating system with something in mind often find it helpful to read something geared specifically toward thier system; hence, this HOWTO will contain syntax that fits exactly the syntax used in OpenBSD.
Also in forward, let me credit Professor Dan J. Bernstein, author of qmail and several other significant pieces of software. I have great respect for djb’s software and development skills; few programmers can code with his eye for simplicity and security-mindedness (as evidenced by his money-backed guarantees). There exists those in the public that criticize djb for his rudeness, crudeness, abrasiveness, overall personality, etc. etc. My point in this case is this: if the software is excellent, use it. Regardless of djb’s personality, the software is still excellent. To those who refuse to use “djbware” based on the personality of the author: you are fools.
Now on to the stuff that matters. Prior to running qmail, there are a couple of things to remember and prepare for:
- qmail is an MTA. It routes mail for users in a domain. In order to be recognized as a domain’s Mail Exchanger, there must exist within the DNS records for that zone an MX record that points to the name of the mail server (not IP address). Ensure that your DNS is correct and set up properly before attempting to use qmail. If you’ve not got DNS fully set up or need a pointer, or even if you do have it set up but want a better DNS package, check out djbdns – it’s a powerful and secure DNS package also written by djb.
- There is a certain way to run qmail, and a certain way to install it. The reasons behind this are simple; it works best doing it in this way. If you are a hotshot admin that thinks that something shouldn’t run out of /var/qmail and think that you want to change it, by all means GO AHEAD. But remember that the documentation you will find is for what is generally accepted as a default qmail installation – the wise admin will not stray from this, but will accept the philosophy of Tai Chi and go with the flow. Bottom line – don’t try to get fancy unless you know what you’re doing – there shouldn’t be many compelling reasons to stray from the steps given in this and other qmail howtos.
- There is other accompanying software besides qmail that we will be installing. If you have the idea to not install it, remember that it is insignificantly small, lightweight, stable, secure, and keeps qmail ticking. djb wrote both of them. If you have a problem installing them still, see the last bullet point above.
In the matter of commands that are to be entered in, I will attempt to make everything so that they can be copied in from the browser and pasted directly into your shell. Note however, that some commands will have to be modified to fit your exact configuration and should not be copied and pasted verbatim. Care should be taken to edit these commands before entering them ito your system.
3.0 – Download Software
So. . . the first item of business is downloading the following packages. ucspi-tcp and daemontools are both useful helper packages for qmail (and most of djb’s software, incidentally) that can help control the various services including logging. The most current version of these packages is linked to from here; little development on this software occurs simply because there have been no inherent security concerns or feature bloat since their release. qmail, for example, has stayed at version 1.03 for somewhere around four years now without requiring revision.
The first link is to the current (as of the time of this writing) version of the package; the second link will direct you to the home page for the program so that you can investigate the release of a more current version.
Once all of the packages have been downloaded, proceed on and we will begin installation.
4.0 – Installation
Installation of qmail will involve several steps, namely installing daemontools and rebooting (since svscanboot will be started from rc.local), installing ucspi-tcp, and finally installing qmail. Although the post-installation configuration is still technically considered installation, we will split this off into a seperate section.
4.0.1 – daemontools
Installing daemontools is very straightforward. All in all, it is a brilliant package. daemontools is designed to monitor a service to ensure that it stays running all the time, and if it is detected as having exited for any reason, restarting the daemon automatically. It works similar in that respect to one of inittab’s functions, without however requiring that the admin edit a config file.
First steps are as follows: create a directory at /package that daemontools will be installed from, and run the install script from the daemontools source in that directory:
mkdir /package mv daemontools-0.76.tar.gz /package cd /package tar zxvf daemontools-0.76.tar.gz cd admin/daemontools-0.76 ./package/install
These steps have installed daemontools into the system. To complete the installation, reboot the system in order to allow svscanboot to start properly from /etc/rc.local. When the system comes back up, log in and we will continue with installation of ucspi-tcp.
ucspi-tcp installation will be equally easy and similar to daemontools, with the lack of any special directories or reboot.
tar zxvf ucspi-tcp-0.88.tar.gz cd ucspi-tcp-0.88 make make setup check
Now with the pre-required packages installed, go on through to the installation of qmail.
There are a few more steps involved in installing qmail. For instance, as the following commands show, a couple of different system accounts and groups are created. The reason behind this is that unlike Sendmail, qmail runs as several individual pieces; Sendmail is one monolithic program performing many complicated functions. This means a couple of things, namely that what affects one aspect or process of Sendmail affects Sendmail as a whole. If compromise occurs on one level, Sendmail as a whole is affected. Under qmail, this is broken up into several different processes running under the control of different user IDs and daemons; this process and privilege separation leads to a more secure program with less potential for bugs (less complication means less room for error.) This is evidenced by its very secure and stable history – compare this to Sendmail’s security and bug list, and the differences become apparent.
mkdir /var/qmail groupadd nofiles useradd -g nofiles -d /var/qmail/alias alias useradd -g nofiles -d /var/qmail qmaild useradd -g nofiles -d /var/qmail qmaill useradd -g nofiles -d /var/qmail qmailp groupadd qmail useradd -g qmail -d /var/qmail qmailq useradd -g qmail -d /var/qmail qmailr useradd -g qmail -d /var/qmail qmails tar zxvf qmail-1.03.tar.gz cd qmail-1.03
You should probably see an error indicating that /var/qmail/alias doesn’t exist; this is expected, as it has not been created yet. This will be taken care of as we continue the installation:
make setup check
This final command will compile the binaries and other files and install qmail into the system; most of the files into /var/qmail and some into /etc. The next thing to do is make sure that qmail is aware of the host’s fully qualified domain name (FQDN). This can be accomplished by one of two ways, depending on whether you can resolve the DNS name of the qmail server (requiring reverse DNS to be functioning) or if you would like to specify it yourself.
- In order to allow DNS to resolve your IP address to the FQDN of the qmail host, use the config.sh script:
- If you do not have a PTR record for the server’s IP and cannot resolve to the hostname with DNS, use the config-fast script:
Where my.host.name is the FQDN of the qmail server. This should also be the hostname that you are designating as the MX for your DNS zone.
You should at this point have daemontools, ucspi-tcp, and qmail installed on the system; continue on to the configuration section where we complete the setup details and configuration of qmail.
This section continues on with some post-installation steps for qmail and configuration of files for settings.
An important point to remember is this: running an MTA (Mail Transfer Agent, or mail relay server, etc.) is that it is a fairly complicated piece of machinery. To successfully and properly operate a public mail server is to have a solid understanding of the way that DNS and SMTP work, as well as System and Network administration knowledge in general. More advanced topics include operation of POP and IMAP protocols, as mentioned earlier. Add into this optional SPAM control, and perhaps the most important (based on its impact and potential for affecting others on the Internet) is understanding of relay control. For this reason, it is imperative to understand the configuration options and operation process that qmail uses and how it works. We will cover the most basic setup and post-setup options in this section.
The first file we will create is qmail’s rc file. This is the control script that runs the neccesary commands to launch the qmail binaries. Using your text editor, create this file at /var/qmail/rc
#!/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`"
With the rc file in place, make it executable.
chmod 755 /var/qmail/rc
And create the mail logging directory:
Traditional UXIX mailboxes have been in mbox format, where new messages are appended to the end of a previous file, making one large mailbox file. This has the potentail for unreliable mail delivery and loss of messages, among other problems. The maildir format of mailboxes was introduced with qmail; this writes individual messages to thier own seperate file in the user’s mailbox directory. We need to tell qmail to use Maildir delivery
echo ./Maildir/ >/var/qmail/control/defaultdelivery
Now it is time to create a script to control qmail with. The qmailctl script allows the administrator to start, stop, restart, and manipulate other operations of qmail. Create this file at /var/qmail/bin/qmailctl
#!/bin/sh PATH=/var/qmail/bin:/bin:/usr/bin:/usr/local/bin:/usr/local/sbin export PATH QMAILDUID=`id -u qmaild` NOFILESGID=`id -g qmaild` case "$1" in start) echo "Starting qmail" if svok /service/qmail-send ; then svc -u /service/qmail-send else echo qmail-send supervise not running fi if svok /service/qmail-smtpd ; then svc -u /service/qmail-smtpd else echo qmail-smtpd supervise not running fi if [ -d /var/lock/subsys ]; then touch /var/lock/subsys/qmail fi ;; stop) echo "Stopping qmail..." echo " qmail-smtpd" svc -d /service/qmail-smtpd echo " qmail-send" svc -d /service/qmail-send if [ -f /var/lock/subsys/qmail ]; then rm /var/lock/subsys/qmail fi ;; stat) svstat /service/qmail-send svstat /service/qmail-send/log svstat /service/qmail-smtpd svstat /service/qmail-smtpd/log qmail-qstat ;; doqueue|alrm|flush) echo "Flushing timeout table and sending ALRM signal to qmail-send." /var/qmail/bin/qmail-tcpok svc -a /service/qmail-send ;; queue) qmail-qstat qmail-qread ;; reload|hup) echo "Sending HUP signal to qmail-send." svc -h /service/qmail-send ;; pause) echo "Pausing qmail-send" svc -p /service/qmail-send echo "Pausing qmail-smtpd" svc -p /service/qmail-smtpd ;; cont) echo "Continuing qmail-send" svc -c /service/qmail-send echo "Continuing qmail-smtpd" svc -c /service/qmail-smtpd ;; restart) echo "Restarting qmail:" echo "* Stopping qmail-smtpd." svc -d /service/qmail-smtpd echo "* Sending qmail-send SIGTERM and restarting." svc -t /service/qmail-send echo "* Restarting qmail-smtpd." svc -u /service/qmail-smtpd ;; cdb) tcprules /etc/tcp.smtp.cdb /etc/tcp.smtp.tmp < /etc/tcp.smtp chmod 644 /etc/tcp.smtp.cdb echo "Reloaded /etc/tcp.smtp." ;; help) cat <
Make the qmailctl file executable and link it into a directory in the executable path:
chmod 755 /var/qmail/bin/qmailctl ln -s /var/qmail/bin/qmailctl /usr/bin
The purpose of installing daemontools earlier was to have a process to monitor and control the qmail daemons. It uses a facility called supervise to accomplish this; create the run scripts that supervise will read to run qmail fuctions:
mkdir -p /var/qmail/supervise/qmail-send/log mkdir -p /var/qmail/supervise/qmail-smtpd/log
Create a file at /var/qmail/supervise/qmail-send/run with the following contents:
#!/bin/sh exec /var/qmail/rc
Create a file at /var/qmail/supervise/qmail-send/log/run with the following contents:
#!/bin/sh exec /usr/local/bin/setuidgid qmaill /usr/local/bin/multilog t /var/log/qmail
Create a file at /var/qmail/supervise/qmail-smtpd/run with the following contents:
#!/bin/sh QMAILDUID=`id -u qmaild` NOFILESGID=`id -g qmaild` MAXSMTPD=`cat /var/qmail/control/concurrencyincoming` if [ -z "$QMAILDUID" -o -z "$NOFILESGID" -o -z "$MAXSMTPD" ]; then echo QMAILDUID, NOFILESGID, or MAXSMTPD is unset in echo /var/qmail/supervise/qmail-smtpd/run exit 1 fi exec /usr/local/bin/softlimit -m 4000000 /usr/local/bin/tcpserver -v -R -l 0 -x /etc/tcp.smtp.cdb -c "$MAXSMTPD" -u "$QMAILDUID" -g "$NOFILESGID" 0 smtp /var/qmail/bin/qmail-smtpd 2>&1
qmail uses the concurrencyincoming file to control the number of simultaneous SMTP connections that can be made. Create this file with an echo statement:
echo 20 > /var/qmail/control/concurrencyincoming chmod 644 /var/qmail/control/concurrencyincoming
Create a file at /var/qmail/supervise/qmail-smtpd/log/run with the following contents:
#!/bin/sh exec /usr/local/bin/setuidgid qmaill /usr/local/bin/multilog t /var/log/qmail/smtpd
Now all of the run files need to be made 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
We now need to create the log directories:
mkdir -p /var/log/qmail/smtpd chown qmaill /var/log/qmail /var/log/qmail/smtpd
The following command will link qmail-send and qmail-smtpd into the /service directory; this will make the daemons available to be controlled by supervise. Since we don't want the daemons to start quite yet, we'll tell qmailctl to stop them:
ln -s /var/qmail/supervise/qmail-send /var/qmail/supervise/qmail-smtpd /service qmailctl stop
5.0.1 - SMTP Relaying Access Control
The matter of relaying mail is a serious one that has led to a lot happening in the world of electronic mail. In the past, many SMTP servers were set up as open relays, meaning that anyone on the Internet could send mail from an SMTP server to any recipient in the world; what this led to was spammers sending bulk mail and using an open relay as the server to send from. This quickly evolved into a problem with wasted bandwidth and worse, the rapid spread of SPAM across the Internet. To counteract this, rules on relaying were estblished. Any SMTP server that is known to be an open relay can now be placed on a blackhole list and mail from these servers denied; the possibility exists that SPAM may be sent out from any open-relay. For this reason, and to prevent unwanted clients from using your mail server as a server to send their junk mail from, be sure to implement some relay control.
qmail makes this easy by maintaining a database of allowed IP addresses that may send mail to domains other than the ones for which qmail accepts mail. Using echo commands, we can create a file that allows anyone on the server as well as anyone in our private address range to send mail through our server:
echo '127.:allow,RELAYCLIENT=""' >>/etc/tcp.smtp echo '10.0.0.:allow,RELAYCLIENT=""' >>/etc/tcp.smtp qmailctl cdb
The above commands added anyone in a 127.x.x.x address and a 10.0.0.x address to be allowed to relay mail onto outside mail servers. The syntax would be similar for any other address ranges you wanted to add. Note that the address range ends in a period; for instance, to add any address in your private 192.168.x.x range:
echo '192.168.:allow,RELAYCLIENT=""' >>/etc/tcp.smtp qmailctl cdb
The cdb argument passed to qmailctl tells it to take the file /etc/tcp.smtp and compile it into a fast-to-parse database format that qmail reads.
OpenBSD comes stock with Sendmail installed and functioning on the system. qmail comes with replacement binaries that can be used to replace Sendmail; this is needed since a lot of mail utilities and system functions take for granted that sendmail will be installed on the system, and therefore will not operate if sendmail binaries are not found.
The first step is to determine the PID of the running Sendmail process and kill it:
ps waux|grep sendmail kill sendmail_pid
The following string of commands will backup the old Sendmail binaries and disable them, and then replace them with the qmail versions of the binaries:
mv /usr/libexec/sendmail/sendmail /usr/libexec/sendmail/sendmail.old mv /usr/sbin/sendmail /usr/sbin/sendmail.old chmod 0 /usr/libexec/sendmail/sendmail.old /usr/sbin/sendmail.old ln -s /var/qmail/bin/sendmail /usr/libexec/sendmail ln -s /var/qmail/bin/sendmail /usr/sbin
There also exists an alternate, and possibly cleaner, way to do this. OpenBSD knows which mail-related programs to run based on the configuration outlined in the file /etc/mailer.conf. Take a look at the original file, and see how all functions are pointing to the original sendmail binary. The below /etc/mailer.conf makes it so that the system will use qmail instead of sendmail when a mail capability is needed:
# [Original comment:] Execute the "real" sendmail program, named /usr/libexec/sendmail/sendmail # [New comment:] Execute qmail's sendmail replacement, /var/qmail/bin/sendmail # sendmail /var/qmail/bin/sendmail send-mail /var/qmail/bin/sendmail mailq /var/qmail/bin/sendmail newaliases /var/qmail/bin/sendmail hoststat /var/qmail/bin/sendmail purgestat /var/qmail/bin/sendmail
Both of these options seem to work; you may either replace the sendmail binaries with the qmail versions, as in the first example, or change the mailer.conf to point to qmail instead, as in the second example.
There is also a crontab entry that should be disabled. Use the command crontab -e to open your crontab for editing and find the line that has the comment "sendmail clientmqueue runner" and comment the cron entry out. This prevents the Sendmail process from occuring. After this line has been commented out, save and exit the crontab file. You should see a notice confirming the changes you made:
crontab: installing new crontab
Finally, OpenBSD comes by default configured with Sendmail running. Although it only listens for local connections, it will need to be disabled nonetheless. In typical BSD fashion, this can be done from /etc/rc.conf - simply make the change indicated below.
sendmail_flags="-L sm-mta -C/etc/mail/localhost.cf -bd -q30m"
Now Sendmail will not be launched at boot.
NOTE: I may as well include, at this point, a small bit of side information for users of OpenBSD 3.2 and (possibly) higher. Changes to the structure of the filesystem where /var is located have put the nosuid option active on it; in order for qmail to function correctly when installed to /var/qmail, make sure that the nosuid option is disabled. To do this, edit the /etc/fstab and remove this option, and then remount the filesystem. For example, here is my newly-edited fstab file, showing the difference (the original line is commented out, and replaced with a new line without the nosuid option.)/dev/wd0a / ffs rw 1 1 #/dev/wd1a /var ffs rw,nodev,nosuid 1 2 /dev/wd1a /var ffs rw,nodev 1 2
5.0.3 - Configuring Mail AliasesBy default, qmail is configured to use mail accounts based on real accounts from /etc/passwd. But like Sendmail, qmail can be configured to deliver mail to accounts that use aliases. We will configure qmail to send mail to certain accounts that should exist on any mail system. Since logging in as root should be minimized, we'll configure qmail to deliver system mail addressed to root to a non-root user, as well as some mail-related aliases, DNS admin, and Web Administrator mail to go to the same user. Say the nonprivileged user that will recieve mail for these accounts is called "bob" - we can use the following commands:
echo bob > /var/qmail/alias/.qmail-root echo bob > /var/qmail/alias/.qmail-postmaster ln -s /var/qmail/alias/.qmail-postmaster /var/qmail/alias/.qmail-mailer-daemon echo bob > /var/qmail/alias/.qmail-webmaster echo bob > /var/qmail/alias/.qmail-hostmaster
The next commands set the proper permissions on the alias files and start qmail - configuration is almost complete.
chmod 644 /var/qmail/alias/.qmail-*
There are a couple of control files that should be configured to match your site's configuration at this point. Control files (located under /var/qmail/control) are where options are set for qmail to read and operate from. Rather than one large config file with many hard to find options, each control file represents an option or setting within the qmail configuration.
The /var/qmail/control/rcpthosts file specifies which domains qmail will accept mail for. If you've gone this far, rcpthosts already contains the FQDN of your local server. We need to add the DNS domain name now. As an example - say your mail host will recieve mail for its local FQDN (we'll call this mail.somedomain.com) and also for the entire somedomain.com domain. The file should then contain:
The /var/qmail/control/locals file contains domain names that should be delived locally on this host, or in other words, that the mailboxes will be located on this server. This would be different to configurations where although the server is responsible for handling mail for a given domain, the mail is actually delivered to another server for mailbox storage and serving. Given the above example, the locals file should exactly mirror the rcpthosts file:
Given the above example, mail sent from the server will be shown from the return address as such: firstname.lastname@example.org. We want mail to be shown as from email@example.com, omitting the host name. For this, make sure that /var/qmail/control/defaultdomain contains the domain that mail should be shown as coming from:
A good way to make sure that new users added to the system will automatically have a mailbox is to create a Maildir in the /etc/skel directory; the contents of this directory are copied into the new user's home directory and changed to thier ownership. Note that this should be done as the root user.
cd /etc/skel /var/qmail/bin/maildirmake Maildir
Finally, we should now be ready to start qmail and test.
6.0 - Testing the Installation
At this point, qmail should be completely installed and running. There are a couple of things to do to check and verify that all is working as it should.
The first thing to check is that the right processes are running - the ps command can be used to verify this. See the following usage and expected results:
# ps auxwww |grep qmail root 1813 0.0 0.1 24 276 ?? I 21Aug02 0:00.07 supervise qmail-send root 10289 0.0 0.1 24 276 ?? I 21Aug02 0:00.04 supervise qmail-smtpd qmaill 29726 0.0 0.1 48 332 ?? I 21Aug02 0:01.05 /usr/local/bin/multilog t /var/log/qmail/smtpd qmaill 14945 0.0 0.1 48 332 ?? I 21Aug02 0:01.72 /usr/local/bin/multilog t /var/log/qmail qmails 17475 0.0 0.1 104 384 ?? I 21Aug02 0:06.88 qmail-send qmaild 15347 0.0 0.1 64 360 ?? I 21Aug02 0:01.56 /usr/local/bin/tcpserver -v -R -l 0 -x /etc/tcp.smtp.cdb -c 20 -u 1003 -g 1002 0 smtp /var/qmail/bin/qmail-smtpd root 26175 0.0 0.1 44 292 ?? I 21Aug02 0:01.78 qmail-lspawn ./Maildir/ qmailr 21027 0.0 0.1 40 288 ?? I 21Aug02 0:00.01 qmail-rspawn qmailq 15163 0.0 0.1 36 304 ?? I 21Aug02 0:01.23 qmail-clean
As can be seen, there are 2 supervise processes managing qmail-send and qmail-smtpd and 2 multilog processes running as qmaill managing logging for these daemons. The other qmail proccesses should look something like this:
- 1 qmail-send process running as qmails
- 1 tcpserver process running as qmaild
- 1 qmail-lspawn proccess running as root
- 1 qmail-rspawn process running as qmailr
- 1 qmail-clean process running as qmailq
If all checks out on these processes, test mail delivery by sending a test message through qmail-inject. First, make sure to create a Maildir for the user that was set up earlier in an alias to recieve root's mail. Use the maildirmake utility to do this. **AS THE USER** (not as root) execute the following command in your home directory:
This command creates the Maildir mailbox structure under the user's home directory, which consists of individual folders for management of unread, read, and other types of messages. Once the maildir is created, send a test message:
echo "to: bob" | /var/qmail/bin/qmail-inject
And now look for a message in the newly arrived mail from within this user's directory:
If there is a file in this folder, then you know that:
- The mail delivery subsystem of qmail is working perfectly
- The qmail alias system is working perfectly
Another test would be to make sure that qmail is listening to the SMTP port on your host. Verify this with the use of the telnet utility:
telnet 127.0.0.1 25
If qmail is listening and accepting connections, you will see something like this:
Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is '^]'. 220 mail.somedomain.com ESMTP