qmail installation guide

Mark Pustjens The Mindlab Hosting 3rd September 2004 qmail installation guide

an extensive guide to setup a complete qmail based MDA

Mark Pustjens 3rd September 2004 List of adresses

Mark Pustjens C. de Houtmanstraat 18 6045 HP Roermond 06-50412316 email: [email protected]

The Mindlab Hosting Mestreech 1234 ab

I Preamble

This guide will describe howto install a qmail based email server, com- plete with virtual domains, pop3, imap, spamassasin and mailinglist (for now). You should be able to use this guide with OpenBSD, FreeBSD and Redhat .

II Contents

List of Tables VII

1 TODO 1

2 Preparations 2 2.1 Conventions ...... 2 2.2 Hardware requirements ...... 2 2.3 Software requirements ...... 2 2.3.1 Linux ...... 3 2.3.2 OpenBSD ...... 3 2.4 Software you need ...... 3 2.4.1 qmail 1.03 ...... 3 2.4.2 ucspi-tcp 0.88 ...... 4 2.4.3 ucspi-ssl 0.68 ...... 4 2.4.4 daemontools 0.76 ...... 4 2.4.5 vpopmail 5.4.5 ...... 4 2.4.6 Courier-IMAP 3.0.7 ...... 4 2.4.7 Procmail 3.22 ...... 5 2.4.8 Spamassassin 3.00 ...... 5

3 Installing the core packages: qmail, ucspi-tcp and daemon- tools 6 3.1 Obtaining the source ...... 6 3.2 Installing ucspi-tcp ...... 6 3.2.1 Compiling ...... 6 3.3 Installing daemontools ...... 7 3.3.1 Compiling ...... 7 3.3.2 Installing ...... 8 3.4 Some notes on daemontools ...... 10 3.4.1 supervise ...... 10 3.4.2 softlimit ...... 10 3.4.3 svc ...... 11 3.5 Compiling and Installing qmail ...... 11

III 3.5.1 Compiling ...... 11 3.5.2 Installing ...... 12 3.6 Replacing the old MTA ...... 17 3.7 Testing what we have ...... 18 3.7.1 Checking the daemons ...... 18 3.7.2 Sending test messages ...... 19 3.8 Conclusion ...... 24

4 Adding services 25 4.1 Overview ...... 25 4.2 Vpopmail ...... 25 4.2.1 Compiling and installing vpopmail ...... 25 4.2.2 Configuring vpopmail ...... 27 4.2.3 Testing vpopmail ...... 28 4.2.4 Creating the localhost as virtual domain ...... 28 4.3 Pop3 ...... 29 4.3.1 Service scripts ...... 29 4.3.2 Testing the pop3 server ...... 29 4.4 IMAP ...... 30 4.4.1 Compiling Courier-IMAP ...... 30 4.4.2 Configuring Courier-IMAP ...... 32 4.5 Conclusion ...... 34

5 Securing services 35 5.1 Overview ...... 35 5.2 Certificates ...... 35 5.3 Installing ucspi-ssl ...... 36 5.3.1 Compiling ...... 36 5.3.2 Installing ...... 37 5.4 Securing SMTP ...... 37 5.4.1 Receiving messages, qmail-smtpd ...... 37 5.4.2 Sending messages, qmail-remote ...... 43 5.5 Securing Pop3 ...... 44 5.5.1 Configuring POP3 over SSL ...... 44 5.5.2 Testing POP3 over SSL ...... 44 5.6 Securing IMAP ...... 45 5.6.1 Configuring IMAP over SSL ...... 45 5.6.2 Testing IMAP over SSL ...... 45 5.7 Conclusion ...... 46

6 Mail Filtering 47 6.1 Procmail ...... 47 6.1.1 Installing ...... 47 6.1.2 Global Filter ...... 48

IV 6.1.3 Testing the filter ...... 49 6.2 Basic Spamassassin Filter ...... 50 6.2.1 Installing ...... 51 6.2.2 configuring spamd ...... 53 6.2.3 Adding spamc to the mail delivery process ...... 55 6.2.4 Testing Spamassassin ...... 55 6.3 Conclusion ...... 56

Bibliography I

A OpenBSD fstab II

B svscanboot III

C /var/qmail/rc IV

D /var/qmail/bin/qmailctl V

E qmail service scripts, qmail-smtpd and qmail-send XII E.1 /var/qmail/supervise/qmail-send/run ...... XII E.2 /var/qmail/supervise/qmail-send/log/run ...... XII E.3 /var/qmail/supervise/qmail-smtpd/run ...... XII E.4 /var/qmail/supervise/qmail-smtpd/log/run ...... XIII

F vpopmail. XIV

G vlimits.default XV

H qmail service scripts, qmail-pop3d XVII H.1 /var/qmail/supervise/qmail-pop3d/run ...... XVII H.2 /var/qmail/supervise/qmail-pop3d/log/run ...... XVII

I qmail service scripts, courier-imapd XVIII I.1 /var/courier-imap/supervise/courier-imapd/run ...... XVIII I.2 /var/courier-imap/supervise/courier-imapd/log/run . . . . . XVIII

J SMTP AUTH Extension example XIX

K qmail service scripts, qmail-smtpsd XXI K.1 /var/qmail/supervise/qmail-smtpsd/run ...... XXI K.2 /var/qmail/supervise/qmail-smtpsd/log/run ...... XXI

L qmail service scripts, qmail-pop3sd XXII L.1 /var/qmail/supervise/qmail-pop3sd/run ...... XXII L.2 /var/qmail/supervise/qmail-pop3sd/log/run ...... XXII

V M qmail service scripts, courier-imapsd XXIII M.1 /var/courier-imap/supervise/courier-imapsd/run ...... XXIII M.2 /var/courier-imap/supervise/courier-imapsd/log/run . . . . . XXIII

N mail filter scripts XXIV N.1 procmailrc ...... XXIV N.2 qmail-users ...... XXVI N.3 qmail-procmail ...... XXVI

O spamassassin service script, spamd XXVII O.1 /var/spamassassin/supervice/spamd/run ...... XXVII O.2 /var/spamassassin/supervice/spamd/log/run ...... XXVIII

P Installing DBD::mysql using CPAN XXIX

Q Spamassassin configuration file XXX

R spamassassin procmail recipe XXXIII

VI List of Tables

3.1 qmail groups ...... 12 3.2 qmail users ...... 13

VII Chapter 1

TODO

This is a list of TODO items. You’ll also find TODO items throughout this manual.

• qmail-smtpd: tcpserver realblacklist? rblsmtpd (ucspi-tcp). dit moet aan want skip rbl checks in spamassassin staat uit

• /var/qmail/queue on seperate filesystem with small blocksize and no softupdates

• max DATABYTES to limit email size, man qmail-smtpd

• systeem aliassen naar mailinglist sturen.

• qmail linken met lib syncdir, of patchen met de fsync patch, qmail wordt veiliger op een fs met soft updates.

• script maken om logs makkelijk te bekijken

• !!! qmail-maildir++ patch !!!

• qmail-remote in ssl wrappen mbv script. als geen ssl beschikbaar is automatische fallback naar gewoon smtp

• STARTTLS hoeft niet gebruikt te worden als smtp ook in ssl gewrapped word, dit is dubbelop

• vermelden de de source bewaard MOET blijven na het installeren.

• tcpserver-mysql patch gebruiken? hiermee kunnen de access databases in mysql gezet worden. Of alleen de access db voor smtpd?

• andere database naam voor alle tabellen

• qqtool voor queue management.

1 Chapter 2

Preparations

2.1 Conventions

Do to the nature of what we are about to do, you should use extreme care with any command you use. Also, in this document we assume you will be using a test server, this reduces any risk to zero if you make any mistake.

2.2 Hardware requirements

Qmail is able to run on almost all kinds of hardware, provided a UNIX OS runs on it.

2.3 Software requirements

Your system must meet the following requirements.

• Qmail is designed to run on any Unix or Unix-like operating system. Qmail’s licence requires it to distributed in source format which means you need a standard C compiler.

• Storage space is no longer a problem on modern systems. You’ll need at least 30 to 40 Megabytes of space for the sources and just a little more for building the sources.

• A running mySQL server. Although this is not needed for qmail itself, the IMAP server and virtual domains support package we will install do need this.

• To be able to use the security features you need an openssl compatible SSL library.

Although not necessairy, the following is recommended.

2 CHAPTER 2. PREPARATIONS 3

• Qmail was designed for highly connected systems. Although there are solutions for systems with low availability of an internet connection, a stable connection is recommended.

• The filesystem should perform link() calls synchronously. This will prevent loss of email on a system failure, as all data is immidiately written to the disk without delay.

• I possible, a seperate filesystem for qmail’s queue and mailstore. This filesystem should be equiped with a small blocksize1. This filesystem should also have a large amount of inodes, increasing the amount of files which can be stored on the filesystem.

2.3.1 Linux If you are using a seperate filesystem for the queue and mailstore, you can speed up disk access a bit by using the following mount options for that filesystem:

• noatime; do not update access times.

• sync; no caching, this not needed with the syncdir library, reduces performance

2.3.2 OpenBSD If you are planning to install qmail on a system running OpenBSD 3.2 and higher, you need to disable the “nosuid” mount option for the filesystem on which qmail will reside. You can remove this option by editing /etc/fstab. An example is provided in appendix A.

2.4 Software you need

The following software packages are used in this guide.

2.4.1 qmail 1.03 Qmail is the set of applications which together make up the mail server. Besides the main qmail package we will need some patches to extend and fix various parts of qmail.

• qmail-queue patch

• sendmail -f flag patch

1Email files are typically very small. With a small blocksize less space is wasted. CHAPTER 2. PREPARATIONS 4

• qmail 0.0.0.0 patch

• qmail-local patch

• qmail glibc errno patch

• qmail identity = netqmail patch

• qmail 64bit compatibility patch

• qmail-smtpd patch

• qmail AUTH and STARTTLS patch

Most of those patches are distributed together with qmail in the netqmail distribution[2]. The instructions in this manual are based on the netqmail distribution.

2.4.2 ucspi-tcp 0.88 This package contains serveral utilities to modularize a tcp server/client environment.

2.4.3 ucspi-ssl 0.68 This package contains SSL enabled versions of the programs in the ucspi-tcp package. We will use those programs to setup SSL wrapped version of the services.

2.4.4 daemontools 0.76 Daemontools is a set of applications to manage services, or daemons. One program monitors a service and restarts it if it fails. Another application serves a an automatic loggin facility. We also need to apply a patch to the source if you are using a version of openSSL higher than 0.9.6.

2.4.5 vpopmail 5.4.5 Using the applications in this package we can manage virtual domains. Vpopmail supports the use of mySQL for storing its domains configuration.

2.4.6 Courier-IMAP 3.0.7 Courier-IMAP is a server which gives user IMAP access to their mailboxes. Courier-IMAP only supports the Maildir mailbox format, and allows the use of the Maildir++ extension. The Maildir++ extension adds folder and quota support. CHAPTER 2. PREPARATIONS 5

2.4.7 Procmail 3.22 Procmail is a general purpose mail filter. Procmail has a powerfull filtering language which allows almost any kind of filtering.

2.4.8 Spamassassin 3.00 Spamassassin claims to be an extensible mail filter. This is very true but its power lies in the fact that it is very effective in identifing spam messages and tagging them as such. Spamassassin has support to store various parts of its configuration in a database, this appears to be working fine although this functionality is still in beta testing stage. At the time of writing, spamassassin 3.00 rc 2 was the latest available version. I expect the instructions given in this document will be compatible with the final release of this version. Chapter 3

Installing the core packages: qmail, ucspi-tcp and daemontools

We begin by installing the three core packages: qmail, ucspi-tcp and dae- montools. With qmail being the most important, the MTA1. ucspi-tcp Ac- cepts connections and will pass those though to the appropriate qmail pro- grams. And daemontools will make sure qmail is running, it will start, stop, restart and log services as necessairy.

3.1 Obtaining the source

You can find the download locations in the Bibliography in section 6.3. For the first part of this guide you need the packages netqmail, daemontools and ucspi-tcp.

3.2 Installing ucspi-tcp

Ucspi-tcp should be installed first. This tools in this package are used in the daemontools scripts.

3.2.1 Compiling Before you unpack the tar.gz file, make sure your umask is set correctly, it should be 0022. If it isn’t, set it to 0022.

# umask 0002 1Message Transer Agent

6 CHAPTER 3. INSTALLING THE CORE PACKAGES: QMAIL, UCSPI-TCP AND DAEMONTOOLS7

# umask 0022 # umask 0022

Move to your source directory, and unpack the netqmail[2] distribution. The netqmail distribution contains various patches we need not only for ucspi-tcp, but also for daemontools. Now unpack the ucspi-tcp[5] distribution and enter the new directory.

# cd /usr/src/ucspi-0.88

You can set your compiler options in the file conf-cc. Acceptable values can be found in your systems make defaults files2 The netqmail also contains some patches for ucspi-tcp, which are located in the netqmail-1.05/other- patches/ folder. Those patches need to be applied too.

# patch < ../netqmail-1.05/other-patches/ucspi-tcp-0.88.a_record.patch # patch < ../netqmail-1.05/other-patches/ucspi-tcp-0.88.errno.patch # patch < ../netqmail-1.05/other-patches/ucspi-tcp-0.88.nodefaultrbl.patch

The rest of the installation is very easy:

# cd /usr/src/ucspi-0.88 # make # make setup check

This will install the binaries into /usr/local/bin. The installation of ucspi-tcp is now completed.

3.3 Installing daemontools

Daemontools uses packages from ucspi-tcp, and qmail will be started using the daemontools.

3.3.1 Compiling Before you unpack the daemontools[4] package, check your umask. See sec- tion 3.2.1 for details. There is a patch for daemontools in the netqmail package. Apply it like this:

# cd /usr/src/admin/daemontools-0.76/src/ # patch < ../../../netqmail-1.05/other-patches/daemontools-0.76.errno.patch

2OpenBSD: /etc/mk.conf, FreeBSD: /etc/make.conf, Redhat Linux: ? CHAPTER 3. INSTALLING THE CORE PACKAGES: QMAIL, UCSPI-TCP AND DAEMONTOOLS8

Editing the conf-cc file will allow you to set your compiler options, just like with ucspi-tcp. You could also you just copy this file from the ucspi-tcp source tree. Now you can build and install daemontools.

# cd /usr/src/admin/daemontools-0.76/ # sh package/install

3.3.2 Installing The steps in the section above installed daemontools using the defaults. This is not what whe want. The installation installed two folders /service and /command, added a line to your startup scripts3, and finally, made symbolic links to the binairies in the source tree. Lets change this to something more standard.

OpenBSD and Linux

# mkdir /etc/daemontools # mv /service /command /etc/daemontools # cd /etc/daemontools/command # rm *

FreeBSD

# mkdir /usr/local/etc/daemontools # mv /service /command /usr/local/etc/daemontools # cd /usr/local/daemontools/command # rm * # ln -s /usr/local/etc/daemontools /etc/daemontools

All systems

# cd /etc/daemontools/command # rm -rf * # cp /usr/src/admin/daemontools/command/* . # chmod 755 * # chown root:wheel *

# cd /usr/local/bin # rm envdir envuidgid fghack multilog pgrphack readproctitle setlock \ > setuidgid softlimit supervise svc svok svscan svscanboot svstat \ > tai64n tai64nlocal 3OpenBSD, FreeBSD: /etc/rc.local, Linux: /etc/inittab CHAPTER 3. INSTALLING THE CORE PACKAGES: QMAIL, UCSPI-TCP AND DAEMONTOOLS9

# ln -s /etc/daemontools/command/* .

The file svscanboot is a startup script for the svscan4 daemon. Currently this script still uses some standard paths, which should be changed to reflect our changes. Also it uses readproctitle as a “logging” service. We will replace readproctitle with multilog. First we need to create the folders for multilog to store its logfiles under.

# mkdir -p /var/log/daemontools/svscan/ # chmod -R 700 /var/log/daemontools/svscan/

Now we need to modify the svscanboot script to actually use multilog. See appendix B for an example. The standard installation modified some system files to make sure the svscanboot script will run when the system boots. Under OpenBSD and FreeBSD it added a command to /etc/rc.local which needs to be modified to reflect the new path of the svscanboot script. Under Linux it added a line to /etc/inittab. If you are using a Sysem V compatible distribution, we will create a control script and remove this line from /etc/inittab. This will be done later on and it is discussed in paragraph 3.5.2. To be able to test if the svscan startup script works, we can start it manually, and see if it spawned some processes. Note that svscanboot keeps itself on the foreground, so you should put it in the background.

# cd /etc/daemontools/command # ./svscanboot & shutting down running services... svc: warning: unable to chdir to /etc/daemontools/service/*: file does not exist svc: warning: unable to chdir to /etc/daemontools/service/*/log: file does not exist restarting services ... # ps waux USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND ...snip... root 19898 0.0 0.1 388 284 C0- I 8:28PM 0:00.01 /bin/sh /etc/daemontools/command/svscanboot root 15332 0.0 0.2 68 316 C0- S 8:28PM 0:00.04 /etc/daemontools/command/svscan /etc/daemontools/service root 6121 0.0 0.2 48 300 C0- I 8:28PM 0:00.01 /etc/daemontools/command/multilog t /var/log/daemontools/svscan

As you can see, the script first tries to shutdown any running services, which fails, because we have not yet installed any services. Then, it tries to start all known services. Here also see the output of the “ps waux” command. You can see that there are three seperate processes running which have to do with svscanboot, this is how it should be. You can check the logfile for any errors.

4Part of the daemontools CHAPTER 3. INSTALLING THE CORE PACKAGES: QMAIL, UCSPI-TCP AND DAEMONTOOLS10

# cd /var/log/daemontools/svscan # tai64nlocal < current 2004-08-25 20:47:30.629504500 ** Starting svscan on /etc/daemontools/service #

In this example, no error was reported. You should now stop svscanboot, and check if it will automatically start when you reboot.

# fg ^C # reboot

Please note that you can use the commands above at any time to start svscanboot manually. This is usefull when testing. However, if svscanboot starts successfully when booting the system, this won’t be necesairy.

3.4 Some notes on daemontools

Please read the notes below carefully, as they will help you to solve problems.

3.4.1 supervise • The first time you will create run scripts for a service they will be loaded automatically, and the service will be started. At this point you should check the logfile to check i an error occured.

• Whenever you modify a run script, the service needs to be restarted for the run script to be reloaded.

3.4.2 softlimit Softlimit is an application which runs another application with other re- source limits. In the run scripts we will create this program will allways be used. The only limit we will set is the memory limit. The memory limits imposed in the scripts should work on most systems. When your new mail server is up and running you should tune these values to suit your system. E.g. on a OpenBSD system you could easily lower the memory limit to 20000005 or less. You should closely monitor the log files whenever you start a new server6. If you see a line similar to the following examples, it means the memory limit was not set high enough and you should raise it.

5About 2 Megabytes 6The phrasing making it known to supervise is used often in this document. CHAPTER 3. INSTALLING THE CORE PACKAGES: QMAIL, UCSPI-TCP AND DAEMONTOOLS11

/var/qmail/bin/qmail-smtpd: error while loading shared libraries: libc.so.6: failed to map segment from shared object: Cannot allocate memory

/usr/libexec/ld.so: tcpserver: libc.so.29.0: Cannot allocate memory

3.4.3 svc Svc controls services which are monitored by supervise. You can use this program to stop and start a service. The following command shows how to stop and then start the qmail-pop3sd service.

# svc -d /etc/daemontools/service/qmail-pop3sd # svc -u /etc/daemontools/service/qmail-pop3sd

You can do the same with the qmailctl control script we will install later.

# /etc/qmailctl stop qmail-pop3sd * stopping services... stopping qmail-pop3sd: qmail-pop3sd down * done stopping services # /etc/qmailctl start qmail-pop3sd * starting services... starting qmail-pop3sd: qmail-pop3sd up * done starting services

3.5 Compiling and Installing qmail

3.5.1 Compiling Before you unpack the compressed archive[2], make sure your umask is set correctly, it should be 0022. If it isn’t, set it to 0022. See section 3.2.1 for detailed instructions. We also need an additional patch[?], which implements STARTTLS and AUTH smtp extensions. We had to uncpress the netqmail sources earlier so we can skip that step now. Because qmail may only be distributed as unmodified source, all patches have to be applied. Netqmail provides a script for this:

# cd netqmail-1.05 # sh collate.sh # cd netqmail-1.05 # patch -p0 < ../../netqmail-1.05-tls-smtpauth-20040705.patch

Now the build tree is ready, you can setup compiler options in the file conf-cc. If you use RedHat Linux, openssl was compiled with kerberos CHAPTER 3. INSTALLING THE CORE PACKAGES: QMAIL, UCSPI-TCP AND DAEMONTOOLS12

Table 3.1: qmail groups

gid name 200 nofiles 201 qmail support. Without a extra compiler option compilation will fail. Add - I/usr/kerberos/include/ as option to conf-cc.

# vi conf-cc #

Now you can create various forlders and symbolic links for qmail. Don’t worry about the permissions on these folders, the qmail makefile will change these to their appropriate settings. The symbolic links will make the con- figuration files available under standard locations.

# mkdir /var/qmail # cd /var/qmail # ln -s /usr/local/man . # to have the manpages on a central location

FreeBSD only:

# ln -s /var/qmail/control /usr/local/etc/qmail

OpenBSD and Linux:

# ln -s /var/qmail/control /etc/qmail

Creating users and groups7. Create a number of users and groups ac- cording to tables 3.2 and 3.1. I chose to have all userids and groupids in the range 200 - 210. Now qmail can be compiled. The commands below will compile and install qmail in “/var/qmail/bin”.

# make setup check

3.5.2 Installing The “make setup check” command allready put the binaries in the right place. Now qmail has to get a basic configuration.

7The use of several seperate system accounts is very important for qmail’s security model CHAPTER 3. INSTALLING THE CORE PACKAGES: QMAIL, UCSPI-TCP AND DAEMONTOOLS13

Table 3.2: qmail users

name uid group homedir shell alias 200 nofiles /var/qmail/alias /bin/false qmaild 201 nofiles /var/qmail /bin/false qmaill 202 nofiles /var/qmail /bin/false qmailp 203 nofiles /var/qmail /bin/false qmailq 204 qmail /var/qmail /bin/false qmailr 205 qmail /var/qmail /bin/false qmails 206 qmail /var/qmail /bin/false

# sh config

This will lookup your hostname, and create a number of configuration files based on that. For this to work properly, your dns servers need to have been configured properly. If this command fails to lookup your hostname, you can use the following command to do it manually.

# sh config-fast your.fully.qualified.domain.name

Configuring the default delivery method Now we need to to tell qmail how to deliver its email. Although the file we will create with the next command is not a standard file, the scripts we are going to create will use this file. Putting this configuration in a seperate file also allows us to change this setting easily without changing every seperate script.

# echo ./Maildir/ > /var/qmail/control/defaultdelivery

Setting a SMTP greeting message Optionally you can set the message sent as a SMTP greeting. This message is sent to the client when connection to the SMTP service. The first word of this message should be your hostname.

# echo your.hostname The Mindlab Hosting mail server > /var/qmail/control/smtpgreeting

Qmail boot script Qmail also needs a boot script. Create the file “/var/qmail/rc” according to appendix C. As you can see, this script logs any output to the standard out- put. In normal cases this would mean that these error messages dissappear. We are going to setup qmail as a service using the daemontools programs. CHAPTER 3. INSTALLING THE CORE PACKAGES: QMAIL, UCSPI-TCP AND DAEMONTOOLS14

The service that will start this script will get its own logging service, which catches all output generated by this script. The script has to be executable, so set the permissions to allown that.

# chmod 755 /var/qmail/rc

Qmail control script Using the qmail programs seperately to get status information can be cum- bersome. Also, starting the daemontools programs to start the right services can be a bit obscure. Therefore we will make a script for this. Create the file /var/qmail/bin/qmailctl, you will find a listing of this script in appendix D. This script has to be executable, so set the rights accordingly. Use the same commands you used for the “rc” script. This script has the form of an init.d control script, and can be used as one. We will make sure it can be used as a one, by creating symbolic links to a few places.

# cd /var/qmail/bin

FreeBSD

# ln -s qmailctl /usr/local/etc/init.d/qmailctl

Linux

# ln -s qmailctl /etc/init.d/qmailctl # cp /etc/inittab /etc/inittab.old # cat /etc/inittab | grep -v svscanboot > /etc/inittab

For Linux users, the line with svscanboot will be removed using the last command. OpenBSD does not use the System V style init, so the above does not apply. FreeBSD also doesn’t use System V style init, but it does provide a directory for the scripts so one can use them manually. We want qmail to start every time the system boots. We can acomplish this by running the command qmailctl start every time the system boots. On BSD like systems, we need to add this command to the file etc/rc.local. On System V style systems, we can link the qmailctl script to the directory’s of the approriate runlevels. For RedHat Linux, use the following commands. This will make sure the qmailctl start command will run in runlevels 2, 4 and 5.

# cd /etc/init.d # ln -s qmailctl ../rc0.d/K30qmail CHAPTER 3. INSTALLING THE CORE PACKAGES: QMAIL, UCSPI-TCP AND DAEMONTOOLS15

# ln -s qmailctl ../rc1.d/K30qmail # ln -s qmailctl ../rc2.d/S80qmail # ln -s qmailctl ../rc3.d/K30qmail # ln -s qmailctl ../rc4.d/S80qmail # ln -s qmailctl ../rc5.d/S80qmail # ln -s qmailctl ../rc6.d/K30qmail #

Installing the qmail services As said before, we will use daemontools to run qmail as a service. In fact, we will need two services. One to listen for incoming mail, and one to send mail. First a few directories need to be created to store the files with instructions for the service in.

# mkdir -p /var/qmail/supervise/qmail-send/log # mkdir -p /var/qmail/supervise/qmail-smtpd/log # chmod 1750 /var/qmail/supervise/qmail-send \ > /var/qmail/supervise/qmail-smtpd

The chmod command shown will set the sticky bit on two directories. Supervise, part of daemontools, will recognise this, and will start the logging service of that service. Now we need to create some scripts in the previously create directories. You can find those scripts, four in total, in appendix E. After the script have been made, the correct permissions should be set on them. We also need to create the directories where multilog will write it’s log files to. And last, one of the scripts created uses another non-standard configuration file, that file has to be created too.

# cd /var/qmail/supervise # chmod 750 */run */log/run

# mkdir -p /var/log/qmail/send # mkdir /var/log/qmail/smtpd # chown -R qmaill:qmail /var/log/qmail

# echo 20 > /var/qmail/control/concurrencysmtp # chmod 640 /var/qmail/control/concurrencysmtp

We need to set some permissions on various files and folders.

OpenBSD

# chown root:qmail /var/qmail/bin/* CHAPTER 3. INSTALLING THE CORE PACKAGES: QMAIL, UCSPI-TCP AND DAEMONTOOLS16

# chown qmailq:qmail /var/qmail/bin/qmail-queue # chmod 755 /var/qmail # chmod 755 /var/qmail/alias

If you are using OpenBSD and you have not yet disabled the nosuid flag for the /var filesystem, do this now and add the suid flag to the “qmail- queue” binairy. All the files necessairy for the services have been created. No we can make those services known to supervise.

# cd /etc/daemontools/service # ln -s /var/qmail/supervise/qmail-send . # ln -s /var/qmail/supervise/qmail-smtpd .

SMTP access control In the file “/etc/tcp.smtp” you can change the way certain hosts are treated concerning relaying of email. We want the localhost to be able to relay email. Based on this file an access database will be built. We have to rebuild this database after every change to this file.

# echo ’127.:allow,RELAYCLIENT=""’ > /etc/tcp.smtp # /var/qmail/bin/qmailctl cdb Reloaded /etc/tcp.smtp.

We also want users with an email adress on this system to be able to relay if they are working from a remote locating. The AUTH smtp extensions makes this already possible. When a user wants to send a message using our smtp server, it must login to the smtp server. Without logging in, relaying is prohibited.

System aliases System aliases in this context are aliases for the email adress of the system administrators. There are a few email adresses which should be on any email server. We can create those using the following commands.

# cd /var/qmail/alias # echo \&admin > .qmail-root # ln -s .qmail-root .qmail-postmaster # ln -s .qmail-root .qmail-mailer-daemon # chmod 644 .qmail-root CHAPTER 3. INSTALLING THE CORE PACKAGES: QMAIL, UCSPI-TCP AND DAEMONTOOLS17

Now, everything sent to “root@yourdomain”, “postmaster@yourdomain” and “mailer-daemon@yourdomain” will be sent to the local user “admin”. You can change “admin” to any local username or email adress. If you use an email adress, please do make sure it is a valid adress, since delivery failure reports get sent there. Of course you can also use seperate receiving adresses for the different system aliasses.

3.6 Replacing the old MTA

Now that we have everything installed, it’s time that we replace the old MTA. Once the old MTA has been removed, we can start testing our qmail installations. It is also possible to disable an other MTA temporarily. In this document however, we just remove the old MTA completely. In most cases the old MTA used is sendmail, so the instructions below are specific to that MTA.

RedHat Linux On RedHat Linux, or any other rpm based distro, you can use the “rpm” command to completely remove sendmail.

# rpm -e sendmail

OpenBSD On OpenBSD follow the following instructions.

# rm -rf /usr/share/sendmail # rm -rf /usr/libexec/sendmail

On OpenBSD there is also a crontab job for sendmail. You can dis- able this crontab by opening your crontab for editing using the command “crontab -e”. There you can comment out the line with sendmail in it. Although sendmail is no longer present, there still is a script that tries to start it if it was enabled. Open your “/etc/rc.conf” for editing, and find the line containing sendmail. Change the line to look like this: sendmail_flags=NO

Another file needs to be edited for OpenBSD. This time it is “/etc/mailer.conf”. All the lines in this file point to the origional sendmail binary. Change the file in such a way that all lines point the qmail sendmail compatibility pro- gram. Use the following location for that program:

/var/qmail/bin/sendmail CHAPTER 3. INSTALLING THE CORE PACKAGES: QMAIL, UCSPI-TCP AND DAEMONTOOLS18

FreeBSD TODO instructies voor FreeBSD

All systems Now that the old sendmail binaries are gone, we need to replace them with qmail’s sendmail program.

# ln -s /var/qmail/bin/sendmail /usr/sbin/sendmail

3.7 Testing what we have

Now every piece of software has been installed, we must test if everything works before continueing the installation.

3.7.1 Checking the daemons First we will try to start and stop qmail, and see if any errors are reported.

# cd /var/qmail/bin # ./qmailctl start Starting qmail # ./qmailctl stop Stopping qmail... qmail-smtpd qmail-send

Then we start qmail again for the rest of the tests. After this is done, we use the qmailctl control script again to see if all the daemons are running.

# ./qmailctl stat /etc/daemontools/service/qmail-send: up (pid 31158) 4 seconds /etc/daemontools/service/qmail-send/log: up (pid 10458) 277 seconds /etc/daemontools/service/qmail-smtpd: up (pid 25674) 4 seconds /etc/daemontools/service/qmail-smtpd/log: up (pid 31109) 277 seconds messages in queue: 0 messages in queue but not yet preprocessed: 0

Every service, four at this point, need to be up. You can use the “ps” command to check if those processes are really running. After you are sure everything is ok you have to reboot. This way we can check if the qmail services are started automatically at system boot. After the reboot run the “qmailctl stat” command again to check if the services are running. Check the log files, and check if there are any abnormalities. CHAPTER 3. INSTALLING THE CORE PACKAGES: QMAIL, UCSPI-TCP AND DAEMONTOOLS19

# cd /var/log/qmail/send # tai64nlocal < current 2004-06-13 22:50:36.342876500 status: local 0/10 remote 0/20

You can use “cat”, “more” or “less” on the logfile, but the date will be in an unreadable time format. In this example, the status is displayed, no error is reported. You can also check the logfile of the smtpd daemon. The log format is almost the same. Also check for a status message in the report.

3.7.2 Sending test messages Now that we know that the daemons are running fine, we should send some test messages and see if they arrive. The following testing method was taken form the book “The qmail Handbook”[1]. Since the testing involves sending messages from and to test users, you will need at least two local accounts. Use other accounts then those you used for the system aliasses, eg. not root. In the example we use the two users sandra andbob. For remote adress, we will use [email protected].

Local user to local user Send youself a test message:

# echo to: bob | /var/qmail/bin/qmail-inject

Now check that the message has arrived.

# ls ~bob/Maildir/new 1087161947.16348.your.domain #

In the example there is one new message in the “new” directory. The message arrived.

Local user to invalid local user Log in as user sandra, and send a message to a non-existing user.

# su - sandra $ echo to: nonexisting | /var/qmail/bin/qmail-inject

Since the user the message was sent to does not exist, user sandra should have received a bounce message. Check if the message arrived, and check its contents. CHAPTER 3. INSTALLING THE CORE PACKAGES: QMAIL, UCSPI-TCP AND DAEMONTOOLS20

$ ls ~/Maildir/new 1087393864.1945.your.domain $ cat ~/Maildir/new/1087393864.1945.your.domain Return-Path: <> Delivered-To: [email protected] Received: (qmail 18709 invoked for bounce); 16 Jun 2004 13:51:04 -0000 Date: 16 Jun 2004 13:51:04 -0000 From: [email protected] To: [email protected] Subject: failure notice

Hi. This is the qmail-send program at your.domain. I’m afraid I wasn’t able to deliver your message to the following addresses. This is a permanent error; I’ve given up. Sorry it didn’t work out.

: Sorry, no mailbox here by that name. (#5.1.1)

--- Below this line is a copy of the message.

Return-Path: Received: (qmail 29203 invoked by uid 1002); 16 Jun 2004 13:51:04 -0000 Date: 16 Jun 2004 13:51:04 -0000 Message-ID: <[email protected]> From: [email protected] to: [email protected] $

The qmail-send logfile should also contain a report about what happened.

# cd /var/log/qmail/send/ # tai64nlocal < current ...snip... 2004-06-16 15:51:04.071999500 new msg 11586 2004-06-16 15:51:04.072219500 info msg 11586: bytes 244 from qp 29203 uid 1002 2004-06-16 15:51:04.110192500 starting delivery 3: msg 11586 to local [email protected] 2004-06-16 15:51:04.110305500 status: local 1/10 remote 0/20 2004-06-16 15:51:04.120796500 delivery 3: failure: Sorry,_no_mailbox_here_by_that_name._(#5.1.1)/ 2004-06-16 15:51:04.140128500 status: local 0/10 remote 0/20 2004-06-16 15:51:04.200546500 bounce msg 11586 qp 18709 2004-06-16 15:51:04.210082500 end msg 11586 2004-06-16 15:51:04.288922500 new msg 11588 2004-06-16 15:51:04.289057500 info msg 11588: bytes 838 from <> qp 18709 uid 206 2004-06-16 15:51:04.328117500 starting delivery 4: msg 11588 to local [email protected] CHAPTER 3. INSTALLING THE CORE PACKAGES: QMAIL, UCSPI-TCP AND DAEMONTOOLS21

2004-06-16 15:51:04.328226500 status: local 1/10 remote 0/20 2004-06-16 15:51:04.367889500 delivery 4: success: did_1+0+0/ 2004-06-16 15:51:04.374925500 status: local 0/10 remote 0/20 2004-06-16 15:51:04.375181500 end msg 11588 ...snip... #

Here you can first see the origional message being delivered, which fails. Then you see the bounce message being sent.

Local user to remote adress Now we’ll try to send a message to a remote adress8.

$ echo to: [email protected] | /var/qmail/bin/qmail-inject

When you check the email for that adress, an empty message should have arrived. Besides this, we can also check the qmail-send logfile to see if the message was sent.

# cd /var/log/qmail/send/ # tai64nlocal < current ...snip... 2004-06-16 16:09:38.352290500 info msg 11586: bytes 227 from qp 26999 uid 1002 2004-06-16 16:09:38.390208500 starting delivery 5: msg 11586 to remote [email protected] 2004-06-16 16:09:38.390319500 status: local 0/10 remote 1/20 2004-06-16 16:09:39.070024500 delivery 5: success: 217.67.234.253_accepted_message./Remote_host_said:_250_ok_1092405836_qp_18158/ 2004-06-16 16:09:39.080113500 status: local 0/10 remote 0/20 2004-06-16 16:09:39.080363500 end msg 11586 ...snip... #

In this example, the message was successfully received by the remote MTA.

Local user to system alias We will try to send a message the the postmaster.

$ echo to: postmaster | /var/qmail/bin/qmail-inject

In this guide we used the user admin as receiver of all messages to system aliasses. Check if the message arrived in the users mailbox.

8You should login as user sandra. CHAPTER 3. INSTALLING THE CORE PACKAGES: QMAIL, UCSPI-TCP AND DAEMONTOOLS22

Invalid local user to invalid local user Messages which are sent to an invalid adress should bounce to the sending adress. If the sending adress doesn’t exist, the message should bounce to the postmaster.

$ echo to: invalidreceipient | /var/qmail/bin/qmail-inject -f invalidsender

The mailbox of the user admin should contain the double bounce mes- sage.

Program delivery With qmail it is possible to deliver email to any program. This way you can take special action when a message arrives for a special user. We will create a script for user bob. This script will create a file when a message arrives at his account. First login as user bob, and create the script. Then create a “.qmail” file with instructions to dilever to the script.

# su - bob $ echo ’groups > MYGROUPS’ > script.sh $ chmod +x script.sh $ echo ’|/home/bob/script.sh; exit 0’ > /home/bob/.qmail

Send a test message to user bob and check if the file “MYGROUPS” exists. Also check the contents of this file. This file should contain only the groups names of which user bob is a member, which proves all mail is deliverd using the userid of the receiving user. After this test was successfull, remove the “.qmail” file and the script.

Using the SMTP daemon directly Testing the SMTP daemon is relatively simple. If you know allready know how to talk to the server, just telnet to localhost on port 25 and send a test message. If you do not know the protocol then follow the instructions below. Commands typed by the user are prefixed with a >.

> $ telnet localhost 25 Connected to localhost. Escape character is ’^]’. 220 your.domain.here ESMTP > ehlo smtp server 250 your.domain 250-STARTTLS 250-PIPELINING CHAPTER 3. INSTALLING THE CORE PACKAGES: QMAIL, UCSPI-TCP AND DAEMONTOOLS23

250-8BITMIME 250 AUTH LOGIN PLAIN CRAM-MD5 > mail from: username@domain # insert your email adress here 250 ok > rcpt to: username@domain # insert your email adress here 250 ok > data 354 go ahead > Subject: test message > > This is a test message > . 250 ok 1087161947 qp 17121 > quit 221 your.server Connection closed by foreign host. $

Now check if the message is in your mailbox.

Remote user to local user Try sending a message from an adress on a remote system to a user on this system. User [email protected] as the reciepient adress. Verify that the message arrived.

Remote user to invalid local user Send a message from a remote adress to an invalid local user. You should receive a bounce message on the remote adress. You can use nonexist- [email protected] as recipient adress.

Remote user to system alias Send a test message to a system alias, eg [email protected], and check that i arrived ok.

Mail user agent test Try to send messages using a MUA9 on the system. This is not needed if no user will login locally. You should test this if the system will also run a webserver. 9E.g. pine, mail, mutt. CHAPTER 3. INSTALLING THE CORE PACKAGES: QMAIL, UCSPI-TCP AND DAEMONTOOLS24

3.8 Conclusion

Using the instructions in this chapter, we setup a very basic , but functional email system. Email can be received, and email can be sent using local accounts. You have learned how to setup ucspi-tcp, a set of applications to modu- larize a tcp-ip client-server environment, daemontools, a set of programs to easily maintain running services and logging of those services, netqmail, the qmail distribution including serveral essential patches. In chapter 4 we will add services to enhance the functionality of the email system. Chapter 4

Adding services

4.1 Overview

In this chapter we will be adding an IMAP and POP3 server to our existing installation.

4.2 Vpopmail

In most qmail installation documentation, Courier-IMAP and qmail-pop3d are installed first and then vpopmail is added. I think this is unnecessairy. In our case, we will be using mysql to store all virtual domains related configuration. If we would install Courier-IMAP and qmail-pop3d first, we would have modify the configuration of those servers when we would install vpopmail. By installing vpopmail first, the configuration and programs Courier-IMAP and qmail-pop3d need to use for authentication are already in place.

4.2.1 Compiling and installing vpopmail First download vpopmail[8] and unpack it somewhere, eg: /usr/src. Then configure and compile the source.

# setenv CFLAGS=’your flags’ # ./configure --prefix=/var/vpopmail \ > --exec-prefix=/var/vpopmail \ > --enable-tcpserver-file=/etc/tcp.smtp \ > --enable-file-sync \ > --enable-qmail-ext \ > --enable-domainquotas \ > --enable-auth-module=mysql \ > --enable-logging=y \ > --enable-valias

25 CHAPTER 4. ADDING SERVICES 26

...snip... vpopmail 5.4.5 Current settings ------vpopmail directory = /var/vpopmail uid = 89 gid = 89 roaming users = OFF --disable-roaming-users (default) tcpserver file = /etc/tcp.smtp open_smtp file = /var/vpopmail/etc/open-smtp rebuild tcpserver file = ON --enable-rebuild-tcpserver-file (default) password learning = OFF --disable-learn-passwords (default) md5 passwords = ON --enable-md5-passwords (default) file locking = ON --enable-file-locking (default) vdelivermail fsync = ON --enable-file-sync make seekable = ON --enable-make-seekable (default) clear passwd = ON --enable-clear-passwd (default) user dir hashing = ON --enable-users-big-dir (default) address extensions = ON --enable-qmail-ext ip alias = OFF --disable-ip-alias-domains (default) domain quotas = ON --enable-domainquotas auth module = mysql --enable-auth-module=mysql mysql replication = OFF --disable-mysql-replication (default) mysql logging = OFF --disable-mysql-logging (default) mysql limits = OFF --disable-mysql-limits (default) MySQL valias = ON --enable-valias auth inc = -I/usr/local/include/mysql auth lib = -L/usr/local/lib/mysql -lmysqlclient -lz -lm system passwords = OFF --disable-passwd (default) pop syslog = show successful and failed login attempts --enable-logging=y auth logging = ON --enable-auth-logging (default) all domains in one SQL table = --enable-many-domains (default) # make install-strip

And if ‘make install-strip’ fails:

# make install # chmod 6711 /var/vpopmail/bin/vchkpw CHAPTER 4. ADDING SERVICES 27

4.2.2 Configuring vpopmail Creating mySQL user For vpopmail to be able to use mySQL for authentication, seperates user accounts should be created for read access and read/write access. Vpopmail is able to use different settings for readonly operations and database mainte- nance operations. In this case we will make an account vpopmail read for all read operations, and an account vpopmail write for all database maintenace operations. And last, a database needs to be created where the information will be stored.

# mysql -u root -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 2 to server version: 3.23.55

Type ’help;’ or ’\h’ for help. Type ’\c’ to clear the buffer. mysql> CREATE DATABASE vpopmail; Query OK, 1 row affected (0.10 sec) mysql> GRANT select ON vpopmail.* TO vpopmail_read@localhost IDENTIFIED BY "password_read"; Query OK, 0 rows affected (0.09 sec) mysql> GRANT update,create,delete,insert,select ON vpopmail.* TO vpopmail_write@localhost IDENTIFIED BY "password_write"; Query OK, 0 rows affected (0.00 sec) mysql> flush privileges; flush privileges; Query OK, 0 rows affected (0.04 sec) mysql> exit Bye #

The accounts and database have been created. No try to login to the database using the two accounts.

# mysql -u vpopmail_read -ppassword_read vpopmail # mysql -u vpopmail_write -ppassword_write vpopmail

If the test succeeded we can tell vpopmail how to connect to mysql. Modify the file /var/vpopmail/etc/vpopmail.mysql to look like the listing in appendix F. CHAPTER 4. ADDING SERVICES 28

Default limits In the file /var/vpopmail/etc/vlimits.default you can set some default lim- itations on newly create domains and user accounts. You can edit this file using any text editor. I set the options as shown in appendix G.

4.2.3 Testing vpopmail Now we should test vpopmail to make sure everything works correctly. Try adding a domain and user, eg “test.com”. If this succeeds, remove the domain. This test will make sure that vpopmail can access the mySQL server.

# cd /var/vpopmail/bin # ./vadddomain test.com # ./vadduser [email protected] # ./vdeldomain test.com

4.2.4 Creating the localhost as virtual domain Now that vpopmail is up and running, we should add the domain as the localhost as a virtual domain. Then, we need to forward all messages to the three system aliasses to email adresses in the virtual domain.

# cd /var/vpopmail/bin # ./vadddomain -b your.domain postmaster-password # ./vadduser [email protected] password # ./vadduser [email protected] password # cd /var/qmail/alias # rm .qmail-postmaster .qmail-mailer-daemon .qmail-root # echo "[email protected]" > .qmail-postmaster # echo "[email protected]" > .qmail-mailer-daemon # echo "[email protected]" > .qmail-root

Now we should send a test message to one of the system acounts to make sure everything works. Use the following commands.

# echo to: postmaster | /var/qmail/bin/qmail-inject # cd /var/vpopmail/domain/your.domain/postmaster/Maildir/new/ # ls 1092838607.22188.your.domain,S=244 #

The second-last line should look like the one in the example. CHAPTER 4. ADDING SERVICES 29

4.3 Pop3

4.3.1 Service scripts The default installation already installed most applications needed for a pop3 daemon. The remaining application was provided for by the vpopmail installation. All that needs to be done is creating the scripts which will run the pop3 daemon.

# cd /var/qmail/supervise/ # mkdir -p qmail-pop3d/log # chmod 1750 qmail-pop3d # mkdir /var/log/qmail/pop3d # chown qmaill:qmail /var/log/qmail/pop3d

Now create two scripts, /var/qmail/supervuse/qmail-pop3d/run and /var/qmail/supervuse/qmail- pop3d/log/run according to appendix H. Don’t forget to replace “your.domain” with your domain name. The first script of those two uses a non-standard configuration file. Create this configuration file and set some permissions using the following commands.

# cd /var/qmail/supervise # chmod 750 */run */log/run # echo 20 > /var/qmail/control/concurrencypop3

Just like for stmp access, there should be an access database. Create this database. In this example, pop3 access is allowed from anywhere.

# echo :allow > /etc/tcp.pop3 # tcprules /etc/tcp.pop3.cdb /etc/tcp.pop3.tmp < /etc/tcp.pop3

Now that all needed files are created. We can make the qmail-pop3d service known to supervise.

# cd /etc/daemontools/service # ln -s /var/qmail-supervise/qmail-pop3d .

4.3.2 Testing the pop3 server After making the service known to supervise, it should have automatically started. Examine if this is the case using the qmailctl control script.

# /etc/qmailctl stat /etc/daemontools/service/qmail-send: up (pid 14007) 8033 seconds /etc/daemontools/service/qmail-send/log: up (pid 30172) 8033 seconds /etc/daemontools/service/qmail-smtpd: up (pid 14239) 8033 seconds CHAPTER 4. ADDING SERVICES 30

/etc/daemontools/service/qmail-smtpd/log: up (pid 21878) 8033 seconds /etc/daemontools/service/qmail-pop3d: up (pid 20556) 28 seconds /etc/daemontools/service/qmail-pop3d/log: up (pid 27534) 28 seconds messages in queue: 0 messages in queue but not yet preprocessed: 0 #

No try and connect to the pop3 server and check for new email. In this example there is one message in the users inbox. Commands typed by the user are prefixed with a >.

# telnet localhost 110 Trying 127.0.0.1... Connected to localhost. Escape character is ’^]’. +OK <[email protected] [email protected] > user [email protected] +OK > pass password +OK > list +OK 1 344 . > quit +OK Connection closed by foreign host. #

4.4 IMAP

As an IMAP server, we will be using CourierIMAP. Courier is a fast and lightweight IMAP server, furthermore, it can use vpopmail’s libraries to authenticate users.

4.4.1 Compiling Courier-IMAP The source package[9] must be untarred and compiled using a normal user account. Trying this as root will not work. After you have unpacked the source, use the following command to configure the source.

$ ./configure --prefix=/var/courier-imap \ > --enable-unicode \ > --without-authpwd \ CHAPTER 4. ADDING SERVICES 31

> --without-authshadow \ > --without-authpam \ > --without-authuserdb \ > --without-authcram \ > --without-authldap \ > --without-authldap \ > --without-authpgsql \ > --without-authdaemon \ > --without-authcustom \ > --without-authmysql \ > --with-authvchkpw \ > --with-ssl

Now build the code, and test the code.

Linux:

$ make $ make check

OpenBSD and FreeBSD:

$ gmake $ gmake check

If the test completed successfully, we can check if the correct authenti- cation modules were chosen. Do this using the following command.

$ cd authlib $ ./authinfo AUTHENTICATION_MODULES="authvchkpw" SASL_AUTHENTICATION_MODULES="PLAIN LOGIN" $ cd ..

Now we must reconfigure the source to include an extra option, and then rebuild the applications.

$ ./configure --prefix=/var/courier-imap \ > --enable-unicode \ > --without-authpwd \ > --without-authshadow \ > --without-authpam \ > --without-authuserdb \ > --without-authcram \ CHAPTER 4. ADDING SERVICES 32

> --without-authldap \ > --without-authldap \ > --without-authpgsql \ > --without-authdaemon \ > --without-authcustom \ > --without-authmysql \ > --with-authvchkpw \ > --with-ssl > --with-trashquota \ $ make # or gmake for OpenBSD and FreeBSD

The actual installation of the programs should be done as the root user.

$ su Password: # make install-strip # make install-configure

If you are using FreeBSD or OpenBSD, use gmake instead of make. Also, if make install-strip fails, use make install instead.

4.4.2 Configuring Courier-IMAP Courier-IMAP is now almost completely installed. By default, it installs some scripts which allow you to run it as a standalone daemon. We are going to create some scripts which allows us to run courier-imap using dae- montools.

Service scripts First create the folders where the supervise scripts and logs will be stored in. Then create the two files /var/courier-imap/supervise/courier-imapd/run and /var/courier-imap/supervise/courier-imapd/log/run according to ap- pendix I.

# cd /var/courier-imap/ # mkdir -p supervise/courier-imapd/log \ > supervise/courier-imapd/env # chmod 1750 supervise/courier-imapd # mkdir /var/log/qmail/imapd # chown qmaill:qmail /var/log/qmail/imapd

In one of the scripts a nonstandard configuration file is used and an access database for the imap service is needed. We also need to set some permissions. CHAPTER 4. ADDING SERVICES 33

# echo 20 > /var/courier-imap/etc/concurrencyimap # echo :allow > /etc/tcp.imap # tcprules /etc/tcp.imap.cdb /etc/tcp.imap.tmp < /etc/tcp.imap

# cd /var/courier-imap/supervise # chmod 750 */run */log/run

All necessairy scripts and configuration is now in place. The next step is to make the service known to supervise. After this, the imap daemon should be running and functioning.

# cd /etc/daemontools/service # ln -s /var/courier-imap/supervise/courier-imapd .

Testing IMAP Try to connect to the imap server using telnet. Commands typed by the user are prefixed with a >.

# telnet 127.0.0.1 143 Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is ’^]’. * OK [CAPABILITY IMAP4rev1 UIDPLUS CHILDREN NAMESPACE ...snip... > a1 login [email protected] password a1 OK LOGIN Ok. > a2 select inbox * FLAGS (\Draft \Answered \Flagged \Deleted \Seen \Recent) * OK [PERMANENTFLAGS (\* \Draft \Answered \Flagged \Deleted \Seen)] Limited * 1 EXISTS * 1 RECENT * OK [UIDVALIDITY 1092924408] Ok * OK [MYRIGHTS "acdilrsw"] ACL a2 OK [READ-WRITE] Ok > 3 logout * BYE Courier-IMAP server shutting down a3 OK LOGOUT completed Connection closed by foreign host. #

In the example above, I logged in as the postmaster of the your.domain domain. Then i selected the inbox. There was a total of 1 message, and 1 message was not you seen. After this, I logged out. CHAPTER 4. ADDING SERVICES 34

4.5 Conclusion

In this chapter you enhanced the functionality of the basic qmail installation by providing pop3 and IMAP access to the users mailboxes. You can now manage multiple virtual email domains and users, and all this information is stored in a mySQL database server. In chapter 5 we will setup secure versions of the SMTP, pop3 and IMAP services. Chapter 5

Securing services

5.1 Overview

Now that all services are up and running, we can begin to add secure versions of those services. We will wrap the SMTP, POP3 and IMAP services in a SSL1 using the sslserver program which is a part of the ucspi-ssl package. We will also discuss what security measures are already present in the current setup.

5.2 Certificates

To be able to secure the services effectively, we need to have a SSL certificate. In this document we will place the certificate in /var/certs/. If you already have a certificate for your server, create symbolic links to those files, and place them in the previously mentioned folder. You need four files in total, a private key, in the file privatekey.pem, a certificate certificate.pem a cer- tificate in the format privatekey–certificate certificate-qmail.pem and a DH parameter file dh1024.pem. The file certificate-qmail.pem can be created us- ing the command cat privatekey.pem certificate.pem ¿ certificate-qmail.pem. If you do not have the necessairy files, use the instructions below to create them. Lines requiring user input are prefixed with a >.

> # mkdir /var/certs > # chmod 755 /var/certs > # cd /var/certs > # openssl genrsa -out privatekey.pem 1024 Generating RSA private key, 1024 bit long modulus ...... ++++++ .++++++ e is 65537 (0x10001) 1Secure Socket Layer

35 CHAPTER 5. SECURING SERVICES 36

> # openssl req -new -x509 -key privatekey.pem \ > -out certificate.pem -days 1095 You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter ’.’, the field will be left blank. ----- > Country Name (2 letter code) []:NL > State or Province Name (full name) []:Limburg > Locality Name (eg, city) []:SomeCity > Organization Name (eg, company) []:The Mindlab Hosting > Organizational Unit Name (eg, section) []: > Common Name (eg, fully qualified host name) []:your.domain Email Address []:[email protected] > # cat privatekey.pem certificate.pem > certificate-qmail.pem > # openssl dhparam 1024 -out dh1024.pem Generating DH parameters, 1024 bit long safe prime, generator 2 This is going to take a long time ...... +...... +....+.+...... ++*++*++* > # chmod 644 *

Please note that the “Common Name” should be your fully qualified domain name for that machine.

5.3 Installing ucspi-ssl

Ucspi-ssl[6] is a package which offers to SSL2 enabled versions of tcpserver and tcpclient called sslserver and sslclient. This makes it easy to to wrap services in an encryption layer. In most daemontools service scripts the tcpserver command can directly be replaced by the sslserver command.

5.3.1 Compiling First download ucspi-ssl[6] and unpack it. Then get a patch[7]. Then use the following commands to prepare and build the source.

# cd /usr/src/host/superscript.com/net/ucspi-ssl-0.68 # mv ucspi-ssl-0.68-openssl_0.9.7.patch /usr/src/host/superscript.com/net/ # patch -p1 < ../ucspi-ssl-0.68-openssl_0.9.7.patch # vi src/conf-cc # package/compile

2Secure Socket Layer CHAPTER 5. SECURING SERVICES 37

# package/rts

The conf-cc file contains the commandline to compile the source. You can optionally use the same file you used for daemontools. The output of the package/rts command should be empty.

5.3.2 Installing To install the applications we can simple copy the programs to where we put the daemontools programs, and create a few symlinks.

# cd command # cp sslcat sslclient sslconnect sslperl sslserver \ > /etc/daemontools/command/ # chown root:wheel /etc/daemontools/command/* # cd /etc/daemontools/command/ # ln -s sslcat /usr/local/bin # ln -s sslclient /usr/local/bin # ln -s sslconnect /usr/local/bin # ln -s sslperl /usr/local/bin # ln -s sslserver /usr/local/bin

5.4 Securing SMTP

SMTP takes up two parts in our qmail installation. The first part is the receiving of messages using SMTP, the second is the sending of messages to other systems. There is another aspect in securing SMTP which has to do with the re- laying of messages. The AUTH extension adds authentication to the SMTP protocol. When a user is authenticated this user can relay messages throught this server. An example of authentication over an SMTP session is given in appendix J.

5.4.1 Receiving messages, qmail-smtpd During the installation of qmail itself3, we added a patch which which im- plements the STARTTLS and AUTH smtp extensions. By defaullt the smtpd daemon allows relaying of messages from any adress to any adress. We changed this so that only the local system may relay to other systems. This was setup in the file /etc/tcp.smtp. You can change the settings per ip-adress in this file. Since we are now offiring pop3 and IMAP access to the users mailboxes, it must be possibe for remote users to send messages to other systems through

3Paragraph 3.5.1 CHAPTER 5. SECURING SERVICES 38 our system. The AUTH extension in our qmail installation allows users to authenticate themselves before sending email. Only authenticated users are allowed to relay messages through our mail system.

Configuring TLS Normally all traffic over a smtp connection is sent in plaintext. This traffic could be monitored and recorded by other systems on the network. The STARTTLS extension allows the traffic over the smtp connection to be en- crypted, this is called TLS4. The STARTTLS extension is already activated, but not yet configured. You can check it like this:

$ telnet 192.168.2.200 25 Trying 192.168.2.200... Connected to 192.168.2.200. Escape character is ’^]’. 220 your.domain ESMTP > starttls 454 TLS missing certificate: error:02001002:system library:fopen:No such file or directory (#4.3.0) > quit 221 your.domain Connection closed by foreign host. $

Using the certificate created in paragraph 5.2 we can easily configure qmail-smtpd to enable the secure connection.

# cd /var/qmail/control # ln -s /var/certs/certificate-qmail.pem servercert.pem

Now verify that the certificate was accepted.

> # telnet localhost 25 Trying 127.0.0.1... Connected to 127.0.0.1. Escape character is ’^]’. 220 your.domain ESMTP > starttls 220 ready for tls

As you can see the error message is gone. When using TLS we can’t use telnet to send messages because a certificate handshake needs to take place and the communication is encrypted.

4Transport Layer Security CHAPTER 5. SECURING SERVICES 39

Testing TLS Using the openssl command we can connect to the smtp daemon and send a test message. Please note that you need at least openssl version 0.9.7 for this. In the following listing you can see an example. Commands typed by the user are prefixed with a >. > $ openssl s_client -starttls smtp -crlf -connect 127.0.0.1:25 CONNECTED(00000003) depth=0 /C=NL/ST=SomeState/L=SomeCity/O=themindlab hosting/CN=your.domain/[email protected] verify error:num=18:self signed certificate verify return:1 depth=0 /C=NL/ST=SomeState/L=SomeCity/O=themindlab hosting/CN=your.domain/[email protected] verify return:1 --- Certificate chain 0 s:/C=NL/ST=SomeState/L=SomeCity/O=themindlab hosting/CN=your.domain/[email protected] i:/C=NL/ST=SomeState/L=SomeCity/O=themindlab hosting/CN=your.domain/[email protected] --- Server certificate -----BEGIN CERTIFICATE----- MIICoDCCAgmgAwIBAgIBADANBgkqhkiG9w0BAQQFADCBlTELMAkGA1UEBhMCTkwx EjAQBgNVBAgTCVNvbWVTdGF0ZTERMA8GA1UEBxMIU29tZUNpdHkxGzAZBgNVBAoT EnRoZW1pbmRsYWIgaG9zdGluZzEiMCAGA1UEAxMZZ2FsYWRyaWVsLnRodWlzLnVu a2llLm9yZzEeMBwGCSqGSIb3DQEJARYPcHVzdGplbnNAZGRzLm5sMB4XDTA0MDgy MDE4NTIyNloXDTA1MDgyMTE4NTIyNlowgZUxCzAJBgNVBAYTAk5MMRIwEAYDVQQI EwlTb21lU3RhdGUxETAPBgNVBAcTCFNvbWVDaXR5MRswGQYDVQQKExJ0aGVtaW5k bGFiIGhvc3RpbmcxIjAgBgNVBAMTGWdhbGFkcmllbC50aHVpcy51bmtpZS5vcmcx HjAcBgkqhkiG9w0BCQEWD3B1c3RqZW5zQGRkcy5ubDCBnzANBgkqhkiG9w0BAQEF AAOBjQAwgYkCgYEA1R3z4HdqMKfeOooyMZpKYKZar99ss2ipUBfUUpe/hz0Twn78 UYU6mVlV8tucP6Za2qxc0DNPQfzY0VWETPsUUSHoXEISfvDqlfQ1NKyeD7obcYXb IdYIoUqqRpDQ7eTUWwNCLXNGP4rkC4jTh0gXc1nrwo7CGl/1lVqaca09PzcCAwEA ATANBgkqhkiG9w0BAQQFAAOBgQAa5mJo9VJlViAE+HDbirQCI+uNYa7BorccCPD4 XXesubtHWZcf8dlkLsM/7FdPqKT4HViSAmVaHGbX/33pQvMEIrUkVofSuSFLKTNs rVCBEsVx3Fe2RcVX1r2TbhmEQYx3w4nH2KXqWB95s/bxTOX4a+tXAbR4tPJu2Qeb E+DWYQ== -----END CERTIFICATE----- subject=/C=NL/ST=SomeState/L=SomeCity/O=themindlab hosting/CN=your.domain/[email protected] issuer=/C=NL/ST=SomeState/L=SomeCity/O=themindlab hosting/CN=your.domain/[email protected] --- No client certificate CA names sent --- SSL handshake has read 1296 bytes and written 350 bytes --- New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA CHAPTER 5. SECURING SERVICES 40

Server public key is 1024 bit SSL-Session: Protocol : TLSv1 Cipher : DHE-RSA-AES256-SHA Session-ID: 3A6430067F90D570224FB94E51E678B5F81866F42A7AF21EC3B89CD119261B1A Session-ID-ctx: Master-Key: 508CEAB91173FE2A29C4E13A5B12A125F762D500878EA2C32078FEF842351FE26EC522D210993BFAF2F92475A82875C7 Key-Arg : None Krb5 Principal: None Start Time: 1093352037 Timeout : 300 (sec) Verify return code: 18 (self signed certificate) --- 220 your.domain ESMTP > ehlo there 250-your.domain 250-PIPELINING 250-8BITMIME 250 AUTH LOGIN PLAIN CRAM-MD5 > mail from: [email protected] 250 ok > rcpt to: [email protected] 250 ok > data 354 go ahead > test message . 250 ok 1093443943 qp 18664 > quit 221 your.domain closed #

In the example we first created a file which contained the commands which we would normally type in the telnet application. Then we converted the file to the DOS format. This is nessecairy because we need to send CR-LF as newline character. Openssl sends only the LF character, which is invalid in our case. Then we use the openssl program to connec to and initiate a TLS session with the smtp server. You should now check the postmaster account for email. The should be a new message. Check for the following email header in the message to verify that the message was sent encryted.

Received: from unknown (HELO there) (192.168.1.100) CHAPTER 5. SECURING SERVICES 41

by 0 with (DHE-RSA-AES256-SHA encrypted) SMTP; 24 Aug 2004 12:52:14 -0000

Configuring SMTP over SSL We will now setup a service which will be completely encrypted. This may seem unnesseceiry after enabling TLS form the smtp daemon. Some MUA’s howerver only support SSL and not TLS to retreive mail. Also, clients which support both will now be able to connect using a SSL encrypted connection, and then issue the STARTTLS command to add another layer of encryption. First we will create a directory in which we will put our global SSL configuration. This directory will be used by the envdir 5 command. We will also use this directory when setting up other SSL wrapped services.

# cd /var/qmail/control # mkdir sslenv # cd sslenv # echo /var/certs/certificate.pem > CERTFILE # echo /var/certs/privatekey.pem > KEYFILE # echo /var/certs/dh1024.pem > DHFILE

Use the following commands to create the service directories for our smtps service. Then create the two files /var/qmail/supervise/qmail-smtpsd/run and /var/qmail/supervise/qmail-smtpsd/log/run according to paragraph K.

# cd /var/qmail/supervise/ # mkdir -p qmail-smtpsd/log # chmod 1750 qmail-smtpsd

# mkdir /var/log/qmail/smtpsd # chown qmaill:qmail /var/log/qmail/smtpsd

# echo 20 > /var/qmail/control/concurrencysmtps # chmod 640 /var/qmail/control/concurrencysmtps

# echo :allow > /etc/tcp.smtps # tcprules /etc/tcp.smtps.cdb /etc/tcp.smtps.tmp < /etc/tcp.smtps

Now create the files

# cd /var/qmail/supervise # chmod 750 */run */log/run

The main run script for the qmail-smtpsd server uses a non-standard configuration file, /var/qmail/control/concurrencysmtps.

5Envdir runs a command using environment variables found in a directory CHAPTER 5. SECURING SERVICES 42

Now that all scripts are in place we can make the new service known to daemontools.

# cd /etc/daemontools/service # ln -s /var/qmail/supervise/qmail-smtpsd .

The service will be started automatically

Testing SMTP over SSL The last steps of the previous paragraph should have started the service. Use the following commands to check if the service is running and working. Commands entered by the user are prefixed with a >.

> $ openssl s_client -connect 127.0.0.1:465 CONNECTED(00000004) depth=0 /C=NL/ST=Limburg/L=SomeCity/O=The Mindlab Hosting/CN=your.server/[email protected] verify error:num=18:self signed certificate verify return:1 depth=0 /C=NL/ST=Limburg/L=SomeCity/O=The Mindlab Hosting/CN=your.server/[email protected] verify return:1 --- Certificate chain 0 s:/C=NL/ST=Limburg/L=SomeCity/O=The Mindlab Hosting/CN=your.server/[email protected] i:/C=NL/ST=Limburg/L=SomeCity/O=The Mindlab Hosting/CN=your.server/[email protected] --- Server certificate -----BEGIN CERTIFICATE----- MIICnjCCAgegAwIBAgIBADANBgkqhkiG9w0BAQQFADCBlDELMAkGA1UEBhMCTkwx EDAOBgNVBAgTB0xpbWJ1cmcxETAPBgNVBAcTCFNvbWVDaXR5MRwwGgYDVQQKExNU aGUgTWluZGxhYiBIb3N0aW5nMSIwIAYDVQQDExlnYWxhZHJpZWwudGh1aXMudW5r aWUub3JnMR4wHAYJKoZIhvcNAQkBFg9wdXN0amVuc0BkZHMubmwwHhcNMDQwODI1 MTQxNDM5WhcNMDcwODI1MTQxNDM5WjCBlDELMAkGA1UEBhMCTkwxEDAOBgNVBAgT B0xpbWJ1cmcxETAPBgNVBAcTCFNvbWVDaXR5MRwwGgYDVQQKExNUaGUgTWluZGxh YiBIb3N0aW5nMSIwIAYDVQQDExlnYWxhZHJpZWwudGh1aXMudW5raWUub3JnMR4w HAYJKoZIhvcNAQkBFg9wdXN0amVuc0BkZHMubmwwgZ8wDQYJKoZIhvcNAQEBBQAD gY0AMIGJAoGBANekcta8S2cJmoslV8GdHA/TxOXAAh/NLfyCCYb0hNybalR1ZMla XEvDVFJyMFJeFVQ88pBCmZfHNmDili5cdDW57dPoomF+qZOQpK0DaGUKyE2SbxYj TJJOmh3w3yN8EDmL/QqrTUKmcmvOxkGPGZjmAgtxf/EYUi3zO+Sib5hVAgMBAAEw DQYJKoZIhvcNAQEEBQADgYEAgHQws4ju/tfUOQNCcOxH/mWnKD/RuPG+JP4I9PY3 ugvekvkrpJQL7m8b4KobPWfz/a7G+oPW6kSkZbjko3/gz4ndN6PfTrc+xBNn728x h46jnUh3gymfpIghAECX7153mYfm3kS0Vj12AiN0JxwfRlhLax+0YEP5l4dNUWEk QxI= -----END CERTIFICATE----- subject=/C=NL/ST=Limburg/L=SomeCity/O=The Mindlab Hosting/CN=your.server/[email protected] CHAPTER 5. SECURING SERVICES 43

issuer=/C=NL/ST=Limburg/L=SomeCity/O=The Mindlab Hosting/CN=your.server/[email protected] --- No client certificate CA names sent --- SSL handshake has read 1238 bytes and written 340 bytes --- New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA Server public key is 1024 bit SSL-Session: Protocol : TLSv1 Cipher : DHE-RSA-AES256-SHA Session-ID: A6B1B8256298393A3BE6456EECEEE9C9B2672A3BA87DCB73FA046B54CAE6BFF9 Session-ID-ctx: Master-Key: 98EE0DBDE02074982F22ED304B58C0D502D9E39EAABBD7764E6E99873588AF91640FB6BDE7781329BA36E0DF9F277B7D Key-Arg : None Start Time: 1093449553 Timeout : 300 (sec) Verify return code: 18 (self signed certificate) --- 220 your.server ESMTP > quit 221 your.server closed #

You could also send a test message. At this point you should be able to figure the correct commands by yourself.

5.4.2 Sending messages, qmail-remote The possibilities to have qmail send messages are limited. The STARTTLS extension in our qmail installation is automatically enabled. This means that when a message is being delivered to a remote host, qmail-remote tries to send the STARTTLS command. When this is successfull the rest of the conversation is encrypted. Just like configuring the starttls for the smtp daemon, we only need to install a certificate to make it work.

# cd /var/qmail/control # ln -s /var/certs/servercert.pem servercert.pem

You can verify if messages are being sent encrypted when possible by sending a message to a remote server you know supports STARTTLS. There should be a header in the message similar to the following. CHAPTER 5. SECURING SERVICES 44

Received: from unknown (HELO there) (192.168.1.100) by 0 with (DHE-RSA-AES256-SHA encrypted) SMTP; 24 Aug 2004 12:52:14 -0000

5.5 Securing Pop3

Securing POP3 is mostly the same as securing SMTP. We need to wrap the service in a SSL layer.

5.5.1 Configuring POP3 over SSL Create the directories for the service scripts and log files. Then create two files, namely: /var/qmail/supervise/qmail-pop3sd/run and /var/qmail/supervise/qmail- pop3sd/log/run according to appendix L. We also need to create a new configuration file and an access database.

# cd /var/qmail/supervise # mkdir -p qmail-pop3sd/log # chmod 1750 qmail-pop3sd

# mkdir /var/log/qmail/pop3sd # chown qmaill:qmail /var/log/qmail/pop3sd

# echo 20 > /var/qmail/control/concurrencypop3s

# echo :allow > /etc/tcp.pop3s # tcprules /etc/tcp.pop3s.cdb /etc/tcp.pop3s.tmp < /etc/tcp.pop3s

Now create the files

# cd /var/qmail/supervise # chmod 750 */run */log/run

Now make the service known to daemontools.

# cd /etc/daemontools/service # ln -s /var/qmail/supervise/qmail-pop3sd .

5.5.2 Testing POP3 over SSL Using the following command you can easily test if the new POP3 over SSL service is working. openssl s_client -connect 192.168.2.200:995 -crlf

You should already know how to talk POP3 at this stage. If not, use the example in paragraph 4.3.2. CHAPTER 5. SECURING SERVICES 45

5.6 Securing IMAP

There are hardly any differences between securing POP3 and securing IMAP. The instructions below whould work perfectly if you managed to secure POP3.

5.6.1 Configuring IMAP over SSL Create the directories for the service scripts and log files. Then create two files, namely: /var/courier-imap/supervise/courier-imapsd/run and /var/courier- imap/supervise/courier-imapsd/log/run according to appendix M. We also need to create two new configuration files and an access database.

# cd /var/courier-imap/supervise # mkdir -p courier-imapsd/log # mkdir -p courier-imapsd/env # chmod 1750 courier-imapsd

# mkdir /var/log/qmail/imapsd # chown qmaill:qmail /var/log/qmail/imapsd

# cd /var/courier-imap/etc # echo 20 > concurrencyimaps # cat imapd | sed ’s/imapd.pid/imapsd.pid/; s/143/993/’ > imapsd

# echo :allow > /etc/tcp.imaps # tcprules /etc/tcp.imaps.cdb /etc/tcp.imaps.tmp < /etc/tcp.imaps

Now create the files

# cd /var/courier-imap/supervise # chmod 750 */run */log/run Now make the service known to daemontools.

# cd /etc/daemontools/service # ln -s /var/courier-imap/supervise/courier-imapsd .

5.6.2 Testing IMAP over SSL Using the following command you can easily test if the new IMAP over SSL service is working. openssl s_client -connect 192.168.2.200:993 -crlf You should already know how to talk IMAP at this stage. If not, use the example in paragraph 4.4.2. CHAPTER 5. SECURING SERVICES 46

5.7 Conclusion

During the course of this chapter, we secured the services we offer by in- stalling ucspi-ssl which makes it very easy to create a SSL wrapped ser- vice. We then used the sslserver application of this package to create SSL wrapped versions of SMTP, POP3 and IMAP. For SMTP, we also config- ured the STARTTLS extension to be fully functional during the receiving of messages, but also the sending of messages. Chapter 6

Mail Filtering

Basic mail filtering capabilities are very usefull in virtually all circumstances. In this chapter we will setup the infrastructure which allows you to write you own filters. Our infrastructure will have a global filter script, but it does allow per domain filters. We will then setup a spam filter which filters spam into a seperate mail- box. The spamfilter configuration can be defined per user, domain and globally.

6.1 Procmail

Procmail[10] is a mail processing utilty with filtering capabilities. One of the advantages of procmail is that it is fast and widely spread. The main disadvantage is its configuration language.

6.1.1 Installing The process of installing procmail is very simple. No special configuration is needed. Almost all systems allready come with a version of procmail installed. Please verify you have the latest version, 3.22 at time of writing. The following paragraphs describe how to install procmail on varions UNIX versions.

OpenBSD and FreeBSD Your ports collection has procmail. For OpenBSD you could use the follow- ing commands.

# cd /usr/ports/mail/procmail # make install

47 CHAPTER 6. MAIL FILTERING 48

Linux, RPM There are RPM’s for almost any RPM based linux. You can find RPM’s on www.rpmfind.net.

Other systems In rare situations its necessairy to compile and install procmail yourself. Use the following instructions to install procmail.

# zcat procmail-3.22.tar.gz | tar xvf - # cd procmail-3.22 # vi Makefile

When editing the Makefile, BASENAME should be /usr/local. CFLAGS should be changed to your systems cflags.

# make install ...snip... ======Would you like to skip running autoconf and use the existing autoconf.h file? When in doubt, press return [n]: n ======...snip... I will temporarily use a testdirectory named _locktest in the following directories:

/tmp .

If you would like to add any, please specify them below, press return to continue:

...snip... #

Procmail is now successfully installed.

6.1.2 Global Filter We will now make procmail a part of our mail delivery traject. We first need to create a procmail configuration file and a dot-qmail 1. file. A listing of those two files is available in appendix N. Put both files in /var/vpopmail/etc. Both files need to have their permissions set.

1Qmail reads its delivery instructions from .qmail files CHAPTER 6. MAIL FILTERING 49

# chown vpopmail:vchkpw qmail-users procmailrc # chmod 640 qmail-users procmailrc

A wrapper script for procmail is needed to translate error codes gener- ated by procmail. Create the script /var/qmail/bin/qmail-procmail accord- ing to appendixN. Also set the permissions on this script.

# chmod 755 /var/qmail/bin/qmail-procmail

Now all the needed scripts and configuration files are in place we can start altering the domains to use the new infrastructure. At this point there should be only one domain. We need to create symbalic links to the procmailrc configuration file and the qmail-users dot-qmail file. The dot- qmail files need to be linked for every mailbox. The procmailrc files only once per domain.

# cd /var/vpopmail/domains/your.domain/ # ls -la -rw------1 vpopmail vchkpw 54 Sep 2 18:42 .qmail-default drwx------3 vpopmail vchkpw 512 Aug 18 16:03 mailer-daemon drwx------3 vpopmail vchkpw 512 Aug 18 15:53 postmaster drwx------3 vpopmail vchkpw 512 Aug 18 16:03 root # ln -s /var/vpopmail/etc/procmailrc .procmailrc # for user in postmaster root mailer-daemon; do > ln -s /var/vpopmail/etc/qmail-users .qmail-$user > done #

By symlinking the configuration files you get a central place where you can change those files if the need arised. It will also leave the possibility to remove the symlink and create a specialized filter per domain. Please remember that those files must be created for every domain/user. If they are not in place no filtering is possible and delivery proceeds using the delivery instruction in the .qmail-default2 file.

6.1.3 Testing the filter Testing the filter is very simple. Just send a message to a valid email adress. E.g. [email protected]. Verify that the message has arrived. Read the message to verify its content. When reading the message also read the headers. If the message did not arrive check the qmail-send logfile to see if there were any errors. If there were no obvious errors, try a dry run of procmail like this: 2This file is automatically generated by vadddomain when creating a new virtual do- main. CHAPTER 6. MAIL FILTERING 50

# cd /var/vpopmail/etc # procmail -m -t -p \ > VERBOSE=on _HOST_=your.domain EXT=postmaster \ > procmailrc < testmessage.txt procmail: [17355] Thu Sep 2 20:38:31 2004 procmail: Assigning "_HOST_=your.domain" procmail: Assigning "EXT=postmaster" procmail: Assigning "MAILDIR=." procmail: Rcfile: "procmailrc" procmail: Assigning "HEAD=/usr/bin/head" procmail: Assigning "USERINFO=/var/vpopmail/bin/vuserinfo" procmail: Executing "test,onx,=,onx,-o,onx,=,yesx" procmail: Match on "test onx = onx -o onx = yesx" procmail: Assigning "LOGFILE=/var/vpopmail/etc/procmail.log" procmail: Opening "/var/vpopmail/etc/procmail.log" # cat procmail.log procmail: Assigning "LOGABSTRACT=all" procmail: Assigning "MAILDIR=/var/vpopmail/domains/your.domain" procmail: Executing "/var/vpopmail/bin/vuserinfo,-d,[email protected]" procmail: Assigning "_MAILDIR_=/var/vpopmail/domains/your.domain/postmaster/Maildir/" procmail: Executing "test,-d,/var/vpopmail/domains/your.domain/postmaster/Maildir/" procmail: Match on "test -d /var/vpopmail/domains/your.domain/postmaster/Maildir/" procmail: Assigning "LASTFOLDER=/var/courier-imap/bin/deliverquota -c /var/vpopmail/domains/your.domain/postmaster/Maildir/" From [email protected] Thu Sep 02 18:21:57 2004 Folder: /var/courier-imap/bin/deliverquota -c /var/vpopmail/domains/ 627 procmail: Executing "/var/courier-imap/bin/deliverquota,-c,/var/vpopmail/domains/your.domain/postmaster/Maildir/" #

As you can see you get some debugging information on the console and some in a logfile. If the dry run did not display any errors, try adding VERBOSE=on in qmail-procmail just before the HOST assignment. In this case some debugging information will get into the qmail-send logfile and some in the file /var/vpopmail/etc/procmail.log.

6.2 Basic Spamassassin Filter

No that the filtering infrastructure is in place we will add one filter; spa- massassin. Spamassassin is widely spread a tested spamfilter. Spamassassin work by testing a message against a number of spam detection algorithms. We will setup spamassassin as a daemon using the daemontools utilities. Our spamassassin configuration will allow seperate configuration per user CHAPTER 6. MAIL FILTERING 51 and domain. Also, the bayes3 database will be stored in a mySQL database for speed, and the possibility of a fallback database.

6.2.1 Installing First downaload spamassassin[11] and unpack the sourcecode somewhere convinient. Then we need to create the makefiles like in the example below. The com- mandline we use will put all spamassassin related files in /var/spamassassin/ and will also enable SSL on the spamd program. Please note that this com- mand requires some user input.

# perl Makefile.PL PREFIX=/var/spamassassin ENABLE_SSL=yes \ > SYSCONFDIR=/var/spamassassin/etc CONFDIR=/var/spamassassin/etc What email address or URL should be used in the suspected-spam report text for users who want more information on your filter installation? (In particular, ISPs should change this to a local Postmaster contact) default text: [the administrator of that system] www.themindlab-hosting.com

Checking if your kit is complete... Looks good Writing Makefile for Mail::SpamAssassin Makefile written by ExtUtils::MakeMaker 6.03 #

If you get any warnings like the one below, you can install the needed package from the CPAN4. If you get a warning that DBD::mysql was not found, install it using the instruction in appendix P.

Warning: prerequisite HTML::Parser 3.24 not found. Writing Makefile for Mail::SpamAssassin Makefile written by ExtUtils::MakeMaker 6.03 # perl -MCPAN -e shell cpan shell -- CPAN exploration and modules installation (v1.61) ReadLine support available (try ’install Bundle::CPAN’) cpan> o conf prerequisites_policy ask prerequisites_policy ask cpan> install HTML::Parser CPAN: Storable loaded ok 3A spam detection algorith which requires learning. 4Comprehensive Perl Archive Network CHAPTER 6. MAIL FILTERING 52

LWP not available CPAN: Net::FTP loaded ok Fetching with Net::FTP: ...snip... Do you want decoding on unicode entities? [no] Checking if your kit is complete... Looks good ...snip... Writing /usr/local/libdata/perl5/site_perl/i386-/auto/HTML/Parser/.packlist Appending installation info to /usr/libdata/perl5/i386-openbsd/5.8.0/perllocal.pod /usr/bin/make install -- OK cpan> quit Lockfile removed. #

Now the source can be built. First set you CFLAGS environment vari- able to your comiler flags. The build the source. Please note that the make test command requires user input, and can take a long while.

Linux:

# CFLAGS="your flags here" export CFLAGS

OpenBSD: setenv CFLAGS "your flags here"

All systems:

# make ...snip... # make test ...snip... t/body_mod...... ok t/cidrs...... ok t/db_awl_path...... ok t/db_based_whitelist...... ok t/db_based_whitelist_ips....ok ...snip... All tests successful, 8 tests skipped. Files=67, Tests=1458, 779 wallclock secs (451.19 cusr + 43.89 csys = 495.08 CPU) # make install CHAPTER 6. MAIL FILTERING 53

...snip... chmod 755 /var/spamassassin/share/spamassassin #

The spamassassin binaries and other files have now been installed in /var/spamassassin.

6.2.2 configuring spamd Default configuration file Spamassassin is now installed and needs a configuration file. This configura- tion file contains the default configuration for spamassassin. Some of the op- tions used in this file could be overwritten by the users by means of their per- sonal spamassassin configuration files. Create the file /var/spamassassin/etc/local.cf according to the listing in appendix Q.

The bayes database As said before we will store the bayes database for the baysian filter in mySQL. To make this work we need to create the database tables and add a mySQL user with access to those tables.

# cd /usr/src/Mail-SpamAssassin-3.0.0/sql/ # mysql -u root -p vpopmail < bayes_mysql.sql Enter password: # mysql -u root -p vpopmail Enter password: mysql> GRANT update, create, delete, insert, select -> ON vpopmail.* -> TO spamassassin@localhost -> IDENTIFIED BY "bayes_db"; Query OK, 0 rows affected (0.14 sec) mysql> quit Bye #

Service scripts Again the installation of the service script is almost the same as with the other services we installed. First we create directories to hold the run script and logfiles. The we create a configuration file and set permissions on the run scripts. CHAPTER 6. MAIL FILTERING 54

The files you need to create are /var/spamassassin/supervice/spamd/run and /var/spamassassin/supervice/spamd/log/run. Listings of both those files can be found in appendic O.

# mkdir -p /var/spamassassin/supervise/spamd/log # chmod 1750 /var/spamassassin/supervise/spamd

# mkdir /var/log/qmail/spamd # chown qmaill:qmail /var/log/qmail/spamd

# echo 20 > /var/spamassassin/etc/concurrencyspamd

Now create the files

# cd /var/spamassassin/supervise # chmod 750 */run */log/run

Now make the service known to daemontools.

# cd /etc/daemontools/service # ln -s /var/spamassassin/supervise/spamd .

At this point spamassassin should be running and you can proceed with testing it.

Testing spamassassin First we will copy two sample email messages from the source distribution of spamassassin. One message is spam and the other isn’t, this is very usefull for testing.

# cd /usr/src/Mail-SpamAssassin-3.0.0/ # cp sample-* /var/spamassassin/share/

Now run both messages through the spamc program. You should care- fully look at the output of these commands, as it will display the processed sample messages. In particular you need to pay attention to the X-Spam headers. Please note that the -u requires a valid username.

# cd /var/spamassassin/bin # ./spamc -u [email protected] < ../share/smaple-spam.txt ..snip... # ./spamc -u [email protected] < ../share/smaple-nonspam.txt ...snip... # CHAPTER 6. MAIL FILTERING 55

6.2.3 Adding spamc to the mail delivery process It is very easy to add spamassassin to the mail delivery process since we have a global filter file for procmailrc. In the file /var/vpopmail/etc/procmailrc, add the lines from the listing in appendix R in the center section of the file. This procmail recipe5 will first filter the message through spamc and then change the maildir if the message was identified as spam.

6.2.4 Testing Spamassassin The last step after completing the mail filter is verifying everything works. First send yourself a message from a remote system. Check your mail and verify the X-Spam headers are in the message. Now send youself a message with the string displayed below on an empty line. This string is a special string recognised by spamassassin which will mark the message as spam. Now use IMAP to see if the message was deliverd in the Spam folder. You must use IMAP, since POP3 doesn’t support folders. See the listing below for an example. User input is prefixed by a >.

> $ telnet 192.168.2.200 143 Trying 192.168.2.200... Connected to 192.168.2.200. Escape character is ’^]’. * OK [CAPABILITY IMAP4rev1 UIDPLUS CHILDREN NAMESPACE THREAD=ORDEREDSUBJECT THRE AD=REFERENCES SORT QUOTA IDLE ACL ACL2=UNION] Courier-IMAP ready. Copyright 1998 -2004 Double Precision, Inc. See COPYING for distribution information. > a1 login [email protected] test a1 OK LOGIN Ok. > a1 select INBOX.Spam * FLAGS (\Draft \Answered \Flagged \Deleted \Seen \Recent) * OK [PERMANENTFLAGS (\* \Draft \Answered \Flagged \Deleted \Seen)] Limited * 1 EXISTS * 0 RECENT * OK [UIDVALIDITY 1094247258] Ok * OK [MYRIGHTS "acdilrsw"] ACL a1 OK [READ-WRITE] Ok > a1 logout * BYE Courier-IMAP server shutting down a1 OK LOGOUT completed Connection closed by foreign host. $ 5filtering rules are called recipes in procmail. CHAPTER 6. MAIL FILTERING 56

6.3 Conclusion

During the course of this chapter we installed procmail and various script for procmail. We then intergrated procmail in the mail delivery process to make it possible to filter incoming messages. After that we install spamassassin, a spamfilter. We then setup a dae- monized version of spamassassin using the daemontools utilities. Then we modified the procmail filter to filter all messages through spamc, the psamas- sassin client. All messages which were tagged as spam are deliverd in the users Spam folder. The mailfiter created in this chapter can easily be modified to include a virusscanner or other filters. CONTINUE Bibliography

Books [1] The qmail Handbook, Dave Sill, ISBN 1-893115-40-2

Software

[2] netqmail 1.05: http://ds9a.nl/qmail/netqmail-1.05.tar.gz

[3] tls-smtpauth patch 20040705: http://shupp.org/patches/netqmail-1.05- tls-smtpauth-20040705.patch

[4] daemontools 0.76: http://cr.yp.to/daemontools/daemontools- 0.76.tar.gz

[5] ucspi-tcp 0.88: http://cr.yp.to/ucspi-tcp/ucspi-tcp-0.88.tar.gz

[6] ucspi-ssl 0.68: http://www.superscript.com/ucspi-ssl/intro.html

[7] ucspi-ssl openssl > 0.9.7 patch http://unkie.org/download.php?view.55

[8] vpopmail 5.4.5: http://sourceforge.net/projects/vpopmail/

[9] Courier-IMAP 3.0.7: http://www.courier-mta.org

[10] Procmail 3.22: http://www.procmail.org

[11] Spamassassin 3.00: http://spamassassin.apache.org/

I Appendix A

OpenBSD fstab

For OpenBSD 3.2 and higher only, almost all filesystems are mounted no- suid. This prevents suid programs to actually run suid. Qmail has various programs which need to be run suid. You can remove this mount flag by changing your fstab. This guide assumes you will install qmail in “/var/qmail”. The following line shows what the mount line for the /var filesystem looks like origionally:

/dev/wd0e /var ffs rw,nodev,nosuid 1 2

You can simple remove the part “nosuid”, and it should look like this.

/dev/wd0e /var ffs rw,nodev 1 2

II Appendix B svscanboot

#!/bin/sh # WARNING: This file was auto-generated. Do not edit!

PATH=/command:/usr/local/bin:/usr/local/sbin:/bin:/sbin:/usr/bin:/usr/sbin:/usr/X11R6/bin SERVICE=/etc/daemontools/service

#exec /dev/null #exec 2>/dev/null echo "shutting down running services..."

/etc/daemontools/command/svc -dx /etc/daemontools/service/* /etc/daemontools/service/*/log echo "restarting services ..."

{ echo "** Starting svscan on $SERVICE" env - PATH=$PATH /etc/daemontools/command/svscan /etc/daemontools/service 2>&1 } | \ env - PATH=$PATH /etc/daemontools/command/multilog t /var/log/daemontools/svscan

III Appendix C

/var/qmail/rc

#!/bin/sh

# Using stdout for logging # Using control/defaultdelivery from qmail-local to deliver messages by default

DELIVERY=‘cat /var/qmail/control/defaultdelivery‘ if [ -z "$DELIVERY" ] ; then echo "/var/qmail/control/defaultdelivery is empty or does not exist" 1>&2 exit 1 fi exec env - PATH="/var/qmail/bin:$PATH" qmail-start "$DELIVERY"

IV Appendix D

/var/qmail/bin/qmailctl

#!/bin/sh

# For Red Hat chkconfig # chkconfig: - 30 80 # description: the qmail MTA #

# Mark Pustjens 2004-08-26

# Setup some variables

PATH=/var/qmail/bin:/bin:/usr/bin:/usr/local/bin:/usr/local/sbin export PATH LOG=/var/log/qmail/qmailctl

DAEMONPATH=/etc/daemontools/ SERVICEPATH=${DAEMONPATH}service/ COMMANDPATH=${DAEMONPATH}command/ SVC=${COMMANDPATH}svc SVOK=${COMMANDPATH}svok SVSTAT=${COMMANDPATH}svstat QMAILPATH=/var/qmail/bin/ QSTAT=${QMAILPATH}qstat QSTAT=${QMAILPATH}qmail-qstat QREAD=${QMAILPATH}qmail-qread TCPRULES=/usr/local/bin/tcprules RULESPATH=/etc/

# log the date, user and tty echo ‘date‘ user ‘whoami‘ on ‘tty‘ $* >> $LOG

V APPENDIX D. /VAR/QMAIL/BIN/QMAILCTL VI

# find all mail services. services which are not found are not started. # this behaviour makes sure this script will run during every step # of the installation of the mailserver.

_SERVICES=$2 if [ -z "${_SERVICES}" -o "${_SERVICES}x" = "allx" ]; then _SERVICES="qmail-send qmail-smtpd qmail-smtpsd qmail-pop3d qmail-pop3d courier-imapd courier-imapsd" fi for SERVICE in ${_SERVICES}; do if [ -d ${SERVICEPATH}${SERVICE} ]; then SERVICES="${SERVICES} ${SERVICE}" fi done unset $_SERVICES if [ -z "${SERVICES}" ]; then echo "No (valid) service(s) specified!" exit 1; fi function usage { cat <

Where ACTION is one of: start, stop, stat, status, doqueue, alrm, flush, queue, reload, hup, pause, unpause, cont, restart, cdb, help.

USAGE echo -n "And where SERVICE is a space seperated list of one or more of: all" for SERVICE in ${SERVICES}; do echo -n ", ${SERVICE}"; done echo "." echo "SERVICE defaults to ’all’, which means the command will work for all services." echo } function help { cat <

HELP } function service_start { echo -n "starting $*: " if $SVOK ${SERVICEPATH}$*; then if [ -z ‘$SVC -u ${SERVICEPATH}$* 2>&1 | tee -a ${LOG}‘ ]; then echo "$* up" fi else echo "supervise not running in: \"${SERVICEPATH}$*\"" APPENDIX D. /VAR/QMAIL/BIN/QMAILCTL VIII fi } function service_stop { echo -n "stopping $*: " if [ -z ‘$SVC -d ${SERVICEPATH}$* 2>&1 | tee -a ${LOG}‘ ]; then echo "$* down" fi } function service_restart { echo -n "restarting $*: " if [ -z ‘$SVC -t ${SERVICEPATH}$* 2>&1 | tee -a ${LOG}‘ ]; then echo "$* restarted" fi } function service_pause { echo -n "pausing $*: " if [ -z ‘$SVC -p ${SERVICEPATH}$* 2>&1 | tee -a ${LOG}‘ ]; then echo "$* paused" fi } function service_continue { echo -n "unpausing $*: " if [ -z ‘$SVC -c ${SERVICEPATH}$* 2>&1 | tee -a ${LOG}‘ ]; then echo "$* continued" fi } function service_status { echo "checking ‘$SVSTAT ${SERVICEPATH}$* | sed "s|${SERVICEPATH}||"‘" } function service_flushqueue { echo "* scheduling EVERY message for IMMIDATE delivery..." | tee -a ${LOG} QMAILSENDUP=‘${SVSTAT} ${SERVICEPATH}qmail-send/ | grep -v "down"‘ if [ -z "${QMAILSENDUP}" ]; then echo "qmail-send is not running, impossible to requeue messages!" | tee -a ${LOG} else ${SVC} -a "${SERVICEPATH}qmail-send/" 2>&1 | tee -a $LOG echo "all messages are queued for immidiate delivery" | tee -a ${LOG} fi APPENDIX D. /VAR/QMAIL/BIN/QMAILCTL IX

} function service_readqueue { echo "* checking queue..." ${QSTAT} echo "* done checking queue" echo "* reading queue..." ${QREAD} echo "* done reading queue" } function service_reread { echo "* rereading locals and virtualdomains..." QMAILSENDUP=‘${SVSTAT} ${SERVICEPATH}qmail-send/ | grep -v "down"‘ if [ -z "${QMAILSENDUP}" ]; then echo "qmail-send is not running, impossible to reread settings!" | tee -a ${LOG} else ${SVC} -h "${SERVICEPATH}qmail-send/" 2>&1 | tee -a $LOG echo "settings reloaded" | tee -a ${LOG} fi } function service_tcprules { DB=‘echo $* | awk -F - ’{print $2}’ | sed ’s/d$//’‘ echo -n "rebuilding and reloading of access database for $*: " if [ -z ‘${TCPRULES} ${RULESPATH}tcp.${DB}.cdb ${RULESPATH}tcp.${DB}.tmp < ${RULESPATH}tcp.${DB} 2>&1 | tee -a $LOG‘ ]; then chmod 644 ${RULESPATH}tcp.${DB}.cdb echo "success"; fi }

# the main program ‘loop’ case "$1" in start) echo "* starting services..." | tee -a ${LOG} for SERVICE in ${SERVICES}; do service_start ${SERVICE}/log ; done for SERVICE in ${SERVICES}; do service_start ${SERVICE} ; done echo "* done starting services" | tee -a ${LOG} ;; stop) echo "* stopping services..." | tee -a ${LOG} for SERVICE in ${SERVICES}; do service_stop ${SERVICE} ; done for SERVICE in ${SERVICES}; do service_stop ${SERVICE}/log ; done echo "* done stopping services" | tee -a ${LOG} APPENDIX D. /VAR/QMAIL/BIN/QMAILCTL X

;; stat|status) echo "* checking services..." for SERVICE in ${SERVICES}; do service_status ${SERVICE} ; done echo "* checking logging services..." for SERVICE in ${SERVICES}; do service_status ${SERVICE}/log ; done echo "* done checking services" echo "* checking queue..." ${QSTAT} echo "* done checking queue"

;; doqueue|alrm|flush) service_flushqueue ;; queue) service_readqueue ;; reload|hup) service_reread ;; pause) echo "* pausing services..." | tee -a ${LOG} for SERVICE in ${SERVICES}; do service_pause ${SERVICE} ; done echo "* done pausing services" | tee -a ${LOG} ;; unpause|cont) echo "* unpausing services..." | tee -a ${LOG} for SERVICE in ${SERVICES}; do service_continue ${SERVICE} ; done echo "* done unpausing services" | tee -a ${LOG} ;; restart) echo "* restarting services..." | tee -a ${LOG} for SERVICE in ${SERVICES}; do service_restart ${SERVICE}/log ; done for SERVICE in ${SERVICES}; do service_restart ${SERVICE} ; done echo "* done restarting services" | tee -a ${LOG} ;; cdb) echo "* rebuilding and reloading access databases..." | tee -a ${LOG} for SERVICE in ${SERVICES}; do if [ "$SERVICE" != "qmail-send" ]; then service_tcprules ${SERVICE} fi done APPENDIX D. /VAR/QMAIL/BIN/QMAILCTL XI echo "* done rebuilding and reloading access databases" | tee -a ${LOG} ;; help) usage help ;; *) usage exit 1 ;; esac exit 0 Appendix E qmail service scripts, qmail-smtpd and qmail-send

E.1 /var/qmail/supervise/qmail-send/run

#!/bin/sh exec /var/qmail/rc

E.2 /var/qmail/supervise/qmail-send/log/run

#!/bin/sh exec /etc/daemontools/command/setuidgid qmaill \ /etc/daemontools/command/multilog t /var/log/qmail/send

E.3 /var/qmail/supervise/qmail-smtpd/run

#!/bin/sh

# Dave Sill, 2001-11-06 # For use with The qmail Handbook, ISBN 1893115402 # Slightly modified by Mark Pustjens 2004-08-24

QMAILDUID=‘/usr/bin/id -u qmaild‘ NOFILESGID=‘/usr/bin/id -g qmaild‘ MAXSMTPD=‘/usr/bin/head -1 /var/qmail/control/concurrencysmtp‘ if [ -z "$QMAILDUID" -o -z "$NOFILESGID" -o -z "$MAXSMTPD" ]; then echo QMAILDUID, NOFILESGID, or MAXSMTPD is unset in echo $0 exit 1 fi

XII APPENDIX E. QMAIL SERVICE SCRIPTS, QMAIL-SMTPD AND QMAIL-SENDXIII exec /etc/daemontools/command/softlimit -m 4000000 \ /usr/local/bin/tcpserver -v -R -H -l 0 -x /etc/tcp.smtp.cdb -c "$MAXSMTPD" \ -u "$QMAILDUID" -g "$NOFILESGID" 0 25 /var/qmail/bin/qmail-smtpd \ /var/vpopmail/bin/vchkpw /usr/bin/true 2>&1

E.4 /var/qmail/supervise/qmail-smtpd/log/run

#!/bin/sh exec /etc/daemontools/command/setuidgid qmaill \ /etc/daemontools/command/multilog t /var/log/qmail/smtpd Appendix F vpopmail.mysql

# MYSQL CONNECTION SETTINGS FOR VPOPMAIL # # Line 1 defines the connection to use for database reads, # Line 2 defines the connection to use for database updates/writes. # # If you omit line 2, then the same settings will be # used for both read and write. # # settings for each line: # host|port|user|password|database # localhost|0|vpopmail_read|password_read|vpopmail localhost|0|vpopmail_write|password_write|vpopmail # # Note: # The value of host may be either a hostname or an IP address. # If host is ’localhost’, then sockets (Unix) or named pipes (Windows) # will be used instead of TCP/IP to connect to the server.

XIV Appendix G vlimits.default

# Default limits file. This file is used for domains without a # .qmailadmin-limits file.

# maximums for each account type, -1 = unlimited maxpopaccounts 10 maxforwards -1 maxautoresponders -1 maxmailinglists 10

# quota for entire domain, in megabytes # example shows a domain with a 100MB quota and a limit of 10,000 messages #quota 100 #maxmsgcount -1

# default quota for newly created users (in bytes) # example shows a user with a 10MB quota and a limit of 1000 messages #default_quota 10485760 #default_maxmsgcount -1

# uncomment the following lines to disable certain features #disable_pop #disable_imap #disable_dialup #disable_password_changing #disable_external_relay #disable_smtp #disable_webmail

# Set bitflags on account management for non-postmaster admins. # To disable certain features, add the following bits:

XV APPENDIX G. VLIMITS.DEFAULT XVI

# Create = 1, Modify = 2, Delete = 4 # So, to allow modification but not creation or deletion of # POP/IMAP accounts, set perm_account to 5. perm_account 0 perm_alias 0 perm_forward 0 perm_autoresponder 0 perm_maillist 0 perm_quota 0 perm_defaultquota 0 Appendix H qmail service scripts, qmail-pop3d

H.1 /var/qmail/supervise/qmail-pop3d/run

#!/bin/sh MAXPOP3D=‘head -1 /var/qmail/control/concurrencypop3‘ if [ -z "$MAXPOP3D" ]; then echo MAXPOP3D is unset in echo $0 exit 1 fi exec /usr/local/bin/softlimit -m 4000000 \ /usr/local/bin/tcpserver -v -R -H -l 0 -x /etc/tcp.pop3.cdb -c "$MAXPOP3D" \ 0 110 /var/qmail/bin/qmail-popup galadriel.thuis.unkie.org /var/vpopmail/bin/vchkpw \ /var/qmail/bin/qmail-pop3d Maildir 2>&1

H.2 /var/qmail/supervise/qmail-pop3d/log/run

#!/bin/sh exec /usr/local/bin/setuidgid qmaill \ /usr/local/bin/multilog t /var/log/qmail/pop3d

XVII Appendix I qmail service scripts, courier-imapd

I.1 /var/courier-imap/supervise/courier-imapd/run

#!/bin/sh MAXIMAPD=‘head -1 /var/courier-imap/etc/concurrencyimap‘ if [ -z "$MAXIMAPD" ]; then echo MAXIMAPD is unset in echo $0 exit 1 fi

# Convert the /var/courier-imap/etc/imapd config file to an envdir cat /var/courier-imap/etc/imapd | /var/courier-imap/libexec/conf2env.sh ./env exec /usr/local/bin/envdir ./env /usr/local/bin/softlimit -m 4000000 \ /usr/local/bin/tcpserver -v -R -H -l 0 -x /etc/tcp.imap.cdb -c "$MAXIMAPD" 0 143 \ /var/courier-imap/sbin/imaplogin /var/courier-imap/libexec/authlib/authvchkpw \ /var/courier-imap/bin/imapd Maildir 2>&1

I.2 /var/courier-imap/supervise/courier-imapd/log/run

#!/bin/sh exec /etc/daemontools/command/setuidgid qmaill \ /etc/daemontools/command/multilog t /var/log/qmail/imapd

XVIII Appendix J

SMTP AUTH Extension example

Below you can see an example SMTP session where the user authenticates it- self before sending a message to an email adress which is not on this machine. The authentication itself is performed with a base64 encoded username and password. Commands entered by the user are prefixed with a >.

> $ telnet 192.168.2.200 25 Trying 192.168.2.200... Connected to 192.168.2.200. Escape character is ’^]’. 220 your.domain ESMTP ehlo there 250-your.domain 250-STARTTLS 250-PIPELINING 250-8BITMIME 250 AUTH LOGIN PLAIN CRAM-MD5 > auth login 334 VXNlcm5hbWU6 > eW91ckBlbWFpbC1hZHJlc3MuY29t 334 UGFzc3dvcmQ6 > c29tZXBhc3N3b3Jk 235 ok, go ahead (#2.0.0) > mail from: [email protected] 250 ok > rcpt to: [email protected] 250 ok > data 354 go ahead > test message

XIX APPENDIX J. SMTP AUTH EXTENSION EXAMPLE XX

> . 250 ok 1093602527 qp 14271 > quit 221 your.domain Connection closed by foreign host. $

The used username is [email protected] which equals eW91ckBlbWFpbC1hZHJlc3MuY29t when it is base64 encoded. The password is somepassword which evaluates to c29tZXBhc3N3b3Jk. Appendix K qmail service scripts, qmail-smtpsd

K.1 /var/qmail/supervise/qmail-smtpsd/run

#!/bin/sh

# Dave Sill, 2001-11-06 # For use with The qmail Handbook, ISBN 1893115402 # Modified by Mark Pustjens for ucspi-ssl

QMAILDUID=‘/usr/bin/id -u qmaild‘ NOFILESGID=‘/usr/bin/id -g qmaild‘

MAXSMTPD=‘/usr/bin/head -1 /var/qmail/control/concurrencysmtps‘ if [ -z "$QMAILDUID" -o -z "$NOFILESGID" -o -z "$MAXSMTPD" ]; then echo QMAILDUID, NOFILESGID, or MAXSMTPD is unset in echo $0 exit 1 fi exec /etc/daemontools/command/softlimit -m 4000000 \ /usr/local/bin/envdir /var/qmail/control/sslenv \ /usr/local/bin/sslserver -v -R -H -l 0 -x /etc/tcp.smtps.cdb -c "$MAXSMTPD" \ -u "$QMAILDUID" -g "$NOFILESGID" 0 465 /var/qmail/bin/qmail-smtpd \ /var/vpopmail/bin/vchkpw /usr/bin/true 2>&1

K.2 /var/qmail/supervise/qmail-smtpsd/log/run

#!/bin/sh exec /etc/daemontools/command/setuidgid qmaill \ /etc/daemontools/command/multilog t /var/log/qmail/smtpsd

XXI Appendix L qmail service scripts, qmail-pop3sd

L.1 /var/qmail/supervise/qmail-pop3sd/run

#!/bin/sh MAXPOP3SD=‘head -1 /var/qmail/control/concurrencypop3s‘ if [ -z "$MAXPOP3SD" ]; then echo MAXPOP3SD is unset in echo $0 exit 1 fi exec /usr/local/bin/softlimit -m 4000000 \ /usr/local/bin/envdir /var/qmail/control/sslenv \ /usr/local/bin/sslserver -v -R -H -l 0 -x /etc/tcp.pop3s.cdb -c "$MAXPOP3SD" \ 0 995 /var/qmail/bin/qmail-popup galadriel.thuis.unkie.org /var/vpopmail/bin/vchkpw \ /var/qmail/bin/qmail-pop3d Maildir 2>&1

L.2 /var/qmail/supervise/qmail-pop3sd/log/run

#!/bin/sh exec /usr/local/bin/setuidgid qmaill \ /usr/local/bin/multilog t /var/log/qmail/pop3sd

XXII Appendix M qmail service scripts, courier-imapsd

M.1 /var/courier-imap/supervise/courier-imapsd/run

#!/bin/sh MAXIMAPSD=‘head -1 /var/courier-imap/etc/concurrencyimaps‘ if [ -z "$MAXIMAPSD" ]; then echo MAXIMAPSD is unset in echo $0 exit 1 fi

# Convert the /var/courier-imap/etc/imapd config file to an envdir cat /var/courier-imap/etc/imapsd | /var/courier-imap/libexec/conf2env.sh ./env

# /usr/local/bin/envdir /var/qmail/control/sslenv \ echo max imapsd connections: $MAXIMAPSD exec /usr/local/bin/envdir ./env /usr/local/bin/softlimit -m 4000000 \ /usr/local/bin/envdir /var/qmail/control/sslenv \ /usr/local/bin/sslserver -v -e -R -H -l 0 -x /etc/tcp.imaps.cdb -c "$MAXIMAPSD" 0 993 \ /var/courier-imap/sbin/imaplogin /var/courier-imap/libexec/authlib/authvchkpw \ /var/courier-imap/bin/imapd Maildir 2>&1

M.2 /var/courier-imap/supervise/courier-imapsd/log/run

#!/bin/sh exec /etc/daemontools/command/setuidgid qmaill \ /etc/daemontools/command/multilog t /var/log/qmail/imapsd

XXIII Appendix N mail filter scripts

N.1 procmailrc

# How to test this procmailrc # # # cd /var/vpopmail/etc # # procmail -m -t -p \ # > VERBOSE=on _HOST_=galadriel.thuis.unkie.org EXT=postmaster \ # > procmailrc < testmessage.txt # # You’ll get some debug information on the shell and in the # file procmail.log. # # Remember to remove all messages deliverd using this testing # method. Since you must run the test as root user the messages # will get incorrect permissions.

# Set some usefull variables

HEAD="/usr/bin/head" USERINFO="/var/vpopmail/bin/vuserinfo"

# If the VERBOSE veriable is set to ’on’ or ’yes’ # we are being run from the commandline. In this # case we must log to a file. # # We must also change MAILDIR so our current # working path changes to what qmail-local # would have set.

:0

XXIV APPENDIX N. MAIL FILTER SCRIPTS XXV

*$ ? test "${VERBOSE}x" = "onx" -o "${VERBOSE}x" = "yesx" { LOGFILE="/var/vpopmail/etc/procmail.log" LOGABSTRACT="all" MAILDIR="/var/vpopmail/domains/${_HOST_}" }

# Find out the users {_MAILDIR_} location # variables EXT and HOST are imported (-p)

_MAILDIR_=‘/var/vpopmail/bin/vuserinfo -d $EXT@${_HOST_}‘/Maildir/

######################################## # Place other recipies below. ########################################

######################################## # Place other recipies above. ########################################

# Default recipy. If the mail could not be deliverd # using any of the previous recipies, deliver it # like this. # # In our case, delivery is attempted to the user if # possible, and if the user could not be found # delivery is delayed. # # The only case where the mailbox could be found is # when mySQL is down.

:0 |/var/courier-imap/bin/deliverquota -c ${_MAILDIR_}

# If all else fails, make sure we return a temorary # error code.

:0e EXITCODE=$EX_TEMPFAIL APPENDIX N. MAIL FILTER SCRIPTS XXVI

N.2 qmail-users

| /var/qmail/bin/qmail-procmail

N.3 qmail-procmail

#!/bin/sh # Copyright (c) 1998 Software in the Public Interest # Written by Philip Hands . Distributed under the GNU GPL # Modified by Mark Pustjens 02-09-2004 # $Id: qmail-procmail,v 1.2 1998/03/24 19:31:27 phil Exp $

/var/qmail/bin/preline /usr/local/bin/procmail -m -t -p _HOST_=$HOST .procmailrc && exit 0

# Explanation of the commandline: # # preline : add missing headers. # -m : accept rc file from commandline. # -t : on error return EX_TEMPFAIL, which # doesn’t drop the message. # -p : preserve environment variables. # MYHOST=$HOST : procmail does not allow to change the # HOST variable

# check if procmail returned EX_TEMPFAIL (75) [ $? = 75 ] && exit 111

# otherwise return a permanent error exit 100 Appendix O spamassassin service script, spamd

O.1 /var/spamassassin/supervice/spamd/run

#!/bin/sh

# The following environment variable may be needed # for perl 5.8 export LANG=en_US

MAXSPAMD=‘/usr/bin/head -1 /var/spamassassin/etc/concurrencyspam‘ if [ -z "$MAXSPAMD" ]; then echo MAXSPAMD is unset in echo $0 exit 1 fi

# Add the -D option to enable debugging information # Warning: this means a _lot_ of output. exec /etc/daemontools/command/softlimit -m 24000000 \ /var/spamassassin/bin/spamd \ --listen-ip=0.0.0.0 \ --allowed-ips=127.,192. \ --syslog=stderr \ --port=783 \ --pidfile=/var/run/spamd.pid \ --username=vpopmail \ --max-children="$MAXSPAMD" \

XXVII APPENDIX O. SPAMASSASSIN SERVICE SCRIPT, SPAMD XXVIII

--paranoid \ --virtual-config-dir=/var/vpopmail/domains/%d/%l/spamassassin \ --nouser-config 2>&1

O.2 /var/spamassassin/supervice/spamd/log/run

#!/bin/sh exec /etc/daemontools/command/setuidgid qmaill \ /etc/daemontools/command/multilog t /var/log/qmail/spamd Appendix P

Installing DBD::mysql using CPAN

Use the commands in the listing below to install the perl DBD::mysql mod- ule.

# perl -MCPAN -e shell cpan> get DBD::mysql Running get for module DBD::mysql CPAN: Digest::MD5 loaded ok CPAN: Compress::Zlib loaded ok Checksum for /root/.cpan/sources/authors/id/R/RU/RUDY/DBD-mysql-2.9004.tar.gz ok Scanning cache /root/.cpan/build for sizes ...snip... DBD-mysql-2.9004/TODO Removing previously used /root/.cpan/build/DBD-mysql-2.9004 cpan> look DBD::mysql # perl Makefile.PL --testuser=root --testpassword=root Running look for module DBD::mysql ...snip... Writing Makefile for DBD::mysql # make test install cp lib/DBD/mysql/GetInfo.pm blib/lib/DBD/mysql/GetInfo.pm cp lib/DBD/mysql.pm blib/lib/DBD/mysql.pm ...snip... Writing /usr/local/libdata/perl5/site_perl/i386-openbsd/auto/DBD/mysql/.packlist Appending installation info to /usr/libdata/perl5/i386-openbsd/5.8.0/perllocal.pod # exit cpan> quit #

XXIX Appendix Q

Spamassassin configuration file

######################################## # # The Mindlab Hosting # Spamassassin configuration file # # See ’perldoc Mail::SpamAssassin::Conf’ # for all possible settings. (non-root) # ######################################## version_tag unknown_03-09-2004_themindlab-hosting.com

######################################## # # Administrator Settings. # # Those cannot be overwritten by per # user/domain settings. # ######################################## bayes_store_module Mail::SpamAssassin::BayesStore::SQL bayes_sql_username spamassassin bayes_sql_password bayes_db bayes_sql_dsn DBI:mysql:vpopmail:localhost

######################################## # Privileged settings

XXX APPENDIX Q. SPAMASSASSIN CONFIGURATION FILE XXXI

# # Those cannot be overwritten by per # user/domain settings. # ########################################

######################################## # # User preferences. # # May be overwritten by the per # user/domain configuration files. # ########################################

# Settings which modify a message required_score 7.0 rewrite_header subject [SPAM] add_header spam Flag _YESNOCAPS_ add_header all Status _YESNO_, score=_SCORE_ required=_REQD_ #add_header all Level _STARS(*) add_header all Checker-Version The Mindlab Hosting spamfilter (SA 3) report_safe 1

# Settings which determine testing # methods used use_dcc 0 use_pyzor 0 use_razor2 0 skip_rbl_checks 1 use_bayes 1

# Settings for the Bayes filter use_bayes_rules 1 bayes_auto_learn 1 bayes_auto_learn_threshold_nonspam 0.10 bayes_auto_learn_threshold_spam 12.0 APPENDIX Q. SPAMASSASSIN CONFIGURATION FILE XXXII bayes_min_ham_num 100 bayes_min_spam_num 100 bayes_learn_during_report 0

# Misc settings dns_available yes Appendix R spamassassin procmail recipe

# Spamassassin filtering rules # # Explanation of the spamc options: # -p port to use # -d host tot connect to # -s maximum message size to filter # -t timeout, waits this long for spamd # -u username sent to spamd

# filter through spamassassin :0fw |$SPAMC -p 783 -d 127.0.0.1 -s 102400 -t 10 -u $EXT@${_HOST_}

# change the _MAILDIR_ to the spam folder. :0 * ^X-Spam-Status: YES { _MAILDIR_="${_MAILDIR_}.Spam/" }

# End of spamassassin filtering rules

XXXIII