Article overview

Help article

Exim antispam with spamassassin in CentOS 7 and 8

Bots and other malicious parties send a lot of spam by email. They try to exploit vulnerabilities on servers (e.g. your VPS) to send spam from an infected mail server. Therefore, it is important to use anti-spam software on your mail server in addition to good general security of your VPS.

In this tutorial, we show you how to use SpamAssassin as spam protection for a mail server with Exim and Dovecot in CentOS.

  • The steps in this article require a CentOS 7 or 8 VPS with Exim and Dovecot. In this tutorial, we explain how to set up Exim and Dovecot.
     
  • Execute the commands in this article using sudo, or as a root user

Spamassassin in short

Spamassassin scans mail for elements it recognizes as possible characteristics of spam, such as:

  • A small amount of text in relation to the number of images in a mail
  • A subject of the mail that consists of capital letters
  • An invalid or missing DKIM record (more and more parties are automatically blocking mail as spam if they don't have DKIM, see also this manual)
  • etc.

If Spamassassin sees these types of characteristics, it gives a score for that characteristic. The score is higher if the specific characteristic often reoccurs in spam. Spamassassin adds all scores and when it reaches a preset value, the mail is blocked as spam.


Installing and configuring Spamassassin

 

Step 1

Connect to your VPS via SSH or the VPS console in the TransIP control panel.


 

Step 2

Install SpamAssassin with:

yum -y install spamassassin

 

Step 3

Then open the Exim configuration:

nano /etc/exim/exim.conf

 

Step 4

In this step, you add some routers in the Exim configuration for SpamAssassin (see the explanation at the bottom of this step). Search for the 'userforward' router, which starts with the following code:

userforward:
  driver = redirect
  check_local_user

Add an anti-spam router under the 'userforward' router (it is important that the anti_spam router is placed before the router(s) that take care of the delivery):

anti_spam:
  driver = accept
  condition = ${if and { {<{$message_size}{256K}} {!def:header_X-Spam-Flag:} {!eq {$received_protocol}{spam-scanned}}} {1}{0}}
  headers_remove = X-Spam-Flag:X-Spam-Report:X-Spam-Status:X-Spam-Level:X-Spam-Checker-Version
  transport = antispam

Then copy the router that you use to deliver mail and give it the name 'antispam_delivery'. Have you followed our Exim manual for the installation and configuration of Exim? Then you copy the router with the name 'virtual_router'.

Place the copy directly under the 'anti_spam' router and add the following code:

condition = ${if and { {def:h_X-Spam-Flag:} {eq {$h_X-Spam-Flag:}{YES}}} }

The result then looks like this:

antispam_delivery:
  driver = accept
  condition = ${if and { {def:h_X-Spam-Flag:} {eq {$h_X-Spam-Flag:}{YES}}} }
  require_files = +/home/vmail/$local_part@$domain/
  transport = anti_spam_delivery
Explanation

By placing the anti_spam router after the routers that cover forwards / out-of-office etc. and before any delivery routers (e.g. the virtual_router and localuser routers), all incoming mail is first sent via the spam_check router, which uses the antispam transport to have Spamassassin perform the check. After the spam check, the mail is forwarded to the routers that take care of the delivery.

The advantage of this structure is that Spamassassin uses quite a few resources. If you run the SpamAssassin check directly on incoming mail instead of passing the mail separately through a spam router / transport, that would result in an additional attack point on your server, causing your resources to be overloaded faster.

anti_spam

  • condition= ${ifetc: scans all mail of 256k and smaller (you can also adjust this to 512k, for example) that have not yet been scanned by SpamAssassin.
  • driver=accept: if the set conditions are met, the transport antispam is used.
  • headers_remove etc: removes all X-Spam-* headers from the incoming mail. They still have to be added but can already be present if a rogue party tries to mislead your spam protection.

antispam_delivery

This router works the same as the regular 'virtual router' router, with an addition:

condition = ${if and { {def:h_X-Spam-etc: ensures that if the mail is checked for spam, it is delivered to the anti_spam_delivery transport.


 

Step 5

 

In addition to these new routers, you also need new transports for delivering the mail. Scroll to the 'TRANSPORTS CONFIGURATION' and add the transport below at any location, for example above or below the 'local_delivery' transport:

antispam:
  driver = pipe
  command = /usr/sbin/exim -oMr spam-scanned -bS
  use_bsmtp
  transport_filter = /usr/bin/spamc -u $local_part@$domain
  home_directory = /tmp
  current_directory = /tmp

Then copy the transport you use for delivering mail and name it 'anti_spam_delivery'. Have you followed our Exim manual for the installation and configuration of Exim? Then, you copy the transport with the name 'virtual_delivery'.

The result looks like this:

anti_spam_delivery:
  driver = appendfile
  directory = /home/vmail/$local_part@$domain/.SPAM/
  maildir_format
  delivery_date_add
  envelope_to_add
  return_path_add
  user = vmail
  group = vmail
  mode = 0660
  mode_fail_narrower = false
Explanation

The antispam transport uses a driver of the 'pipe' type, so it can be delivered to a command. In this case, this is a command under 'command =' with which the spam check is performed and the additional spam filter that is used for this via the spamc command.

The anti_spam_delivery transport also works the same as the virtual_transport.


 

Step 6

By default, SpamAssassin is set to stop mail as spam with a score of 5 (see 'Spamassassin in short’). This is a pretty strict check that can lead to a number of false positives. For example, we see this more often when older mail software is used to send emails. Old software often contains errors in the layout of the mails, so that it can be classified as spam.

We therefore recommend using a value of 7 to 10 instead of 5. You can adjust this in the following file:

nano /etc/mail/spamassassin/local.cf

Adjust the value of the required_hits to the desired value, for example:

required_hits 8

Then, save your changes and close the file (ctrl + x> y> enter).

Individual Spamassassin rules can be found in the files in /usr/share/spamassassin. The content of these files falls outside the scope of this manual.


 

Step 7

Finally, restart Spamassassin and Exim:

systemctl restart exim
systemctl restart spamassassin

 

That brings us to the end of this tutorial. However, there are additional checks that you can perform to see if mail is spam: blacklist check. This tutorial explains how to enable blacklist control.

Should you have any questions left regarding this article, do not hesitate to contact our support department. You can reach them via the ‘ContactUs’ button at the bottom of this page.

If you want to discuss this article with other users, please leave a message under 'Comments'.

Has this article been helpful?

Create an account or log in to leave a rating.

Comments

Create an account or log in to be able to leave a comment.