Manage spams with dovecot

You might want to help the anti-spam to learn if it missed spams or got wrong for some messages.

If you use dovecot and a mail client with IMAP protocol, you can move spams in "Junk" folder so the anti-spam recognize them in the future. On the contrary, moving a mail from "Junk" to "INBOX" folder indicates it is legitimate.

No matter if you use rspamd or spammassassin, we will see both. 3 steps are necessary :

1. Install dovecot plugin.

2. Enable and configure the plugin.

3. Create scripts so the anti-spam can learn.

It is described in dovecot documentation (you should read 😉)

First, let's install dovecot pigeonhole plugin :

# pkg_add dovecot-pigeonhole

Add "imap_sieve" in plugins list to enable it at the end of "/etc/dovecot/local.conf" :

protocol imap {
	mail_plugins = $mail_plugins imap_sieve

Then, still in dovecot's local.conf, configure sieve plugin si it run scrits according to where messages are moved..

plugin {
	sieve_plugins = sieve_imapsieve sieve_extprograms
	# When a message is moved in Junk folder; report as spam
	imapsieve_mailbox1_name = Junk
	imapsieve_mailbox1_causes = COPY
	imapsieve_mailbox1_before = file:/usr/local/lib/dovecot/sieve/report-spam.sieve
	# When a mail is removed from Junk folder : it is nor a spam 
	imapsieve_mailbox2_name = *
	imapsieve_mailbox2_from = Junk
	imapsieve_mailbox2_causes = COPY
	imapsieve_mailbox2_before = file:/usr/local/lib/dovecot/sieve/report-ham.sieve
	sieve_pipe_bin_dir = /usr/local/lib/dovecot/sieve
	sieve_global_extensions = +vnd.dovecot.pipe +vnd.dovecot.execute

Now create two files in the directory "/usr/local/lib/dovecot/sieve/".

The first is "report-spam.sieve":

require ["vnd.dovecot.pipe", "copy", "imapsieve", "environment", "variables"];
if environment :matches "imap.user" "*" {
  set "username" "${1}";
pipe :copy "" [ "${username}" ];

The second is "report-ham.sieve" :

require ["vnd.dovecot.pipe", "copy", "imapsieve", "environment", "variables"];
if environment :matches "imap.mailbox" "*" {
  set "mailbox" "${1}";
if string "${mailbox}" "Trash" {
if environment :matches "imap.user" "*" {
  set "username" "${1}";
pipe :copy "" [ "${username}" ];

Now reload dovecot and compile the above scripts :

# rcctl restart dovecot
# sievec /usr/local/lib/dovecot/sieve/report-spam.sieve
# sievec /usr/local/lib/dovecot/sieve/report-ham.sieve

As you may have notices, the above files call "" and "". Thoses scripts will be different wether you use rspamd or spammassassin since they don't learn spams/hams with the same command. Read the next part 😉.

Learning scripts.

Scripts below are stored in "/usr/local/lib/dovecot/sieve".

For spamassassin

/usr/local/bin/spamc -u ${1} -L spam -C report
/usr/loca/bin/spamc -u ${1} -L ham -C report

for rspamd

exec /usr/local/bin/rspamc -d "${1}" learn_spam
exec /usr/local/bin/rspamc -d "${1}" learn_ham

For both :

Scripts must be executables :

# chmod +x /usr/local/lib/dovecot/sieve/learn-*.sh

At last, reload dovecot:

# rcctl reload dovecot

Here you go, now your anti-spam will learn when you'll move messages in approriate folders.

Learn more with dovecot official documentation.