Dovecot antispam with Rspamd (part 2)
Ahoy !
I realized that forgot about half of the
Rspamd &
Dovecot in
my last article,
so here is an attempt to correct this misstep.
In this article we'll configure Dovecot's
Sieve to understand how Rspamd assign spam
score and headers to emails. Then, we'll implement policies to reject
or filter spam from Sieve. If needed, we'll use the
spamtest
and spamtestplus
Sieve extensions.
This is the second part of the Dovecot & Rspamd integration setup, talking about mail filtering using Dovecot spamtest. If you missed the first part about Rspamd autolearn integration with Dovecot antispam plugin, you'll find it here.
Dovecot Sieve configuration
First we will configure Dovecot's Sieve to parse
Rspamd X‑Spamd‑Result
header, so
later we may filter from Sieve based on the email's spam "score".
conf.d/90-sieve.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | ... # Path to a script file or a directory containing script files that need to be # executed before the user's script. If the path points to a directory, all # the Sieve scripts contained therein (with the proper .sieve extension) are # executed. The order of execution within a directory is determined by the # file names, using a normal 8bit per-character comparison. Multiple script # file or directory paths can be specified by appending an increasing number. sieve_before = /usr/local/etc/dovecot/sieve/before.d #sieve_before2 = #sieve_before3 = (etc...) ... # Which Sieve language extensions are available to users. By default, all # supported extensions are available, except for deprecated extensions or # those that are still under development. Some system administrators may want # to disable certain Sieve extensions or enable those that are not available # by default. This setting can use '+' and '-' to specify differences relative # to the default. For example `sieve_extensions = +imapflags' will enable the # deprecated imapflags extension in addition to all extensions were already # enabled by default. #sieve_extensions = +notify +imapflags sieve_extensions = +spamtest +spamtestplus sieve_spamtest_status_type = score # Rspamd output looks like: X-Spamd-Result: default: False [12.00 / 15.00] sieve_spamtest_status_header = X-Spamd-Result: default: [[:alnum:]]+ \[(-?[[:digit:]]+\.[[:digit:]]+) / -?[[:digit:]]+\.[[:digit:]]+\] sieve_spamtest_max_header = X-Spamd-Result: default: [[:alnum:]]+ \[-?[[:digit:]]+\.[[:digit:]]+ / (-?[[:digit:]]+\.[[:digit:]]+)\] ... |
For more infos on Dovecot's spamtest extensions, see the official documentation.
When using
Rmilter
You need to have extended_spam_headers = yes
in the
spamd
section of
rmilter.conf (otherwise you won't have
the X‑Spamd‑Result
header).
before.d Sieve filters
As configured before, any Sieve script in /usr/local/etc/dovecot/sieve/before.d will be run by Dovecot. This let us write some default Sieve code that will be run on every incoming emails, very handy.
You need to be
sure to manually pre-compile the scripts specified by
sieve_before
after any changes using the sievec tool:
# sudo sievec /usr/local/etc/dovecot/sieve/before.d
a simple example
/usr/local/etc/dovecot/sieve/before.d/no-spam.sieve
1 2 3 4 5 6 7 8 9 10 | require "fileinto"; require "imap4flags"; if header :is "X-Spam" "Yes" { fileinto "Junk"; setflag "\\seen"; stop; } /* Other messages get filed into Inbox or to user's scripts */ |
Here we rely on the X-Spam
header, which is the result of the
add_header
action. This way let us handle the threshold from
the Rspamd configuration.
a less simple example
/usr/local/etc/dovecot/sieve/before.d/no-spam.sieve
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | require "spamtestplus"; require "fileinto"; require "relational"; require "comparator-i;ascii-numeric"; require "imap4flags"; if spamtest :value "gt" :comparator "i;ascii-numeric" :percent "95" { discard; stop; } elsif spamtest :value "ge" :comparator "i;ascii-numeric" :percent "50" { fileinto "Junk"; setflag "\\seen"; stop; } /* Other messages get filed into Inbox or to user's scripts */ |
This example make full use of the spamtest
parsing we
configured earlier:
- discard emails with a score superior to 95%,
-
deliver into the
Junk
folder emails with a score superior or equal to 50%.
Of course YMMV, and this method let you do some crazy stuff with Sieve (tell me if you do!).
That's it for now, have fun!
sieve_before
directory (we'll get back to this later).spamtest
andspamtestplus
Sieve extensions.sieve_spamtest_status_type
toscore
, meaning that we'll have a numeric score.X‑Spamd‑Result
header:sieve_spamtest_status_header
is a regexp that should match the email's spam score…sieve_spamtest_max_header
a regexp matching what could be the maximum spam score for this email. We will then be able from Sieve to express our filters in percent of spam probability if we want to.