My Qmail installation guide

A fresh Qmail installation on FreeBSD is something that i have to deal once a couple of years. It´s just one of those things that i could well live without, but the time will come again and usually i can’t remember of half of my previous installation…. this is my personal installation guide to do it faster and with less effort.

Why Qmail? Why FreeBSD? Well, if you come all the way into this dark corner of the Internet, you should know the answer to both… so moving on, this is a massive, uber-geek, fully comprehensive and detailed installation guide, so it takes time and some brain damage.

CAUTION: proceed at your own risk

1 – Installing daemontools

cd /usr/ports/sysutils/daemontools 
make install clean

options selected: MAN, S_NORMAL, TESTS

add to /etc/rc.conf
svscan_enable=”YES”
svscan_servicedir=”/service”

2 – Installing ucspi-tcp

cd /usr/ports/sysutils/ucspi-tcp 
make install clean

options selected: LIMITS, MANPAGES, RSS_DIFF

in fact i’m not using the limits patch, but it’s there if i want to. It offers a load limit, and a maximum connections from one IP address. Also is very easy, just set up some vars in tcp.smtp, ex:
:allow,MAXLOAD=”350″ # (the connection will be accepted only if load average is below 3.50)
:allow,MAXCONNIP=”5″ # (each IP address can get only 5 concurrent connections)

3 – Installing Qmail itself

cd /usr/ports/mail/qmail-tls 
make extract

options selected: SMTP_AUTH_PATCH, QMAILQUEUE_PATCH, OUTGOINGIP_PATCH, LOCALTIME_PATCH, MAILDIRQUOTA_PATCH, BLOCKEXEC_PATCH, DISCBOUNCES_PATCH, SPF_PATCH

In the extracting process there was a failure fetching ftp://ftp.FreeBSD.org/pub/FreeBSD/ports/distfiles/qmail/qmail-spf-rc5.patch-auth-tls, but i had it in another machine (it can be found here qmail-spf-rc5.patch-auth-tls) and just upload it to /usr/ports/distfiles/qmail/.

Also i would like to have the tarpit patch, but as this time it’s not on the port options, so i did manually.

cd /usr/ports/distfiles/qmail/
fetch http://www.palomine.net/qmail/tarpit.patch 
cd /usr/ports/mail/qmail-tls/ 
make patch 
cd work/qmail-1.03
patch -R < /usr/ports/distfiles/qmail/tarpit.patch 
cd ../../ 
make install clean

Then make and install the certificate, we could use the port handy make target ‘make certificate’ that would generate and place a concatenated file in PEM format with a RSA key and a self signed certificate on /var/qmail/control/servercert.pem (as required by the TLS patch). But we would loose the key file and the certificate file, that we will use in other mail services and of course the insight of what is going on:

cd /var/qmail/control
openssl genrsa -out server.key 1024
openssl req -new -key server.key -out server.csr
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
cat server.key server.crt > servercert.pem

4 – Autorespond

This is hard…

cd /usr/ports/mail/autorespond 
make install clean

5 – Ezmlm

This is also very hard…

cd /usr/ports/mail/ezmlm-idx
make install clean

options selected: none

6 – Vpopmail (with MySQL integration)

edit /etc/make.conf and add these lines

# Vpopmail
.if ${.CURDIR:M*/usr/ports/mail/vpopmail*}
WITH_CLEAR_PASSWD=1
WITH_MYSQL=1
WITH_MYSQL_LIMITS=1
WITH_VALIAS=1
WITHOUT_ROAMING=1
WITH_SINGLE_DOMAIN=1
LOGLEVEL="p"
.endif

save, exit, and

cd /usr/ports/mail/vpopmail
make install clean

The compilation process will also include the mysql client, in the options i disabled the SSL option as all the database access will be on the same server.

One really bad thing of vpopmail port is that installs everything in /usr/local/vpopmail (ala ports and freebsd hier), but usually /usr/local/ lives in the boot partition (slice in FreeBSD wonderland) / which is a small partition and outside the backups system. So i usually move this to the /home partition…

mv /usr/local/vpopmail 
/home/ ln -s /home/vpopmail /usr/local/vpopmail

and change the home directory to /home/vpopmail

chpass vpopmail

Next you should fire up your MySQL server create a new database and a user with privileges and edit /usr/local/vpopmail/etc/vpopmail.mysql with host|port|user|password|database settings.

7 – Set-up main alias

Define the root, postmaster and mailer-daemon aliases to a account that you WILL later create

cd /var/qmail/alias 
echo "myaccount@mydomain.com" > .qmail-root 
echo "myaccount@mydomain.com" > .qmail-postmaster 
echo "myaccount@mydomain.com" > .qmail-mailer-daemon

8 – Qmail configurations (control files)

Go to the control directory to set up qmail configurations

cd /var/qmail/control

The qmail-tls places the servercert under the normal qmaild user, but as we are going to use vpopmail, chown it.

chown vpopmail:vchkpw /var/qmail/control/servercert.pem

If you skip this starttls will not work correctly with the error:
454 TLS missing certificate: error:0200100D:system library:fopen:Permission denied (#4.3.0)

Empty the rcpthosts file. It’s filled with assigned domains to the server own IPs on install. This files controls the domains that we accept as local. If the domain of the address given in the RCPT TO command is listed here Qmail will accept the email, else it will (or not) relay it to other server.

cp /dev/null rcpthosts

Set the maximum simultaneously incoming emails, remember that SpamAssassin can eat up lots of resources, concurrencyincoming isn’t a standard qmail control file, we will be using it in the qmail-smtpd run script.

echo "20" > concurrencyincoming

Used from qmail-send, is the maximum number of simultaneous local delivery attempts (defaults to 10), i guess it makes sense to be at last as big as concurrencyincoming.

echo "20" > concurrencylocal

Again used by qmail-send, set up concurrencyremote (defaults to 20), max simultaneous remote deliveries.

echo "30" > concurrencyremote

Set-up default delivery to Maildir (this is read by /var/qmail/rc, that is executed by qmail-send run script).

echo "./Maildir" > defaultdelivery

Config the defaultdomain, it defaults to “me” control (a bit lower in this guide), and it is used by qmail-inject.

echo "domain.com" > defaultdomain

i really don’t quite understand the difference between envnoathost and defaultdomain, so i set-up the same value.

echo "domain.com" > envnoathost

and plusdomain, is used where the domain ends wirh a trailing + (plus sign) ??, i quite also don’t get why a domain is not in the normal host.domain.ext but like domain+, but if it does qmail-inject will use this value.

echo "domain.com" > plusdomain

Empty locals, because all domains will be in the virtual system.

cp /dev/null locals

Define “me”, this will be used in several places, and you will want to use a fqdn (and set up a reverse dns entry with the same value. Change this to your own fqdn (please don’t use mine). Also, it is a good idea to add this as an alias of your defaultdomain (if not the same).

echo "mail.domain.com" > me

If you want to customize the outgoing ip of your qmail, it defaults to your main, set up outgoingip control file. Again, remember to set up dns and reverse according, so your sent email doesn’t end up in spam folder.

echo "a.b.c.d" > outgoing

I lower the queue lifetime (defaults to 604800 secs = a week) to a much lower value (a day). It the mail doesn’t get delivered in one day it bounces back.

echo "86400" > queuelifetime

also timeoutsmtpd and timeoutremote (they timeout only after a massive 20 minutes), to a much lower value

echo "120" > timeoutsmtpd 
echo "120" > timeoutremote

The default SPF record behavior. Will go with 4 (reject mails when SPF resolves to softfail). We can override this by source in /etc/tcp.smtp The full options are:
0: Never do SPF lookups, don’t create Received-SPF headers
1: Only create Received-SPF headers, never block
2: Use temporary errors when you have DNS lookup problems
3: Reject mails when SPF resolves to fail (deny)
4: Reject mails when SPF resolves to softfail
5: Reject mails when SPF resolves to neutral
6: Reject mails when SPF does not resolve to pass

echo "4" > spfbehavior

Configure tarpitting, from the patch website “tarpitcount is the
number of RCPT TOs you accept before you start tarpitting, and tarpitdelay is
the number of seconds of delay to introduce after each subsequent RCPT TO.”

echo "50" > tarpitcount echo "10" > tarpitdelay 

Create tlsclientciphers and tlsserverciphers, these files have the available ciphers to client and server TLS communications.

openssl ciphers > /var/qmail/control/tlsclientciphers
openssl ciphers > /var/qmail/control/tlsserverciphers

Setup /etc/tcp.smtp, the compiled in cdb format of this file is used by tcpserver (that listens for incoming smtp connections and launches qmail-smtp) to setup variables that customize qmail behaviour and accept or reject incoming connections. You can find a template here, that must be customized to your needs (at least the IPs). Some stuff in this file will be more clear down this tutorial. After customization compile it to a cdb file.

tcprules /etc/tcp.smtp.cdb /etc/tcp.smtp.tmp < /etc/tcp.smtp

9 - Qmail start-up scripts and directories

cd /var/qmail/
edit rc

and copy rc file content save and mark it executable

chmod +x rc

create the daemontools scripts directories

mkdir -p supervise/qmail-pop3d/log
mkdir -p supervise/qmail-smtpd/log
mkdir -p supervise/qmail-send/log

and log directory (each service will automagically create it's own subdirectory on startup)

mkdir -p /var/log/qmail
chown qmaill /var/log/qmail

create qmail-pop3 run script, change the IP to where the pop3 daemon will listen for incoming connections and mark it executable

cd /var/qmail/supervise/qmail-pop3d 
edit run 
chmod +x run

now qmail-pop3-log, you can customize 's' the number of max bytes of each log file, and 'n' the number of log files to keep before rotating. I use the max value for bytes - 16777215 (16Mb) and keep 5 files. So each service will keep about 80Mb worth of logs.

cd /var/qmail/supervise/qmail-pop3d/log 
edit run 
chmod +x run

A note about djb multilog date format, they are in strange (precise) timestamp, like this @400000004fff531605fc768c. To convert it to something human readable you can use tai64nlocal. Ex:

tail -f /var/log/qmail/qmail-smtpd/current | tai64nlocal

Now do the same for qmail-send (run and log) and qmail-smtpd (run and log script).

In qmail-smtpd run please set the correct ip address, and it may be necessary to change the softlimit value, max memory in bytes used per qmail-smtpd run (more on this later).

10 - Stop sendmail, replace sendmail with qmail and start qmail

/etc/rc.d/sendmail stop

and make it permanently in /etc/rc.conf

# Disable Sendmail
sendmail_enable="NO"
sendmail_submit_enable="NO"
sendmail_outbound_enable="NO"
sendmail_msp_queue_enable="NO"

FreeBSD comes with a mailwrapper that is used system wide by mail user programs (MUAs), so no need to symlink to the sendmail binary, just adjust mailer.conf and be confident that all programs will use qmail

Edit /etc/mail/mailer.conf with these:

sendmail        /var/qmail/bin/sendmail
send-mail       /var/qmail/bin/sendmail
mailq           /var/qmail/bin/qmail-qread
newaliases      /var/qmail/bin/newaliases
hoststat        /var/qmail/bin/qmail-tcpto
purgestat       /var/qmail/bin/qmail-tcpok

Now link the startup scripts to the /service dir to startup Qmail.

ln -s /var/qmail/supervise/* /service/

Download and put somewhere qmailctl, a pretty neat bash script that makes life much more easier to start, stop, make the cdb file, flush the queue, etc.

wget http://www.marcogoncalves.com/wp-content/uploads/2012/08/qmailctl
mv qmailctl /usr/local/bin/
chown +x /usr/local/bin/qmailctl

11 - Test the basic qmail setup

Now, we should have a functional email system. Some features are still missing, but this is the core and this is the time to taste it before adding extra layers.

Stop/start/stat qmail

qmailctl stop
qmailctl start
qmailctl stat

Create a dummy domain, list it and remove it

vadddomain dummy.com
vmoddomlimits -S dummy.com
vdeldomain dummy.com

If all goes nice and smooth, configure a real domain at vpopmail, configure DNS mx and test it. Send and reception of email within local accounts and remote accounts. Emails with attachments of different sizes. SMTP with TSL and without, etc. Most problems can be debugged with the aid of the logs in /var/log/qmail/* or telnet the service. Check the quota system, if the maildirsize (/home/vpopmail/domains/domain.com/user/Maildir/maildirsize) is correctly updated on each operation.

Actually i found myself a big no-no, because on email reception vpopmail was writing two times the same email in the maildirsize hence reporting a double usage of quota... i trace this with a help of Google™ and found a bug report that help me solve the problem. With a bit of source code edit, re-compilation and re-installation of vpopmail all was fine.

12 - Install Qmailadmin

Qmailadmin is a web interface for managing the domains emails by domain administrators. It's a bit old school, uses cgi interface to a elf binary, and the layouts suck. But for now is the best tool that just works out of the box.

You must have Apache running (the qmailadmin binary is setuided to change on call to the vpopmail:vchkpw user) but i rather like mpm-itk to set the user at virtualhost level), mod_cgi or mod_cgid, and if you want clean url's mod_rewrite.

First create a home directory to qmailadmin

cd /home
mkdir qmailadmin
cd qmailadmin
mkdir logs

The port install is a bit awkward because we can't configure all with make.conf and we will make changes in the Makefile.

cd /usr/ports/mail/qmailadmin
edit Makefile

and make these changes

CGIBINDIR?= /home/qmailadmin/cgi-bin
CGIBINSUBDIR?=
CGIBINURL?= /
WEBDATADIR?= /home/qmailadmin/www
WEBDATASUBDIR?=
WEBDATAURL?=
MAXUSERSPERPAGE?= 15
MAXALIASESPERPAGE?= 25

and also

CONFIGURE_ARGS+= \
--enable-qmaildir=${QMAIL_PREFIX} \
--enable-htmldir=${WEBDATADIR} \
--enable-imagedir=${WEBDATADIR}/images \
--enable-imageurl=/images \
--enable-htmllibdir=/home/qmailadmin/templates \
--enable-cgibindir=${CGIBINDIR} \
--enable-cgipath=/cgi-bin \
--enable-vpopmaildir=${VPOPMAIL_DIR} \
--enable-autoresponder-path=${LOCALBASE}/bin \
--enable-maxusersperpage=${MAXUSERSPERPAGE} \
--enable-maxaliasesperpage=${MAXALIASESPERPAGE} \
--enable-ezmlmdir=${LOCALBASE}/bin

exit and save.

make install clean

and select CATCHALL, IDX, IPAUTH, TRIVIAL PASSWORD, USER_INDEX

cd /home
chown -R vpopmail:vchkpw qmailadmin
cd /home/qmailadmin/cgi-bin/
mv qmailadmin qmailadmin.cgi
chmod 550 qmailadmin.cgi

If you don't have mod-itk in Apache DON'T chmod qmailadmin.cgi file (that is leave the sticky bit on). Now for the Apache Virtualhost:

<VirtualHost aaa.bbb.ccc.ddd:80>
    ServerName email.domain.com
    DocumentRoot "/home/qmailadmin/cgi-bin/"
    CustomLog "/home/qmailadmin/logs/access.log" combined
    ErrorLog "/home/qmailadmin/logs/error.log"

    AssignUserId vpopmail vchkpw
    
    <Directory "/home/qmailadmin">
        Order deny,allow
        Allow from all
    </Directory>

    # Rewrite
    RewriteEngine on
    RewriteCond   %{REQUEST_URI}    !(images)   [NC]
    RewriteRule   ^/cgi-bin(.*)$  /qmailadmin.cgi/$1   [L]

    DirectoryIndex qmailadmin.cgi
    Options +ExecCGI
    AddHandler cgi-script cgi
    Alias /images/ /home/qmailadmin/www/images/
</VirtualHost>

restart Apache, and point your browser to ServerName to test qmailadmin. You can (kind of) customize the templates in /home/qmailadmin/templates/html.

13 - Install Imap Server

For the IMAP services we will be using Dovecot, a fast and secure imap server. It will be used mainly by the webmail and also by mobile devices. The installation? Quite simple, again thanks to the fabolous ports system.

cd /usr/ports/mail/dovecot2
make install clean

select DOCS, EXAMPLES, KQUEUE, SSL, VPOPMAIL

Add dovecot_enable="YES" to /etc/rc.conf.

Now for the configuration, the Dovecot is a highly configurable IMAP and POP server and that has a price, lots and lots of configurations options to consider. We will be using only the IMAP, as the POP service is provided by qmail-pop3d, also we want to have a SSL aware server for encrypted sessions in untrusted environments.

One must keep in mind that Vpopmail quota system doesn't account emails flagged as deleted or in the Trash folder (this is default in the Courier suite maildir++ implementation). As i didn't found any Vpopmail switch equivalent to the -with-trashquota in Courier to account emails in Trash, we have to enforce the same behavior in Dovecot (to discard deleted emails for quota calculations). We will also automagically create for the user the Trash, Junk, Drafts and Sent folders.

The port places at /usr/local/share/doc/dovecot/example-config all configuration files with all options from where you can jump start building your own custom configuration, but as a nice and friendly guy i am, my own configuration is posted here, if you are following this guide you only need download it, extract it to /usr/local/etc/dovecot/ and set the correct Listen IP address in dovecot.conf. How cool is that?

We will be using the certificate and key that we generated for qmail, so /var/qmail/control/server.crt and /var/qmail/control/server.key must exist.

Go ahead, customize the Dovecot configuration. And then fire it up:

/usr/local/etc/rc.d/dovecot start

Now test with an IMAP client or with telnet. Delete messages (or move to Trash folder) and check the quota. Logging is done to /var/log/mailog. To test the SSL features you can use a handy little ssl client that is bundled with openssl:

openssl s_client -crlf -connect aaa.bbb.ccc.ddd:993

With the IMAP server up and running is very easy to add an webmail to your system, i like a lot the excellent Roundcube webmail project.

14 - POP3 and SMTP over SSL

In current times, when users rely more and more on laptops, tablets and mobile devices to get things done through all kind of non-secure networks (think public Wi-Fi), it's very important to provide encryption and to educate your users to the importance of using it.

To add SSL support to POP3 and to SMTP (already has TLS but is quite easy to provide SSL too), we must install a handy little SSL proxy that will take care of the SSL layer transparently. We will install this (you guessed it) using the ports system:

cd /usr/ports/security/stunnel/
make install clean

options selected: PTRHEAD

now create the stunnel pop3 configuration file. Edit /usr/local/etc/stunnel/pop3.conf script (download it here) and replace the mail.domain.com after qmail-popup with the value you have in /var/qmail/control/me (unfortunately i couldn't find way to inject this in the configuration file, so if you change it you must change it here also...).

Next, it's just like step 9, just create /var/qmail/supervise/qmail-pop3ds and /var/qmail/supervise/qmail-pop3ds/log directories and put there the correspondent run scripts.

cd /var/qmail/supervise
mkdir qmail-pop3ds/log

the /var/qmail/supervise/qmail-pop3ds/run script will call stunnel that will take care of the SSL layer (remember to customize the IP address). And of course the /var/qmail/supervise/qmail-pop3ds/log/run script to take care of the logging. Mark both files as executable and your are ready to SSL.

Make a symbolic link to /services to fire the service up and you can test it with openssl

ln -s /var/qmail/supervise/qmail-pop3ds /service/qmail-pop3ds
svstat /service/qmail-pop3ds
openssl s_client -crlf -connect aaa.bbb.ccc.ddd:995

and you should be in an encrypted POP3 session. Now for the SMTP over SSL is just the same logic here are the files you need:
/usr/local/etc/stunnel/smtp.conf
/var/qmail/supervise/qmail-smtpds/run
/var/qmail/supervise/qmail-smtpds/log/run

and another treat, an updated qmailctl file accounting the new encrypted services.

15 - Clam Anti Virus, Spam Assassin and Qmail-scanner

We will install ClamAV an awesome open source anti-virus, SpamAssassin from Apache foundation as a spam filter and qmail-scanner to glue this stuff together with qmail.

First thing, ClamAV

cd /usr/ports/security/clamav
make install clean

options selected: ARC, ARJ, DOCS, ICONV, LHA, LLVM, TESTS, UNRAR, UNZOO

Add the rcvars to /etc/rc.conf
clamav_clamd_enable="YES"
clamav_freshclam_enable="YES"

and fire it up, the configuration dafaults should be good for both clamd (the ClamAV daemon) and the freshclamd (the virus definition database updater daemon).

Now, for the SpamAssassin

cd /usr/ports/mail/p5-Mail-SpamAssassin
make install clean

options selected: SPAMC, DKIM, GNUPG, RAZOR, DCC

like clamav, the configuration defaults should be fine. Just a tweak in rc.conf to rest assured that users can't mess up our system. So, put into /etc/rc.conf:

spamd_enable="YES"
spamd_flags="--nouser-config --username=spamd"

this is actually something that i want to change in the future, to be able to give to users the possibility of customizing SpamAssassin for their own accounts/domains.

Run the rules updater to see if everything goes well and start it up.

sa-update -v
/usr/local/etc/rc.d/sa-spamd start

we should put the ruleset in a periodic script, edit /usr/local/etc/periodic/daily/spamd and paste

#!/bin/sh
#
# Updates Spamassassin rules
#

PATH=/etc:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin

/usr/local/bin/sa-update -v && /usr/local/etc/rc.d/sa-spamd restart

rc=0
exit $rc

And now, the glue of all this, the qmail-scanner script. The best way that i found was to customize was to edit the Makefile of the port. So edit /usr/ports/mail/qmail-scanner/Makefile and change the configure args to:

CONFIGURE_ARGS+= \
--qmaildir "${QMAIL_PREFIX}" \
--spooldir "${SPOOLDIR}" \
--etcdir "${SPOOLDIR}" \
--logdir "${SPOOLDIR}" \
--bindir "${PREFIX}/bin" \
--qmail-queue-binary "${QMAIL_QUEUE}" \
--mime-unpacker "reformime" \
--no-QQ-check \
--batch \
--log-details yes \
--sa-quarantine "10" \
--unzip yes \
--add-dscr-hdrs yes \
--scanners "clamdscan,mhr,fast_spamassassin=SPAM:"

we are adding several options, the first "log-details" discards syslog and logs to a nice csv formatted (that we can later parse for statistics) file in /var/spool/qscand/mailstats.csv, next "sa-quarantine" gets an identified spam message to get quarantined if the spam score is bigger than 10 (adjustable). The "unzip" option makes the qmail-scanner to unzip the attachments, it makes more sense to unzip it once and then feed the uncompressed attachments to Spamassassin and Clamav than to let each one them to do their own unzip. The "add-dscr-hdrs", adds X-Qmail-Scanner headers to the message (this is good to check fast if a message has passed trough the system.

And finally the strangest option --scanners "clamdscan,mhr,fast_spamassassin=SPAM:", normally the Qmail-scanner configuration script auto-detects and configures for the filters installed in the system but we need to override to have the subject rewritten for emails that have been scored high enough to be marked by SpamAssassin but not as high to quarantine them. The required score for an email be declared as spam by SpamAssassin is 5 (it can be adjusted in /usr/local/etc/mail/spamassassin/local.cf with the required_score option).

So, with these options:

Email scoring < 5 is normally delivered Email scoring > 5 and < 10 is delivered with the subject rewritten to "SPAM:original subject" Email scoring > 10 is automatic quarantined to /var/spool/qscand/quarantine/spam Maildir and not delivered

Now we must adjust the permissions, /var/spool/qscand is the directory that all the action takes in, and the both SpamAssassin and Clamav will work here, the best solution i have found is to change both the daemon users group to qscand. Find the qscand group in /etc/group (in my system is 98) and then use chpass or equivalent to change the spamd and clamav user.

chpass clamav
chpass spamd

and change the Gid to 98 (the group id of qscand that you checked in /etc/group).

One strange thing with qmail-scanner is that for local users it bypasses SpamAssassin checks, but for authenticated users it doesn't... when an user is authenticated we have the TCPREMOTEINFO environment variable set so we can check it.

Open /usr/local/bin/qmail-scanner-queue.pl and find "sub spamassassin {" around line 2697 and change:

sub spamassassin {
  #Don't bother if this is going to be quarantined
  return if ($quarantine_event);

  #Only run SA if mail is from a "remote" SMTP client, or QS_SPAMASSASSIN
  #is defined via tcpserver...
  if ($QS_RELAYCLIENT && !$ENV{'QS_SPAMASSASSIN'}) {
    &debug("spamassassin: don't scan as RELAYCLIENT implies this was sent by a local user");
    return;
  }

to

sub spamassassin {
  #Don't bother if this is going to be quarantined
  return if ($quarantine_event);

  #Only run SA if mail is from a "remote" SMTP client which is not SMTP athenticated, or QS_SPAMASSASSIN
  #is defined via tcpserver...
  if (!$ENV{'QS_SPAMASSASSIN'}) {
    if ($QS_RELAYCLIENT){
      &debug("spamassassin: don't scan as RELAYCLIENT implies this was sent by a local user");
      return;
    }
    if ($ENV{'TCPREMOTEINFO'}){
      &debug("spamassassin: don't scan as TCPREMOTEINFO implies this was sent by a SMTP AUTHenticated user");
      return;
    }
  }

And that does the trick.

Update 28-04-2013
In my latest Qmail install, with qmail-scanner-2.10, this is not needed anymore, as qmail-scanner-queue.pl as been updated to get the authenticated users into consideration. The code isn't exactly the same as i proposed (it should be better) but the end result is the same. So, no need to hack qmail-scanner-queue.pl and emails from authenticated users skip by apam checks.

A little extra configuration that must be done is the internal qmail-scanner filter rules. Copy quarantine-events.txt.sample to quarantine-events.txt and open it.

cd /var/spool/qscand
cp quarantine-events.txt.sample quarantine-events.txt

The file is well commented and by itself it blocks some virus and spam without the need to call external Spam-Assassin and Clamav. It works out of the box without any customization. Then it must be compiled to Berkeley DB format.

/usr/local/bin/qmail-scanner-queue.pl -g

Next, we must update our /etc/tcp.smtp to use our anti-spam system, we compiled Qmail with the qmailqueue patch that easily allows us to change to the qmail-scanner-queue. Updated tcp.smtp here. Then compile it to cdb format that is used by tcpserver.

qmailctl cdb

And finally, the system anti-spam system maintenance. First we need to delete the old quarantined messages, a periodic script will be fine, so edit /usr/local/etc/periodic/daily/clear-quarantined-emails and paste:

#!/bin/sh
#
# Deletes old quarantined emails by qmail-scanner and and cleanup old temp files 
#

/usr/bin/find /var/spool/qscand/quarantine/* -type f -mtime +10 -exec /bin/rm -f {} \;
/usr/local/bin/qmail-scanner-queue -z

rc=0
exit $rc

and for the log rotation, we will use newsyslog (Linux folks should check logrotate). Edit /etc/newsyslog.conf and add a couple of lines, to rotate every day at 6am and keep 3 bzip2 compressed historical files.

/var/spool/qscand/quarantine.log  qscand:qscand   640  3     *    $D6   JCB
/var/spool/qscand/qmail-queue.log qscand:qscand   640  3     *    $D6   JCB
/var/spool/qscand/mailstats.csv   qscand:qscand   640  3     *    $D6   JCB

16 - Adjust softlimit

In the qmail-smtpd run script (and qmail-smtpds for SMTP over SLL), there is an 100 Megabytes memory limit, this was set-up deliberately high to avoid any problems during the installation, but now is time to adjust it to a correct value. Each system is different, and has different memory requirements, so to adjust it:

1 - set the SOFTLIMIT down in the run script
2 - restart Qmail
3 - try to send an email trough SMTP or SMTP over SLL till you get '451 qq temporary problem (#4.3.0)' or on smtp-auth login '/libexec/ld-elf.so.1: /usr/lib/libstdc++.so.6: mmap of data failed: Cannot allocate memory'
4 - when that happens start to incrementally raise the limit
5 - don't forget to restart Qmail on each increment
6 - when the '451' error code goes away add a couple of Megabytes more.

Congratulations, you have make it all the way, by now you should be a proud system administrator with a full featured email system installed on your FreeBSD box. But you can (should) go the extra mile.

2 thoughts on “My Qmail installation guide”

Leave a Reply