Post.Office & SpamAssassin

Post.Office Tips & Tricks: Index

Tenon included SpamAssassin in build 720 of Post.Office 3.5.3. However the documentation for SpamAssassin was very limited. Therefore I wrote this installation guide for SpamAssassin and Post.Office. I posted those tips and tricks on the Post.Office mailing list but I thought it would be better to provide a web page with it as well -- this makes it easier to copy the various scripts and to print the instructions.

Here's my preliminary setup information for SpamAssassin under Post.Office


Before you start

Make sure to keep the messages filtered by your SMTP body/header filters. You need 1000-5000 messages to train SpamAssassin's Bayesian Filtering. The default setup of SpamAssassin says that only 200 messages are needed but you'll get better results with more messages. The training process is done with the "sa-learn" command line tool. You also need to feed good messages to SpamAssassin (called "ham"). The easiest way would be to use Apple Mail to hand-sort your messages into a Spam and a Ham folder for training purposes. This works nicely if you are using IMAP and Apple Mail to sort the messages directly on the server.


Security Settings

The default Post.Office installation runs spamd (the SpamAssassin daemon) as root user. Personally, I prefer to run spamd as a different user for security reasons.

So we need to create a new user and modify the Post.Office startup script to always launch spamd with the new user.

SpamAssassin User Account

You can use different ways to create a user. I used the Workgroup Manager as I run MacOS X Server. Make sure to create an unprivileged user, i.e. with no administrator rights. You might need to create the home directory and set the default shell.

Here's a quick shell script which should do the trick... some parts of it were taken from Tenon's iTools 6 adduser script -- I adapted it to add a user called spamd -- please see the first couple of line for settings (username, password,...)

#!/bin/sh
######################################
# Lets check if user is already added
######################################
full_name="SpamAssassin"
myclientid="spamd"
myclientpw="Spam123qwerty"
shell="/bin/tcsh" home="/Users/$myclientid" guid=20 ttt=`niutil -list . /users | awk '{print $2}' | egrep ^$myclientid` if [ "$myclientid" = "$ttt" ]; then echo "Warning! user exists already" exit fi shift uid=1000 TMPUID=`nidump passwd . | grep $uid | cut -f 3 -d :` while [ ! -z $TMPUID ] do let "uid +=1" TMPUID=`nidump passwd . | grep $uid | cut -f 3 -d :` done niutil -create . /users/$myclientid niutil -createprop . /users/$myclientid uid $uid niutil -createprop . /users/$myclientid gid $guid niutil -createprop . /users/$myclientid shell $shell niutil -createprop . /users/$myclientid home $home niutil -createprop . /users/$myclientid realname "$full_name" niutil -createprop . /users/$myclientid _shadow_passwd #niutil -createprop . /users/$myclientid sharedDir Public niutil -createprop . /users/$myclientid passwd `openssl passwd -crypt $myclientpw` if [ ! -d $home ]; then mkdir $home chown ${myclientid}:staff $home chmod 777 $home fi mkdir -p ${home}/.spamassassin cp /usr/share/spamassassin/user_prefs.template ${home}/.spamassassin/user_prefs chown -R ${myclientid}:staff $home #end

If you used the script above, then the SpamAssassin user_prefs have been copied to the spamd home directory. If you didn't create the user with the script, then you should run the following 3 commands from the terminal (as root) to create the SpamAssassin preference folder and copy the default preferences:

mkdir -p /Users/spamd/.spamassassin
cp /usr/share/spamassassin/user_prefs.template /Users/spamd/.spamassassin/user_prefs
chown -R spamd:staff /Users/spamd/

Now that the user has been created, we'll change the Post.Office startup script to use the new user to launch spamd. Use your favorite (command line) editor to edit /Library/StartupItems/PostOffice/PostOffice

Startup Item

Here's the startup script as I use it -- I changed the /usr/bin/spamd& to /usr/bin/spamd -u spamd -d -r /var/run/spamd.pid

This sets the user to spamd (-u spamd), runs SpamAssassin as a daemon (-d) and creates a pid file with the process id (-r /var/run/spamd.pid)

#!/bin/sh

. /etc/rc.common

##
# Start mail server
##

POSTOFFICE=-YES-
if [ "${MAILSERVER:=-NO-}" = "-YES-" ]; then
    ConsoleMessage "Disable existing mail server and reboot to run Post.Office"
else
    if [ "${POSTOFFICE:=-NO-}" = "-YES-" ]; then
        if [ -f /Library/Tenon/System/Configuration/StartUp ]; then
            MAILSERVER=`grep MAILSERVER /Library/Tenon/System/Configuration/StartUp | cut -b 12-`;
            if [ "$MAILSERVER" = "-YES-" ]; then
                ConsoleMessage "Starting Post.Office mail services"
                if [ -f /usr/bin/spamd ]; then
                    /usr/bin/spamd -u spamd -d -r /var/run/spamd.pid
                fi
                /usr/local/post.office/post.office
            fi
        else
            ConsoleMessage "Starting Post.Office mail services"
            if [ -f /usr/bin/spamd ]; then
                /usr/bin/spamd -u spamd -d -r /var/run/spamd.pid
            fi
            /usr/local/post.office/post.office
        fi
    fi
fi

As I'm very concerned about security, I also modify my sshd_config file to make sure that nobody can log into my server using the spamd user account. Therefore I use the DenyUsers directive. The following command will append the right syntax to your ssh configuration:

echo "DenyUsers spamd" >> /etc/sshd_config

(You can also just limit the login possibility to a few account by using "AllowUsers user1 user2"... all other users will be denied to log in)


SpamAssassin Configuration

Now it's time to have a look at the SpamAssassin configuration. These are just a few steps to make sure Bayesian filtering works.

The default configuration of SpamAssassin is located in /usr/share/spamassassin/. You should not edit those rules directly, but create a local configuration instead.

SpamAssassin will look into /etc/mail/spamassassin/ for the local side-wide configuration.

You can copy the default configuration to the side-wide directory by using these commands:

mkdir -p /etc/mail/spamassassin
cp /usr/share/spamassassin/10_misc.cf /etc/mail/spamassassin/local.cf

Edit local.cf to suit your needs... You could create your own configuration file using the online SpamAssassin config tool at: http://www.yrex.com/spam/spamconfig.php

# SpamAssassin config file for version 2.5x
# generated by http://www.yrex.com/spam/spamconfig.php (version 1.01)

# How many hits before a message is considered spam.
required_hits           5.4 

# Whether to change the subject of suspected spam
rewrite_subject         1
always_add_headers      1

# Text to prepend to subject if rewrite_subject is used
subject_tag             *****SPAM*****

# Encapsulate spam in an attachment
report_safe             1

# Use terse version of the spam report
use_terse_report        0

# Enable the Bayes system
use_bayes               1
bayes_path              /Users/spamd/.spamassassin/bayes

#bayes_expiry_max_db_size 80000

# Enable Bayes auto-learning
auto_learn              1
auto_learn_threshold_nonspam    -2
auto_learn_threshold_spam       12

# Enable or disable network checks
skip_rbl_checks         0
use_razor2              0 
use_dcc                 0 
use_pyzor               0 
score RAZOR2_CHECK 2.094
score RAZOR2_CF_RANGE_51_100 2.202
score RCVD_IN_SORBS_HTTP 2.202
score RCVD_IN_SORBS_MISC 2.408

# Mail using languages used in these country codes will not be marked
# as being possibly spam in a foreign language.
ok_languages            all

# Mail using locales used in these country codes will not be marked
# as being possibly spam in a foreign language.
ok_locales              all

score X_OSIRU_DUL 0.0
score X_OSIRU_DUL_FH 0.0
score X_OSIRU_OPEN_RELAY 0.0
score X_OSIRU_SPAMWARE_SITE 0.0
score X_OSIRU_SPAM_SRC 0.0 
score RCVD_IN_OSIRUSOFT_COM 0


... the actual configuration file is a bit longer because there are a few additional
filters that I included and also blacklists and whitelists for our users...

The OSIRU lines were added to make sure that SpamAssassin doesn't use the osirusoft RBL's which are no longer available. I also added bayes_path to make sure SpamAssassin knows where to look for the bayes database. I also increased the required_hits to 6.0 as it seems to work better on our server.

Now you need to tell Post.Office to use SpamAssassin for its filters. Please check the Post.Office FAQ how to add the SpamAssassin module. http://www.tenon.com/faq/faq.php?display=faq&nr=73&catnr=18&prog=3.5.3&lang=en&onlynewfaq=69

SpamAssassin Filter Setup

Basically, you create a new filter and only add a body filter: plugin spam_assassin. Make sure to copy the filtered messages to an e-mail address as you can use those messages to further train SpamAssassin and also check for any false positives.

Now would be a good time to restart your server to load Post.Office and SpamAssassin with all the changes you've made.


Training SpamAssassin

Once your server has rebooted, you should train SpamAssassin. Copy the mailboxes containing spam and ham to your server. Set the ownership of those files to the SpamAssassin user:

chown spamd:staff /ham.mbox /spam.mbox

In order to train SpamAssassin, you should use the terminal: change to the root user and then to the spamd user and use the sa-learn command (more info under "man sa-learn")

su -
su spamd
sa-learn --spam --showdots --mbox /spam.mbox
sa-learn --ham --showdots --mbox /ham.mbox

Type the following command to see if the Bayesian files were updated:

ls -alt ~spamd/.spamassassin/

The following command gives you some interesting information about SpamAssassin and its configuration:

spamassassin -D --lint

Final Comments

When you make any changes to the SpamAssassin configuration (local.cf), you need to restart spamd for the changes to become active.

This can be done with this command line:

kill `cat /var/run/spamd.pid` ; /usr/bin/spamd -u spamd -d -r /var/run/spamd.pid

spamd logs its activities to /var/log/mail.log (run "tail -f /var/log/mail.log" for live scrolling of the mail log file). If you start spamd with the following command, you'll get debug information (-D) in your mail.log -- this can be useful to see how SpamAssassin works:

/usr/bin/spamd -u spamd -d -r /var/run/spamd.pid -D

To get a summary of the spam and clean messages, use this command:

echo "Spam Messages: "`grep "identified spam" /var/log/mail.log | wc -l`
echo "Good Messages: "`grep "clean message" /var/log/mail.log | wc -l`

Here's another script which gives you an idea about SpamAssassin's performance: it lists the number of times a certain spam score was achieved and also lists a sorted distribution of all spam scores.

#!/bin/sh
echo ""
spammsg=$(grep "identified spam" /var/log/mail.log | grep -v "logmsg" | wc -l)
goodmsg=$(grep "clean message" /var/log/mail.log | grep -v "logmsg" | wc -l)

echo "Spam Messages:" $spammsg
echo "Good Messages:" $goodmsg

let spamrate=spammsg+goodmsg
let spamrate=spammsg*100/spamrate
echo "Spam Rate: ${spamrate}%"

Please support the development of these scripts through PayPal. Thank you.


Copyright by Jochen "Joe" Savelberg - © 2003-2004 -- Last Modified: 11th February 2004