Install SpamAssassin with Content Filter

Install SpamAssassin from the default Ubuntu software repository. Spamc is the client for SpamAssassin spam filtering daemon.

sudo apt install spamassassin spamc

The debian-spamd user and group will be automatically created during the installation.

By default, the spamassassin system service is disabled, you can enable auto start at boot time with:

sudo systemctl enable spamassassin

Then start SpamAssassin.

sudo systemctl start spamassassin

Integrate SpamAssassin with Postfix SMTP Server as a Milter

SpamAssassin via the sendmail milter interface to reject an email when it gets a very high score such as 8, so it will never be seen by the recipient.

Install the spamass-filter packages from the Ubuntu default software repository.

sudo apt install spamass-milter

Next, edit /etc/postfix/main.cf file and add the following lines at the end of the file.

# Milter configuration
milter_default_action = accept
milter_protocol = 6
smtpd_milters = local:spamass/spamass.sock
non_smtpd_milters = $smtpd_milters

If you have configured OpenDKIM and OpenDMARC, then these lines should look like the below. The order matters.

# Milter configuration
milter_default_action = accept
milter_protocol = 6
smtpd_milters = local:opendkim/opendkim.sock,local:opendmarc/opendmarc.sock,local:spamass/spamass.sock
non_smtpd_milters = $smtpd_milters

If you haven’t configured OpenDMARC, then you should remove local:opendmarc/opendmarc.sock, it from smtpd_milters line.

Save and close the file.

Now open the /etc/default/spamass-milter file and find the following line.

sudo nano /etc/default/spamass-milter
#OPTIONS="${OPTIONS} -r 15"

Uncomment this line and change 15 to your preferred reject score such as 8.

OPTIONS="${OPTIONS} -r 8"

If the score of a particular email is over 8, Spamassassin would reject it and you would find a message like below in the /var/log/mail.log file, indicating it’s rejected.

milter-reject: END-OF-MESSAGE  5.7.1 Blocked by SpamAssassin

If you want the sender to see a different reject text, then add the -R (reject text) an option like below.

OPTIONS="-u spamass-milter -i 127.0.0.1 -R SPAM_EMAIL_ARE_NOT_ALLOWED"

Save and close the file. Restart Postfix and Spamass Milter for the changes to take effect.

sudo systemctl restart postfix spamass-milter
sudo systemctl start spamassassin
sudo systemctl enable spamassassin

Checking Email Header and Body with SpamAssassin

SpamAssassin ships with many spam detection rules in /usr/share/spamassassin/ directory.

If you like to use the Cron job shipped with SpamAssassin to automatically update SpamAssassin’s rules on a daily basis. If so, open the /etc/default/spamassassin file and change

CRON=0 to CRON=1.

Set Custom Score for Existing Rules

In the 50_scores.cf and 72_active.cf file, you can see the default scores for various tests. If you think the default score is too low or too high for a certain test, you can set custom score in /etc/spamassassin/local.cf file.

sudo nano /etc/spamassassin/local.cf

Every email message must have From: and Date: header fields

Set a very high score if either of them is missing in an email message by appending the following two lines in local.cf file.

score MISSING_FROM   5.0
score MISSING_DATE   5.0

To: header field is not mandatory in RFC 5322

score MISSING_HEADERS 3.0

Some Spammer use empty message, different domain names in the From: and Reply-To: header, non-existent domain name, many spammers spoof the gmail.com domain in the From: header field.

Set Score for these

score EMPTY_MESSAGE 5.0
score FREEMAIL_FORGED_REPLYTO 3.5
score DKIM_ADSP_NXDOMAIN 5.0
score FORGED_GMAIL_RCVD 2.5

Adding Your Own Rules

Add custom SpamAssassin rules in /etc/spamassassin/local.cf file.

Header Rules

For example, some spammers use the same email address in the From: and To: header, you can add the following lines at the end of the file to add scores to such emails.

header   FROM_SAME_AS_TO   ALL=~/\nFrom: ([^\n]+)\nTo: \1/sm
describe FROM_SAME_AS_TO   From address is the same as To address.
score    FROM_SAME_AS_TO   2.0

spammers use an empty address for the Envelope From address

header    EMPTY_RETURN_PATH    ALL =~ /<>/i
describe  EMPTY_RETURN_PATH    empty address in the Return Path header.
score     EMPTY_RETURN_PATH    3.0

If you have configured OpenDMARC on your mail server, you can now add the following lines to add scores to emails that fail the DMARC check.

header    CUSTOM_DMARC_FAIL   Authentication-Results =~ /dmarc=fail/
describe  CUSTOM_DMARC_FAIL   This email failed DMARC check
score     CUSTOM_DMARC_FAIL   3.0

Body Rules

SpamAssassin to increase the score of an email if a certain phrase is found in the body. Many spammers use the recipient’s email address in the first body line like below.

Hi you@your-domain.com
Hello you@your-domain.com
Dear you@your-domain.com

Create a rule in SpamAssassin to filter this kind of email.

body      BE_POLITE       /(hi|hello|dear) you\@your\-domain\.com/i
describe  BE_POLITE       This email doesn't use a proper name for the recipient
score     BE_POLITE       5.0

Regular expression in SpamAssassin is case-sensitive by default, you can add the i option at the end to make it case-insensitive.

Add Negative Scores

You can also add a negative score to good emails, so there will be fewer false positives.  Spammers would not include words like DebianUbuntuLinux Mint in the email body, create the following rule.

body      GOOD_EMAIL    /(debian|ubuntu|linux mint|centos|red hat|RHEL|OpenSUSE|Fedora|Arch Linux|Raspberry Pi|Kali Linux)/i
describe  GOOD_EMAIL    spammer would not include these words in the email body.
score     GOOD_EMAIL    -4.0

If the email body contains a Linux distro’s name, then add a negative score (-4.0).

There are some common phrases that is included in legitimate bounce messages,

body      BOUNCE_MSG    /(Undelivered Mail Returned to Sender|Undeliverable|Auto-Reply|Automatic reply)/i
describe  BOUNCE_MSG    Undelivered mail notifications or auto-reply messages
score     BOUNCE_MSG    -1.5

Note that body rules also include the Subject as the first line of the body content.

Meta Rules

In addition to header and body rules, there are also meta-rules. Meta rules are combinations of other rules. You can create a meta-rule that fires off when two or more other rules are true. Occasionally you might receive emails saying that the sender wants to apply for a job and a resume is attached. you have never said on your website that you hiring people. The attachment is used to spread virus. Following meta rule to filter this kind of email.

body      __RESUME        /(C.V|Resume)/i
meta      RESUME_VIRUS    (__RESUME && __MIME_BASE64)
describe  RESUME_VIRUS    The attachment contains virus.
score     RESUME_VIRUS    5.5

The first sub rule __RESUME tests if the email body contains the word C.V. or resume. The second sub-rule __MIME_BASE64 is already defined in /usr/share/spamassassin/20_body_tests.cf file, To define it again in local.cf file. This rule tests if the email message includes a base64 attachment.

rawbody   __MIME_BASE64  eval:check_for_mime('mime_base64_count')
describe  __MIME_BASE64  Includes a base64 attachment

My meta rule RESUME_VIRUS will fire off when both of the sub-rules are true, adding a 5.5 score to the email message. Note that sub-rule often starts with a double underscore, so it has no score in its own right.

Whitelist

You can use the whitelist_from parameter to add a particular email address or domain to your Spamassassin whitelist. Add the following lines at the end of local.cf file.

whitelist_from *@alfaintelli.com
whitelist_from *@heateat.com.au
whitelist_from *@alfaintelli.net
whitelist_from it@aawaz-e-zameer.in
whitelist_from coffee@2quench.com
whitelist_from *@paypal.com
whitelist_from *@*stripe.com
whitelist_from *@inder.work
whitelist_from *@manjits.com

A whitelisted sender has a -100 default score. They will still be tested by SpamAssassin rules, but it’s super hard for them to reach a 5.0 score.

Blacklist

To blacklist a sender, use the blacklist_from parameter, which has the same format as whitelist_from.

blacklist_from spam@example.com
blacklist_from *@example.org

Checking Syntax and Restart

After saving the local.cf file. Run the spamassassin command in lint mode to check if there are any syntax errors.

sudo spamassassin --lint

Then restart SpamAssassin for the changes to take effect.

sudo systemctl restart spamassassin

SpamAssassin’s Builtin Whitelist

SpamAssassin ships with its own whitelist. There are several files under /usr/share/spamassassin/ directory that includes 60_whitelist the filename. These files contain SpamAssassin’s builtin whitelist. For example, the 60_whitelist_spf.cf file contains a list of addresses which send mail that is often tagged (incorrectly) as spam.

Move Spam into the Junk Folder

Move spam to Junk folder with the Dovecot IMAP server and the sieve plugin.

This method requires that inbound emails are delivered to the message store via the Dovecot “deliver” LDA (local delivery agent).

You might find the following text in /var/log/mail.log file, then this requirement is satisfied.

postfix/lmtp

or

delivered via dovecot service

Run the following command install dovecot-sieve from Ubuntu software repository.

sudo apt install dovecot-sieve

This package installs two configuration files under /etc/dovecot/conf.d/ directory: 90-sieve.conf and 90-sieve-extprograms.conf. Open the 15-lda.conf file.

sudo nano /etc/dovecot/conf.d/15-lda.conf

Add the sieve plugin to local delivery agent (LDA).

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

Save and close the file. Find the 20-lmtp.conf file under /etc/dovecot/conf.d/ directory, enable the sieve plugin in that file like below.

protocol lmtp {
      mail_plugins = quota sieve
}

Edit the /etc/dovecot/conf.d/10-mail.conf file.

sudo nano /etc/dovecot/conf.d/10-mail.conf

Sieve scripts are stored under each user’s home directory. If you followed my PostfixAdmin tutorial and are using virtual mailbox domains, then you need to enable mail_home for the virtual users by adding the following line in the file, because virtual users don’t have home directories by default.

mail_home = /var/vmail/%d/%n

Save and close the file. Then open the 90-sieve.conf file.

sudo nano /etc/dovecot/conf.d/90-sieve.conf

Go to line 79 and add the following line, which tells Sieve to always execute the SpamToJunk.sieve script before any user-specific scripts.

sieve_before = /var/mail/SpamToJunk.sieve

Save and close the file.

Create the sieve script.

sudo nano /var/mail/SpamToJunk.sieve

Add the following lines, which tells Dovecot to move any email messages with the X-Spam-Flag: YES header into Junk folder.

require "fileinto";

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

Save and close the file. Compile this script.

sudo sievec /var/mail/SpamToJunk.sieve

Now there is a binary file saved as /var/mail/SpamToJunk.svbin.

Restart dovecot for the changes to take effect.

sudo systemctl restart dovecot

Set Message Maximum Size

By default, SpamAssassin does not check messages with attachments larger than 500KB, as indicated by the following line in the /var/log/mail.log file.

spamc[18922]: skipped message, greater than max message size (512000 bytes)

The default max-size is set to 512000 (bytes). A high value could increase server load, However, the default size is a little bit small. To increase the max-size, edit /etc/default/spamass-milter file and add the following lines at the end.

#Spamc options
OPTIONS="${OPTIONS} -- --max-size=5120000"

The empty -- the option tells spamass-milter to pass all remaining options to spamc, which understands the --max-size option. I increased the size to 5000KB. Save and close the file. Then restart spamass-milter.

sudo systemctl restart spamass-milter

How to Configure Individual User Preferences

Set custom rules for emails sent to a specific address on the mail server.

First, edit the SpamAssassin main configuration file.

sudo nano /etc/spamassassin/local.cf

Add the following line to allow user rules.

allow_user_rules 1

Save and close the file. Next, edit the SpamAssassin environment file.

sudo nano /etc/default/spamassassin

Find the following line.

OPTIONS="--create-prefs --max-children 5 --helper-home-dir"

We need to change it to

OPTIONS="--create-prefs --max-children 5 --helper-home-dir --nouser-config --virtual-config-dir=/var/vmail/%d/%l/spamassassin --username=vmail"

Save and close the file. Then restart SpamAssassin.

sudo systemctl restart spamassassin

By default, spamass-milter will send only the local part of email address to SpamAssassin. To make it send the full email address. Edit the spamass-milter configuration file.

sudo nano /etc/default/spamass-milter

Find the following line.

OPTIONS="-u spamass-milter -i 127.0.0.1 -R SPAM_EMAIL_NOT_ALLOWED"

Add the following option to this line.

-e yourdomain.com

Like this:

OPTIONS="-e yourdomain.com -u spamass-milter -i 127.0.0.1 -R SPAM_EMAIL_NOT_ALLOWED"

The -e option will make spamass-milter pass the full email address to SpamAssassin. Replace yourdomain.com with your real domain name. Save and close the file. Then restart spamass-milter.

sudo systemctl restart spamass-milter

Now send an email from Gmail, Hotmail, etc. to your domain email address. You will find the spamassassin directory is automatically created under /var/vmail/yourdomain.com/username/ directory.

cd /var/vmail/yourdomain.com/username/spamassassin/

You can use a command-line text editor to create the per-user preference file here. This file must be named as user_prefs.

sudo nano user_prefs

Add custom rules in this file same as you would do in the /etc/spamassassin/local.cf file

body      SUBSCRIPTION_SPAM   /(unsubscribe|u n s u b s c r i b e|Un-subscribe)/i
describe  SUBSCRIPTION_SPAM   I didn't subscribe to your spam.
score     SUBSCRIPTION_SPAM   3.0
header    LIST_UNSUBSCRIBE   ALL =~ /List-Unsubscribe/i
describe  LIST_UNSUBSCRIBE   I didn't join your mailing list.
score     LIST_UNSUBSCRIBE   2.0
score FROM_DOMAIN_NOVOWEL 4.0
score HTML_IMAGE_RATIO_02 4.0

Save and Close file

Following command to check syntax. Silent output means there’s no syntax error.

sudo spamassassin --lint

Restart SpamAssassin for the changes to take effect.

sudo systemctl restart spamassassin

Deleting Email Headers For Outgoing Emails

Use smtp_header_checks to delete email headers that could show sensitive information. smtp_header_checks are only applied when Postfix is acting as an SMTP client, so it won’t affect incoming emails.

For example, you might not want the recipient to know that you are using SpamAssassin on your mail server, then you can create the /etc/postfix/smtp_header_checks file

sudo nano /etc/postfix/smtp_header_checks

And add the following lines in the file. This tells Postfix to delete the X-Spam-Status and X-Spam-Checker-Version header from the email message when sending emails.

/^X-Spam-Status:/             IGNORE
/^X-Spam-Checker-Version:/    IGNORE

Save and close the file.

Edit the Postfix main configuration file.

sudo nano /etc/postfix/main.cf

Add the following line at the end of the file.

smtp_header_checks = pcre:/etc/postfix/smtp_header_checks

Save and close the file.

Run the following command.

sudo postmap /etc/postfix/smtp_header_checks

Reload Postfix for the change to take effect.

sudo systemctl reload postfix

2 Responses

  1. This article is perfect for someone who is just starting out with SpamAssassin. It covers all the basics and provides a comprehensive guide for installation.

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Liked this post? Share with others!

Do you want to boost your business today?

This is your chance to invite visitors to contact you. Tell them you’ll be happy to answer all their questions as soon as possible.