Exim & spam assassin – rejecting spam at different scores
So I’ve spent some time researching how to implement rejection of spam at different scores based on the recipients of a given message.
We didn’t like options A or B and option C isn’t sensible in this day and age.
Option D. For a given message, reject at the highest score for the given list of recipients. If a@example.com has a reject of 18, and b@example.com has a reject of 25 then a message sent to both will have a reject of 25. This isn’t ideal and it certainly doesn’t provide the detailed per user settings potentially available within spam assassin, but it’s certainly a reasonable compromise.
So, how do we do this?
Let’s define an expansion variable that we can re-use:
SPAM_REJECT_SCORE = ${lookup {${lc:$local_part@$domain}} lsearch* {/etc/spam-reject-scores} }
From this, we can see that we’re using a plain text aliases style file with a search for a default value if no match is found (that’s what the * does):
b@example.com: 25
*: 18
Now we add the following to the acl_smtp_rcpt (which may be called something different, find the ‘acl_smtp_rcpt =’ line in your config) ACL:
# If the acl_m0 isn't set, get the value from SPAM_REJECT_SCORE and set it.
accept condition = ${if def:acl_m0 {0}{1}}
set acl_m0 = SPAM_REJECT_SCORE
# If the SPAM_REJECT_SCORE value is higher than acl_m0, set it to the value from SPAM_REJECT_SCORE
accept set acl_m0 = ${if > {SPAM_REJECT_SCORE} {${acl_m0}} \
{SPAM_REJECT_SCORE} \
{${acl_m0}} \
}
Shiny! Now we need to do something with it to reject messages, so this is what I’ve got in my acl_smtp_data (which again might be named differently):
# Reject spam at high scores - value is an INTEGER!!!!
deny message = This message scored $spam_score spam points.
log_message = exceeded spam threshold with $spam_score points.
spam = nobody:true
condition = ${if >{$spam_score_int}{${eval:$acl_m0 * 10}}{1}{0}}
You’ll notice that the value is multiplied by 10 to turn it into an integer for comparison with the value returned by spam assassin. This bit me first time I tried to do this.
So testing should give you something like this:
[root@localhost ~]# exim -bh 209.85.229.17
..
220 localhost.localdomain ESMTP Exim 4.69 Tue, 23 Feb 2010 09:34:09 +0000
helo mail.google.com
250 localhost.localdomain Hello ww-in-f17.1e100.net [209.85.229.17]
MAIL FROM: bob@example.com
250 OK
RCPT TO: a@example.com
..
>>> processing "accept"
>>> check condition = ${if def:acl_m0 {0}{1}}
>>> = 1
>>> check set acl_m0 = ${lookup {${lc:$local_part@$domain}} lsearch* {/etc/spam-reject-scores} }
>>> = 18
>>> accept: condition test succeeded
250 Accepted
DATA
354 Enter message, ending with "." on a line by itself
Subject: !!!!!!PENIS ENLARGEMMENT!!!!11!!! cialis levitra soma
To: a@example.com
From: "Pammer, S"
Test SMTP session
GET YOUR VIAGRA HERE!!!!!!!!!! PORNOGRAPHY
see the attached file for details
viagra express Online Pharmacy No prescription needed No prescription needed
.
...
>>> processing "deny"
>>> check spam = nobody:true
>>> check condition = ${if >{$spam_score_int}{${eval:$acl_m0 * 10}}{1}{0}}
>>> = 1
>>> deny: condition test succeeded
>>> unspool_mbox(): unlinking '/var/spool/exim/scan/1NjrI5-0000FW-Ow/1NjrI5-0000FW-Ow.eml'
550 This message scored 20.4 spam points.
LOG: 1NjrI5-0000FW-Ow H=ww-in-f17.1e100.net (mail.google.com) [209.85.229.17] F= rejected after DATA: exceeded spam threshold with 20.4 points.
Similar test to b@example.com finishes with:
>>> processing "deny"
>>> check spam = nobody:true
>>> check condition = ${if >{$spam_score_int}{${eval:$acl_m0 * 10}}{1}{0}}
>>> = 0
>>> deny: condition test failed
>>> processing "accept"
>>> accept: condition test succeeded
>>> unspool_mbox(): unlinking '/var/spool/exim/scan/1NjrKA-0000FZ-Q8/1NjrKA-0000FZ-Q8.eml'
LOG: 1NjrKA-0000FZ-Q8 <= bob@example.com H=ww-in-f17.1e100.net (mail.google.com) [209.85.229.17] P=smtp S=1941 from for b@example.com
250 OK id=1NjrKA-0000FZ-Q8
**** SMTP testing: that is not a real message id!
No pink meat was harmed in the making of this post…..
0 comments
Kick things off by filling out the form below.
Leave a Comment