Postfix & Spamassassin integration allowing for custom processing

This assumes that you have postfix installed and running as your SMTP server

First, make sure that you’re root

1
whoami

I probably shouldn’t have to explain that if you’re reading this but just in case; if that last command returned something else than ‘root’ issue the following command

1
sudo su

and enter your password

step 1: Let’s install the packages we’re gonna need

1
2
apt-get update
apt-get install spamassassin spamc

step 2: Now we configure spamassasin

1
2
3
cat /etc/default/spamassassin | sed -e 's#ENABLED=0#ENABLED=1#g' > /etc/default/spamassassin
cat /etc/default/spamassassin | sed -e 's#CRON=0#CRON=1#g' > /etc/default/spamassassin
cat /etc/spamassassin/local.cf | set -e 's## rewrite_header Subject *****SPAM*****#rewrite_header Subject [*****SPAM*****] > /etc/spamassassin/local.cf

and we start/restart it

1
/etc/init.d/spamassassin restart

step 3: We create a little script that will take desired action upon spamassassin flagging

create a user called spamassassin (or whatever you want as long as you keep it consistent)

1
useradd -m spamassassin

then edit the script file /home/spamassassin/spamcheck and throw the following in it

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
 # variables
  
SENDMAIL="/usr/sbin/sendmail -i"
  
EGREP=/bin/egrep
  
SPAMLIMIT=10
  
# exit codes from <sysexits.h>
  
EX_UNAVAILABLE=69
  
# clean up when done or when aborting.
  
trap "rm -f /tmp/out.$$" 0 1 2 3 15
  
# pipe message to spamc
  
cat | /usr/bin/spamc -u spamd > /tmp/out.$$
  
# are there more than $SPAMLIMIT stars in X-Spam-Level header? :
  
if $EGREP -q "^X-Spam-Level: *{$SPAMLIMIT,}" < /tmp/out.$$
  
then
  
# option 1: move spam messages to sideline dir so a human can look at them later:
  
mv /tmp/out.$$ /home/spamassassin/`date +%Y-%m-%d_%R`-$$
  
# option 2: divert spam message to an alternate e-mail address:
  
#$SENDMAIL xyz@xxxx.xx < /tmp/out.$$
  
# option 3: just delete the spam message
  
# rm -f /tmp/out.$$
  
# option 4: still relay the email to the recipient with the subject of the email now containing [*****SPAM*****]
  
# $SENDMAIL "$@" < /tmp/out.$$
  
else
  
$SENDMAIL "$@" < /tmp/out.$$
  
fi
  
# Postfix returns the exit status of the Postfix sendmail command.
  
exit $?

make sure that you

1
2
chown spamassassin:spamassassin /home/spamassassin/spamcheck
chmod 750 /home/spamassassin/spamcheck

step 4: Ok, so we got spamassassin going and a little script that will take an email and throw it in /home/spamassassin if it’s spam (if you chose option1) now we just need to tell postfix to pass all messages to that script

edit /etc/postfix/master.cf and replace

1
smtp      inet  n       -       -       -       -       smtpd

with

1
smtp      inet  n       -       n       -       -       smtpd -o content_filter=spamcheck:dummy

also add the following 2 lines at the bottom of the file (the indentation is important)

1
2
3
spamcheck   unix  -       n       n       -       10      pipe
 
flags=Rq user=spamassassin argv=/bin/spamcheck -f ${sender} -- ${recipient}

We’re almost there, just restart postfix and you’re good to go!

1
/etc/init.d/postfix restart

If you wanna test that out, watch the log while you send emails to your servers

1
tail -f /var/log/syslog

send a clean mail, make sure that it reaches destination, then send something you know will get flagged as spam and make sure it ends up in /home/spamassasin instead of the intended recipient.

The reason we choose option 1 here is because there’s no point in still relaying a flagged email as it will still clog the recipient’s mailbox. On the other hand we don’t want to just delete it if spamassassin makes a mistake we want to play it safe and keep every emails should something arise, we quarantine the bad ones in /home/spamassassin

Lastly, as long as you have postfix just feeding the emails to a script like we just did, it’s easy to become fancier and do all kinds of processing to the email, on my server I actually call a php script that throws emails in a DB.

Silly Apache warning

If the following happens to you:

1
apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1 for ServerName

just issue a:

1
echo Servername `cat /etc/hostname` >> /etc/apache2/apache2.conf

Tested on: Ubuntu server 9.04 32b / Ubuntu 12.04 64b

recursive name based delete

Here’s a neat little command that will let you delete specified files/directories recursively and based on their names.

Let’s do a dry run first to make sure that the command will go through the right files. Run:

1
<code class="plain plain">find <directory_to_start_the_recursion_in> -name <file_name</code>>

Keep in mind that if you’re gonna have asterisks (*) in the <file_name> you need to escape them like so:

1
find /var/www -name *.jpg

make sure that the result only lists the files/directories that you indeed want to obliterate. Then improve that last command by adding:

1
find <directory_to_start_the_recursion_in> -name <file_name> -exec rm -rf {} ;

Since this is a pretty dangerous command even after a dry run, you can use -ok instead of -exec which will prompt you for approval everytime the command it executed.

1
find <directory_to_start_the_recursion_in> -name <file_name> -ok rm -rf {} ;

This is of course not limited to rm 🙂