How to Install Spamassassin with Postfix and Dovecot on Ubuntu/Debian Server

By | August 11, 2020

Spam free email with SpamAssassin

If you are running your own mailbox on a server using Postfix and Dovecot then it is imperative to install an anti-spam software to protect your mailbox from getting bombed with incoming spam mails.

And for this SpamAssassin is one of the best solutions available out there. It is quite effective and one of the most popular.

In this post we shall see how to setup spamassassin with postfix and dovecot for spam protection.

We assume that you have already setup Postfix and Dovecot on your server for handling incoming mails.

And that you are using Dovecot LMTP for delivering mails for user accounts. The process had been outlined in a previous post here -

Setup a mail server with Postfix and Dovecot on Ubuntu / Debian

Spamassassin scans incoming emails to identify spam and if a mail is found to be potentially a spam mail then Spamassassin adds headers to that email to mark it a spam.

Spam checking happens at the Postfix level. Postfix is configured to talk to Spamassassin as a content_filter.

In the next step, Dovecot analyses these headers to identify spam messages and puts them in a separate Spam folder, just like Gmail.

1. Install Spamassassin

The first thing would be to install spamassassin packages.

$ apt-get install spamassassin spamc

2. Setup a user account and group for spamd service

# groupadd spamd
# useradd -g spamd -s /bin/false -d /var/log/spamassassin spamd
# mkdir /var/log/spamassassin
# chown spamd:spamd /var/log/spamassassin

3. Configure Spamassassin

Edit /etc/default/spamassassin so these options are set:

# Change to one to enable spamd
ENABLED=1

SAHOME="/var/log/spamassassin/"

# Options
# See man spamd for possible options. The -d option is automatically added.

# SpamAssassin uses a preforking model, so be careful! You need to
# make sure --max-children is not set to anything higher than 5,
# unless you know what you're doing.

OPTIONS="--create-prefs --max-children 5 --helper-home-dir --username spamd \
-H ${SAHOME} -s ${SAHOME}spamd.log"

Also find the option called CRON at the bottom and change it to 1. This will enable automatic updating of spamassassin rules as they are released.

# Cronjob
# Set to anything but 0 to enable the cron job to automatically update
# spamassassin's rules on a nightly basis
CRON=1

4. Start the Spamassassin daemon (spamd)

# service spamassassin start
Starting SpamAssassin Mail Filter Daemon: spamd.
root@localhost:/etc/default# 
root@localhost:/etc/default# service spamassassin status
 * spamd is running
root@localhost:/etc/default#

Spamassassin starts a background service, so use the netstat command to ensure that spamassassin is running fine or not.

# netstat -nlp4 | grep spam
tcp        0      0 127.0.0.1:783           0.0.0.0:*               LISTEN      1123/spamd.pid

4. Configure Postfix to use Spamassassin as a filter

Postfix needs to be configured to use spamassassin service to filter all incoming mails
The postfix configuration file master.cf needs to be edited to add spamassassin filter. Open the file.

# cat /etc/postfix/master.cf

Add the following at the end of the file

spamassassin unix -     n       n       -       -       pipe
        user=spamd argv=/usr/bin/spamc -f -e  
        /usr/sbin/sendmail -oi -f ${sender} ${recipient}

After adding the above lines to master.cf the next task is to restart postfix and make sure that it works fine.

$ service postfix restart

5. Configure Spamassassin to Mark Spam Messages

After configuring Postfix to use Spamassassin, its time to configure Spamassassin to modify emails according to spam checks. The configuration file is - /etc/spamassassin/local.cf

$ nano /etc/spamassassin/local.cf

Uncomment the rewrite_header line to modify the Subject lines of emails that are identified as spam.

#   Add *****SPAM***** to the Subject header of spam e-mails
#
# rewrite_header Subject *****SPAM*****

rewrite_header Subject [***** SPAM _SCORE_ *****]

The above line would add the Spam score with the asterisk marks to indicate that the message looks like spam. Higher scores would indicate higher probability of the message being a spam.

Spam Score

The minimum required score to mark the message as spam. The default is 5.0, but now a days you might need a more strict score level. So 4.0 works good.

#   Set the threshold at which a message is considered spam (default: 5.0)
#
required_score 4.0

Check out the other options in the file and edit them as required.

Restart Spamassassin - After configuring all parameters in the file, save the file and restart spamassassin.

# service spamassassin restart
Restarting SpamAssassin Mail Filter Daemon: spamd.

6. Check Spamassassin log

If at any point you need to debug something or view whats going in the background of spamassassin, feel free to check its look file.

# tail -f /var/log/spamassassin/spamd.log 
Fri Feb  5 20:11:43 2016 [1123] info: prefork: child states: II
Fri Feb  5 20:23:02 2016 [1123] info: spamd: server killed by SIGTERM, shutting down
Fri Feb  5 20:23:02 2016 [1404] info: logger: removing stderr method
Fri Feb  5 20:23:03 2016 [1406] info: zoom: able to use 360/360 'body_0' compiled rules (100%)
Fri Feb  5 20:23:03 2016 [1406] info: spamd: server started on IO::Socket::INET6 [127.0.0.1]:783, IO::Socket::INET6 [::1]:783 (running version 3.4.0)
Fri Feb  5 20:23:03 2016 [1406] info: spamd: server pid: 1406
Fri Feb  5 20:23:03 2016 [1406] info: spamd: server successfully spawned child process, pid 1407
Fri Feb  5 20:23:03 2016 [1406] info: spamd: server successfully spawned child process, pid 1408
Fri Feb  5 20:23:03 2016 [1406] info: prefork: child states: IS
Fri Feb  5 20:23:03 2016 [1406] info: prefork: child states: II

7. Test a Spam mail

Send an email to your mail system from outsite. Include the following piece of text in the email's body

XJS*C4JDBQADN1.NSBN3*2IDNEN*GTUBE-STANDARD-ANTI-UBE-TEST-EMAIL*C.34X

Its called GTUBE - Generic Test for Unsolicited Bulk Email. Its a simple way to test if your mail server is using spamassassin to filter mails or not.

Learn more about it here -
http://spamassassin.apache.org/gtube/

SpamAssassin adds headers to all emails with spam scores > 0

Mail with spam score 12.9 This is considered spam according to our configuration of minimum score of 3

X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on localhost
X-Spam-Flag: YES
X-Spam-Level: ************
X-Spam-Status: Yes, score=12.9 required=3.0 tests=FROM_LOCAL_NOVOWEL,
	HTML_FONT_LOW_CONTRAST,HTML_FONT_SIZE_LARGE,HTML_MESSAGE,HTML_OBFUSCATE_05_10,
	MIME_HTML_ONLY,MISSING_MID,RCVD_IN_BL_SPAMCOP_NET,RCVD_IN_BRBL_LASTEXT,
	RCVD_IN_PBL,RCVD_IN_PSBL,RCVD_IN_XBL,RDNS_NONE autolearn=no
	autolearn_force=no version=3.4.0

Spam Score 1.7, Not considered spam

X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on localhost
X-Spam-Level: *
X-Spam-Status: No, score=1.7 required=3.0 tests=DEAR_SOMETHING,FREEMAIL_FROM,
	HTML_MESSAGE,RCVD_IN_MSPIKE_H2,URIBL_BLOCKED autolearn=no autolearn_force=no
	version=3.4.0

These headers shall be used to send emails into a separate Spam folder via Dovecot LMTP transport.

Configure Dovecot with separate Spam folder

Dovecot is the mail reading and managing system, POP3 and IMAP server. It is Dovecot that organises mails into separate folders depending on criterias.

Dovecot can be configured to read mail headers and move spam mails to a separate folder called Spam. Much like you see with free mail services like Gmail and Outlook.

Install and Configure Sieve Plugin

Dovecot needs the Sieve interpreter plugin to use Sieve to read mails. Install the Sieve packages

# apt-get install dovecot-sieve dovecot-managesieved

Edit
/etc/dovecot/conf.d/20-lmtp.conf

Configure dovecot to enable the sieve plugin

protocol lmtp {
  # Space separated list of plugins to load (default is global mail_plugins).
  mail_plugins = $mail_plugins sieve
}

Finally its time to restart dovecot

# service dovecot restart

Now check if the sieve server is running on port 4190. Use the netstat command. The service will be named as dovecot.

# netstat -nltp | grep 4190
tcp        0      0 0.0.0.0:4190            0.0.0.0:*               LISTEN      9843/dovecot    
tcp6       0      0 :::4190                 :::*                    LISTEN      9843/dovecot

Setup Sieve filtering

To learn more about sieve filters, check out the following page - http://wiki2.dovecot.org/Pigeonhole/Sieve/Examples

# mkdir /var/lib/dovecot/sieve/

Create a file called default.sieve and fill it with the following rule sets

require ["fileinto", "mailbox"];

if header :contains "X-Spam-Flag" "YES" {
        fileinto :create "Spam";
}

Now compile the .sieve script file using the sievec command.

# sievec default.sieve

If you have multiple .sieve files in the directory, then you can compile all of them in one go like this -

# sievec sieve/

Now change the ownership of the sieve files to the dovecot specific user so that dovecot can read them. In this case the username is vmail.

/var/lib/dovecot# chown -R vmail:vmail sieve/*

Restart Dovecot again.

# service dovecot restart

Check dovecot logs

Dovecot log files shall help you diagnose any problems that might come along the way.

Find the location of dovecot log files with the following command

# doveadm  log find
Debug: /var/log/dovecot.log
Info: /var/log/dovecot.log
Warning: /var/log/dovecot.log
Error: /var/log/dovecot.log
Fatal: /var/log/dovecot.log

Then open the file using the tail command

# tail -f /var/log/dovecot.log
Feb 06 11:17:16 imap-login: Info: Login: user=<[email protected]>, method=PLAIN, rip=122.163.23.27, lip=173.255.230.5, mpid=10370, TLS, session=<RfgSgBMr1QB6oxcb>
Feb 06 11:17:37 lmtp(10379): Info: Connect from local
Feb 06 11:17:37 lmtp(10379, [email protected]): Error: uMMvHPmItVaLKAAA0J78UA: sieve: main script: failed to stat sieve script: stat(/var/lib/dovecot/sieve/default.sieve) failed: Permission denied (euid=5000(vmail) egid=5000(vmail) missing +x perm: /var/lib/dovecot, dir owned by 0:0 mode=0750)
Feb 06 11:17:37 lmtp(10379, [email protected]): Error: uMMvHPmItVaLKAAA0J78UA: sieve: failed to access default user script /var/lib/dovecot/sieve/default.sieve
Feb 06 11:17:37 lmtp(10379, [email protected]): Info: uMMvHPmItVaLKAAA0J78UA: msgid=<CAKfwS=YH3TJ2XCxE0RzQqisBO54-QmYe9QJWAQd8-i207JN_1Q@mail.gmail.com>: saved mail to INBOX
Feb 06 11:17:37 lmtp(10379): Info: Disconnect from local: Successful quit
Feb 06 11:18:31 lmtp(10379): Info: Connect from local
Feb 06 11:18:31 lmtp(10379, [email protected]): Error: vMMvHPmItVaLKAAA0J78UA: sieve: msgid=<CAKfwS=YLa+1DYyX3HiQ7qQN=4PkmzCfX_1vB28A1gHT9xB4xjA@mail.gmail.com>: failed to store into mailbox 'Spam': Mailbox doesn't exist: Spam
Feb 06 11:18:31 lmtp(10379, [email protected]): Info: vMMvHPmItVaLKAAA0J78UA: sieve: msgid=<CAKfwS=YLa+1DYyX3HiQ7qQN=4PkmzCfX_1vB28A1gHT9xB4xjA@mail.gmail.com>: stored mail into mailbox 'INBOX'
Feb 06 11:18:31 lmtp(10379, [email protected]): Error: vMMvHPmItVaLKAAA0J78UA: sieve: execution of script /var/lib/dovecot/sieve/default.sieve;name=main script failed, but implicit keep was successful
Feb 06 11:18:31 lmtp(10379): Info: Disconnect from local: Successful quit
Feb 06 11:26:27 lmtp(10479): Info: Connect from local
Feb 06 11:26:27 lmtp(10479, [email protected]): Info: 3h4eBwuLtVbvKAAA0J78UA: sieve: msgid=<CAKfwS=b6cEU-WwhOkxaBjZcxb61dAZomyC4x98T4drLVFgeTxw@mail.gmail.com>: stored mail into mailbox 'Spam'
Feb 06 11:26:27 lmtp(10479): Info: Disconnect from local: Successful quit
Feb 06 11:26:57 imap-login: Info: Login: user=<[email protected]>, method=PLAIN, rip=122.163.23.27, lip=173.255.230.5, mpid=10483, TLS, session=<OreuohMrXgB6oxcb>
Feb 06 11:26:58 imap-login: Info: Login: user=<[email protected]>, method=PLAIN, rip=122.163.23.27, lip=173.255.230.5, mpid=10484, TLS, session=<xr6+ohMrXwB6oxcb>
Feb 06 11:28:30 imap-login: Info: Login: user=<[email protected]>, method=PLAIN, rip=122.163.23.27, lip=173.255.230.5, mpid=10499, TLS, session=<n7Q2qBMrCwB6oxcb>

Change the permissions of the dovecot directory

/var/lib/dovecot# chmod a+x .

Boost Spamassassin spam filtering with Pyzor

Pyzor will act just like other rules.
https://wiki.apache.org/spamassassin/Rules/PYZOR_CHECK

It will add an extra spam score of about 1.985 according to the tests table found at - http://spamassassin.apache.org/tests_3_3_x.html

# sudo apt-get install pyzor

Discover the Pyzor servers

# pyzor --homedir /etc/mail/spamassassin/pyzor discover

Make the servers file readable by all

/etc/spamassassin/pyzor# chmod a+r servers

Run a check -

# echo "test" | spamassassin -D pyzor 2>&1 | less

You should see some output like this

Feb  9 16:24:58.824 [23979] dbg: pyzor: network tests on, attempting Pyzor
Feb  9 16:24:59.787 [23979] dbg: pyzor: pyzor is available: /usr/bin/pyzor
Feb  9 16:24:59.788 [23979] dbg: pyzor: opening pipe: /usr/bin/pyzor check < /tmp/.spamassassin23979z26KDDtmp
Feb  9 16:24:59.841 [23979] dbg: pyzor: [23981] finished: exit 1
Feb  9 16:24:59.842 [23979] dbg: pyzor: check failed: no response

Add the following lines to the end of /etc/spamassassin/local.cf

pyzor_options --homedir /etc/mail/spamassassin/pyzor

And restart spamassassin daemon

# service spamassassin restart

Install Razor

sudo apt-get install razor
/etc/spamassassin# mkdir razor

Now run the following commands to register with the razor distributed network.

# razor-admin -home=/etc/spamassassin/razor -register
Register successful.  Identity stored in /etc/mail/spamassassin/razor/identity-rudkVFCIxs
# razor-admin -home=/etc/spamassassin/razor -create
# razor-admin -home=/etc/spamassassin/razor -discover

Add the following line at the end of /etc/spamassassin/local.cf file

razor_config /etc/spamassassin/razor/razor-agent.conf

Finally restart spamassassin

check razor working with this command

# echo "test" | spamassassin -D razor2 2>&1 | less

something like this should show up

Feb  9 17:11:34.701 [26028] dbg: razor2: razor2 is available, version 2.84
 Razor-Log: read_file: 15 items read from /etc/mail/spamassassin/razor/razor-agent.conf

Custom scores for higher scores

This is a little bit advanced way to increase the accuracy of spamassassin to catch spam better. It involves increasing the score levels for certain spam-tests inside of spamassassin. These are the spam tests that are known to have a very high level of accuracy in detecting spam.

So if some of these high accuracy tests indicate a mail as spam, we should focus more on it.

http://toao.net/566-improving-spamassassin-accuracy-with-statistics

Conclusion

That was the process to setup SpamAssassin on your mail server to detect spam mails and keep your mailbox clean.
The process is a bit lengthy but it works great if you need your own mail server with anti-spam system in place.

If you have any feedback or questions, please let us know in the comments below.

References and Resources

Simple Spamassassin setup with Postfix and Dovecot on Ubuntu Breezy
http://www.townx.org/index.php?q=blog/elliot/simple_spamassassin_setup_with_postfix_and_dovecot_on_ubuntu_breezy

How To Install and Setup Spamassassin on Ubuntu 12.04
https://www.digitalocean.com/community/tutorials/how-to-install-and-setup-spamassassin-on-ubuntu-12-04

Instructions on installing Pyzor and Razor with Spamassassin
https://kura.io/2011/09/22/spamassassin-razor-pyzor/

Setting up Sieve filtering with Dovecot
https://easyengine.io/tutorials/mail/server/sieve-filtering/

Spamassassin Tips : Ultimate Setup Guide
http://www.spamtips.org/p/ultimate-setup-guide.html

How to Improve SpamAssassin Accuracy
https://wiki.apache.org/spamassassin/ImproveAccuracy

On the effects of lowering your SpamAssassin threshold
http://taint.org/2008/02/29/155648a.html

Improving SpamAssassin accuracy on cPanel (or any other) mail servers - with statistics
http://toao.net/566-improving-spamassassin-accuracy-with-statistics

This post outlines simple hacks that you can use to change score levels for some of the spamassassin tests thereby improving spam filtering.

Advanced Tips for Using SpamAssassin
https://www.andrewferrier.com/oldpages/spamassassin_tips.html

About Silver Moon

A Tech Enthusiast, Blogger, Linux Fan and a Software Developer. Writes about Computer hardware, Linux and Open Source software and coding in Python, Php and Javascript. He can be reached at [email protected].

5 Comments

How to Install Spamassassin with Postfix and Dovecot on Ubuntu/Debian Server
  1. Anonymous Coward

    I was really impressed with the “Install Postfix mail server and Dovecot on Ubuntu or Debian” guide, but this one seems to no longer be up-to-date and have been abandoned (errors from 2018 still not addressed in 2020). I understand that we may not always have time, but then it’s better to remove it than have people waste time with it.

    Pyzor discover has been discontinued since around 2017:

    # pyzor –homedir /etc/mail/spamassassin/pyzor discover
    2020-09-29 11:54:59,586 (559) CRITICAL Unknown command: discover

    Now I have to backtrack the installation and follow a more up-to-date version.

  2. Alex

    Also in the section “Setup Sieve filtering” you should mention the changes to dovecot’s configuration in 90-sieve.conf to tell dovecot to use this new default.sieve

    sieve_global_path = /var/lib/dovecot/sieve/default.sieve
    sieve_global_dir = /var/lib/dovecot/sieve/

    etc

  3. Alex

    Thanks for this guide. In the section “Configure Postfix to use Spamassassin as a filter” you perhaps ought to add the line to postfix’s master.cf that tells postfix to use spamassassin as a filter, i.e. changing

    smtp inet n – n – – smtpd

    to

    smtp inet n – n – – smtpd -o content_filter=spamassassin

    1. Silver Moon Post author

      yes, its necessary to add
      -o content_filter=spamassassin

      thanks for pointing it out. i missed it.
      will update the article.

Leave a Reply

Your email address will not be published. Required fields are marked *