Exim and Spamassassin: Rewriting headers, adding SPAM and Score to Subject

This tutorial is a follow-up to my article Setting up Exim4 Mail Transfer Agent with Anti-Spam, Greylisting and Anti-Malware.

I finally got around solving this problem: If an email has a certain spam score, above a certain threshold, Exim should rewrite the Subject header to contain the string *** SPAM (x.x points) *** {original subject}

Spamassassin has a configuration option to rewrite a subject header in its configuration file /etc/spamassassin/local.cf  …

rewrite_header Subject ***SPAM***

… but this is misleading, because it is used only when Spamassassin is used stand-alone. If used in combination with a MTA (Mail Transfer Agent) like Exim, the MTA is ultimately responsible for modifying emails. So, the solution lies in the proper configuration of Exim. To modify an already accepted message, the Exim documentation suggests a System Filter. You can set it up like this:

Enable the system filter in your main Exim configuration file. Add to it:

system_filter = /etc/exim4/system.filter
system_filter_user = Debian-exim

Then create the file /etc/exim4/system.filter , set proper ownership and permission, then insert:

if $header_X-Spam-Score matches "^[^-0][0-9\.]+" and ${sg{$header_X-Spam-Score:}{\\.}{}} is above 50
then
headers add "Old-Subject: $h_subject"
headers remove "Subject"
headers add "Subject: *** SPAM ($header_X-Spam_score points) *** $h_old-subject"
headers remove "Old-Subject"
endif

This means: If the header $header_X-Spam_score_int  is present (has been added by Exim in the acl_check_data  ACL section, see my previous tutorial), and is more than 50 (this is 5.0), rewrite the Subject header. The regular expression checks if the spam score is valid and not negative.

Note that in the acl_check_data section of the Exim config, you can deny a message above a certain spam score threshold. This means, in combination with this System Filter, you can do the following:

  • If spam score is above 10, reject/bounce email from the ACL.
  • If spam score is above 5, rewrite the Subject.

10 thoughts on “Exim and Spamassassin: Rewriting headers, adding SPAM and Score to Subject”

  1. Exim [4.84_1] gives a filter error if spamassassin returns a negative $header_X-Spam-Score-Int

    1. I get Error in system filter: malformed numerical string “-18\n0”
      My filter is
      if $header_X-Spam-Score-Int is not “” and $header_X-Spam-Score-Int is above 40
      then
      headers add “Old-Subject: $h_subject”
      headers remove “Subject”
      headers add “Subject: ## Maybe-SPAM ($header_X-Spam-Score points) ## $h_Old-Subject”
      headers remove “Old-Subject”
      endif

      1. Yes, I got the same error after a while. The following should work in most cases:

        if $header_X-Spam-Score matches “^[^-0][0-9\.]+” and ${sg{$header_X-Spam-Score:}{\\.}{}} is above 30

        1. Thanks Michael,
          I made the change you suggested but a message with the following did NOT get it’s Subject changed.
          X-Spam-Score: 5.4
          X-Spam-Score-Int: 54
          X-Spam-Bar: +++++

          1. The problem is back. I now see the following in the log file:
            1bKRsK-0000En-EB Error in system filter: malformed numerical string “2967\n-51”

            My filter is now :-
            if $header_X-Spam-Score matches “^[^-0][0-9\.]+” and ${sg{$header_X-Spam-Score:}{\\.}{}} is above 40
            then
            headers add “Old-Subject: $h_subject”
            headers remove “Subject”
            headers add “Subject: ## Maybe-SPAM ($header_X-Spam-Score points) ## $h_Old-Subject”
            headers remove “Old-Subject”
            endif

            //Ger

  2. This is actually a tad outdated. Exim4 ACLs now allow the remove_header modifier so the Subject header rewriting can be made much simpler in a data ACL:

    warn spam = nobody
    remove_header = Subject
    add_header = Subject: ***SPAM (score: $spam_score)*** $rh_Subject:

    //Ivar

  3. Thanks Michael,
    Pls update (score >Score) ,I not sure Why your system work but for me (Debian8) must be sensitive case ($header_X-Spam_Score)

    /etc/exim4/system.filter

    headers add “Subject: *** SPAM ($header_X-Spam_score points) *** $h_old-subject”
    to
    headers add “Subject: *** SPAM ($header_X-Spam_Score points) *** $h_old-subject”

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.