sl/openbsd

Installing qmail and courier-imap on OpenBSD

Last updated: 2019-03-07T21:38:15-0500

   uname -a
   OpenBSD th.inri.net 6.0 GENERIC#2229 amd64

NOTE: th.inri.net is the name of my machine. If you use any of these files you will need to change every occurrence of th.inri.net to match your own system.

Why

Djb software is abandonware written by a political dissident. Furthermore, it was removed from the OpenBSD ports tree prior to the 9/11 attacks on New York City and Washington, D.C. Critical functionality is provided by unofficial patches of questionable origin. To make matters worse, most of the required software does not build on OpenBSD without patching. Therefore, to save myself trouble in the future, I have documented the process of acquiring, patching, installing, and configuring all of the software needed to stand up a fully functioning mail server under qmail and courier-imap on OpenBSD.

daemontools

We’ll use daemontools to ensure qmail does not crash to death, but instead re-spawns upon failure. To install:

   cd $HOME/src
   wget http://openbsd.stanleylieber.com/src/daemontools-0.76.tar.gz
   tar zxvf daemontools-0.76.tar.gz
   cd admin/
   wget http://openbsd.stanleylieber.com/src/daemontools-0.76.errno.patch
   cd daemontools-0.76
   patch -p1 <../daemontools-0.76.errno.patch
   package/install

qmail

Features like SMTP authentication and SPF checking are not present in qmail as it was created by djb. To add these features we rely upon patches uploaded to the Internet by miscellaneous qmail users. I have not reviewed these at source level but they seem to work. YMMV.

   cd $HOME/src
   wget http://openbsd.stanleylieber.com/src/netqmail-1.06.patched.tgz

NOTE: Rather than manually patching a distribuion of qmail which essentially never changes, I have patched my copy in advance. My tarball, netqmail-1.06.patched, was created thusly:

   # on freebsd
   cd /usr/ports/mail/qmail
   # enable DNS_CNAME, SMTP_AUTH_PATCH, and SPF_PATCH
   make config
   make extract
   cd work
   mv netqmail-1.06 netqmail-1.06.patched
   tar zcvf netqmail-1.06.patched.tgz netqmail-1.06.patched
   # and, on openbsd
   tar zxvf netqmail-1.06.patched.tgz
   cp qmail-1.03/auto_uids.c.dist netqmail-1.06/patched/
   cp qmail-1.03/qbiff.c netqmail-1.06.patched/
   cd netqmail-1.06.patched
   sam -d Makefile
   114
   c
           cp auto_uids.c.dist auto_uids.c
   .
   w
   q

NOTE: There is no need to perform the above steps unless you don’t trust my netqmail-1.06.patched tarball.

Back to installation:

   tar zxvf netqmail-1.06.patched.tgz
   cd netqmail-1.06.patched
   mkdir -p /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
   make setup check
   cd /var/qmail
   wget http://openbsd.stanleylieber.com/qmail/rc
   chmod 755 /var/qmail/rc
   mkdir /var/log/qmail
   mkdir /var/qmail/control
   cd /var/qmail/control
   echo 20 >concurrencyincoming
   chmod 644 concurrencyincoming
   echo ./Maildir/ >defaultdelivery
   echo th.inri.net >defaultdomain
   echo th.inri.net >locals
   echo th.inri.net >me
   echo inri.net >plusdomain
   echo th.inri.net >rcpthosts
   cd /var/qmail/bin
   wget http://openbsd.stanleylieber.com/qmail/qmailctl
   chmod 775 qmailctl
   mkdir /usr/local/qmail
   mv /var/qmail/bin /usr/local/qmail/
   ln -s /usr/local/qmail/bin /var/qmail/bin
   ln -s /usr/local/qmail/bin/qmailctl /usr/local/bin/
   mkdir -p /var/qmail/supervise/qmail-send/log
   mkdir -p /var/qmail/supervise/qmail-smtpd/log
   mkdir -p /var/qmail/supervise/qmail-smtpd-ssl/log
   cd /var/qmail/supervise/qmail-send
   wget http://openbsd.stanleylieber.com/qmail/supervise/qmail-send-run
   mv qmail-send-run run
   cd /var/qmail/supervise/qmail-send/log
   wget http://openbsd.stanleylieber.com/qmail/supervise/qmail-send-log-run
   mv qmail-send-log-run run
   cd /var/qmail/supervise/qmail-smtpd
   wget http://openbsd.stanleylieber.com/qmail/supervise/qmail-smtpd-run
   mv qmail-smtpd-run run
   cd /var/qmail/supervise/qmail-smtpd/log
   wget http://openbsd.stanleylieber.com/qmail/supervise/qmail-smtpd-log-run
   mv qmail-smtpd-log-run run
   cd /var/qmail/supervise/qmail-smtpd-ssl
   wget http://openbsd.stanleylieber.com/qmail/supervise/qmail-smtpd-ssl-run
   mv qmail-smtpd-ssl-run run
   cd /var/qmail/supervise/qmail-smtpd-ssl/log
   wget http://freebsd.stanleylieber.com/qmail/supervise/qmail-smtpd-ssl-log-run
   mv qmail-smtpd-ssl-log-run run
   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
   chmod 755 /var/qmail/supervise/qmail-smtpd-ssl/run
   chmod 755 /var/qmail/supervise/qmail-smtpd-ssl/log/run
   mkdir -p /var/log/qmail/smtpd
   chown qmaill /var/log/qmail /var/log/qmail/smtpd
   mkdir -p /var/log/qmail/smtpd-ssl
   chown qmaill /var/log/qmail /var/log/qmail/smtpd-ssl
   rcctl stop smtpd
   rcctl disable smtpd
   /etc/rc.d/sendmail stop
   mv /usr/lib/sendmail /usr/lib/sendmail.old # ignore errors
   mv /usr/sbin/sendmail /usr/sbin/sendmail.old # ignore errors
   chmod 0 /usr/lib/sendmail.old /usr/sbin/sendmail.old # ignore errors
   ln -s /var/qmail/bin/sendmail /usr/lib
   ln -s /var/qmail/bin/sendmail /usr/sbin
   echo sl > /var/qmail/alias/.qmail-root
   echo sl > /var/qmail/alias/.qmail-postmaster
   ln -s .qmail-postmaster /var/qmail/alias/.qmail-mailer-daemon
   ln -s .qmail-postmaster /var/qmail/alias/.qmail-abuse
   chmod 644 /var/qmail/alias/.qmail-root /var/qmail/alias/.qmail-postmaster
   echo doublebounce >/var/qmail/control/doublebounceto
   # silently discard double bounces
   echo '#' >/var/qmail/alias/.qmail-doublebounce
   # silently discard all messages to non-existent accounts
   echo '#' >/var/qmail/alias/.qmail-default
   ln -s \
          /var/qmail/supervise/qmail-send \
          /var/qmail/supervise/qmail-smtpd \
          /var/qmail/supervise/qmail-smtpd-ssl \
          /service
   qmailctl stop # until you're ready

ucspi-tcp

The ucspi-tcp tcpserver(1) program will answer incoming TCP connections and hand them off to either qmail-smtpd directly, or to the ucspi-tools tlss(1) program (which will in turn hand them off to qmail-smtpd). For now, we will only allow relaying from localhost.

   pkg_add ucspi-tcp
   echo '127.:allow,RELAYCLIENT=""' >>/etc/tcp.smtp
   qmailctl cdb

ucspi-tools

The ucspi-tools tlss(1) program will handle TLS for incoming TCP connections. After the TLS connection is established, tlss(1) spawns qmail-stmpd.

   pkg_add ucspi-tools
   openssl genrsa -out /etc/ssl/qmail.server.key 2048
   openssl req -new -key /etc/ssl/qmail.server.key \
          -out /etc/ssl/qmail.server.csr
   openssl x509 -sha256 -req -days 365 \
                -in /etc/ssl/qmail.server.csr \
                -signkey /etc/ssl/qmail.server.key \
                -out /etc/ssl/qmail.server.crt
   chown root:nofiles /etc/ssl/qmail.server.csr /etc/ssl/qmail.server.key
   chmod 640 /etc/ssl/qmail.server.csr /etc/ssl/qmail.server.key

courier-authlib

This suite handles authentication for the other courier tools and for qmail’s SMTP auth.

   pkg_add courier-authlib
   # compile the userdb portion from ports if OpenBSD <= 6.0
   cd /usr/ports/mail/courier-authlib
   env SUBPACKAGE=-userdb make install clean
   sam -d /etc/courier/authdaemonrc
   27
   c
   authmodulelist="authuserdb"
   .
   w
   q
   rcctl enable courier_authdaemond
   rcctl start courier_authdaemond

courier-imap

This is how you will access your mail on your awful mobile phone.

   pkg_add courier-imap
   cd /etc/courier
   ed imapd.cnf  # edit to match your site
   sam -d imapd
   60
   c
   MAXPERIP=40   # many folders == many connections
   .
   w
   q
   mkdhparams
   mkimapdcert
   rcctl enable courier_imap_ssl
   rcctl start courier_imap_ssl

courierpasswd

Called directly by the qmail-smtpd and qmail-smtpd-ssl run scripts.

   pkg_add gmake # ugh
   cd $HOME/src
   wget http://openbsd.stanleylieber.com/src/courierpasswd-1.1.3.tar.gz
   tar zxvf courierpasswd-1.1.3.tar.gz
   cd courierpasswd-1.1.3
   export CPPFLAGS=-I/usr/local/include
   export LDFLAGS=-L/usr/local/lib
   ./configure
   make
   make install
   chgrp courier /usr/local/sbin/courierpasswd
   chmod g+s /usr/local/sbin/courierpasswd

Add an SMTP/IMAP user

User accounts are managed separately from user accounts on the host operating system. Both instances of authentication will rely upon the same mechanism: courierpasswd backed by courier-authlib.

   # as $USER
   maildirmake $HOME/Maildir
   >$HOME/.th-imap-password
   chmod 600 $HOME/.th-imap-password
   echo password >$HOME/.th-imap-password
   # as root
   username=username userdb $username set \
          home=/home/$username \
          mail=/home/$username/Maildir \
          uid=`id -u $username` \
          gid=`id -g $username`

   # update SMTP/IMAP user password db based on
   # the contents of of $HOME/.th-imap-password
   cd /usr/local/qmail/bin
   wget http://openbsd.stanleylieber.com/qmail/updatepass.sh
   chmod 775 updatepass.sh
   ln -s /usr/local/qmail/bin/updatepass.sh /usr/local/bin
   /usr/local/bin/updatepass.sh       # read this, suitable to run from cron

   # create new IMAP folder called newfolder
   # as $USER
   maildirmake -f newfolder /home/$USER/Maildir

SpamAssassin and maildrop

Now that everything sort of works, let’s assume we’d like to mitigate spam. We’ll allow individual users to control the filtering via $HOME/.qmail (used by qmail) and $HOME/.mailfilter (used by maildrop).

   pkg_add maildrop p5-Mail-SpamAssassin
   sa-update
   crontab -e
   ,p
   a
   1 7 * * * /usr/local/bin/sa-update
   .
   w
   q
   rcctl enable spamassassin
   rcctl start spamassassin
   ## do this as root to enable SpamAssassin for all users by default
   #echo '| /usr/local/bin/spamc | maildir ./Maildir/' \
   #      >/var/qmail/control/defaultdelivery
   # OR do this as $USER to enable SpamAssassin for only that user
   cd
   wget http://openbsd.stanleylieber.com/qmail/dot.mailfilter &&
          mv dot.mailfilter .mailfilter      # edit to suit
   chmod 600 .mailfilter
   echo '| /usr/local/bin/spamc | maildrop' >.qmail

Turn on qmail

   qmailctl start
   qmailctl stat # trust, but verify

Logs

   # qmail-send
   tail -f /var/log/qmail/current | tai64nlocal
   # qmail-smtpd
   tail -f /var/log/qmail/smtpd/current | tai64nlocal
   # qmail-smtpd-ssl
   tail -f /var/log/qmail/smtpd-ssl/current | tai64nlocal

Troubleshooting

DO NOT UNDER ANY CIRCUMSTANCES run the add-on program queue-fix. Pending further investigation.