Using Spamprobe Via Sieve

This is a brief outline of how to take advantage of using only Sieve scripts to manage spam via Spamprobe and Dovecot IMAP services on a Ubuntu Zesty 17.04 server. In my case I use separate UID:GIDs for each virtual domain (but not for each user) and a custom path to each mailbox so the path arguments to spamprobe below would have to modified for your situation. You would need to install these packages…

apt install dovecot-core dovecot-imapd dovecot-lmtpd dovecot-managesieved \
    dovecot-mysql dovecot-sieve dovecot-sqlite spamprobe

This setup allows for retraining incorrectly filtered spam (either spam in your Inbox or good messages in your Spam folder) by simply dragging those messages in to or out of the Spam folder and the Sieve scripts featured below will take care of retraining those incorrectly tagged messages automatically.

First we add these rules to a Dovecot config file. I’ll assume /etc/dovecot/dovecot.conf for simplicity…

plugin {
  imapsieve_mailbox1_before = file:~/sieve/retrain-as-spam.sieve
  imapsieve_mailbox1_causes = COPY
  imapsieve_mailbox1_name = Spam
  imapsieve_mailbox2_before = file:~/sieve/retrain-as-good.sieve
  imapsieve_mailbox2_causes = COPY
  imapsieve_mailbox2_from = Spam
  imapsieve_mailbox2_name = *
  sieve = file:~/sieve;active=~/.dovecot.sieve
  sieve_dir = ~/sieve
  sieve_execute_bin_dir = /etc/dovecot/sieve
  sieve_extensions = +vnd.dovecot.debug +editheader +vnd.dovecot.execute
  sieve_plugins = sieve_imapsieve sieve_extprograms

Next we assume there is a directory (listed above) available for the symlink to the /usr/bin/spamprobe binary. You should be able to copy and paste the sections below directly into a root shell…

[[ ! -d /etc/dovecot/sieve ]] && mkdir -p /etc/dovecot/sieve
cd /etc/dovecot/sieve
ln -s /usr/bin/spamprobe

Now to set up a user we su - someuser and change directory to their virtual homedir where their Maildir exists and install the personal Sieve scripts…

[[ ! -d sieve ]] && mkdir sieve

cat << 'EOS' > sieve/retrain-as-good.sieve
require ["vnd.dovecot.execute", "environment", "variables", "imapsieve"];
if environment :matches "imap.mailbox" "*" {if string "${1}" "Trash" { stop; }}
execute :pipe "spamprobe" ["-c", "-d", ".spamprobe", "good"];

cat << 'EOS' > sieve/retrain-as-spam.sieve
require ["vnd.dovecot.execute"];
execute :pipe "spamprobe" ["-c", "-d", ".spamprobe", "spam"];

cat << 'EOS' > sieve/spamprobe.sieve
require ["vnd.dovecot.execute", "fileinto", "envelope", "variables", "editheader"];
if envelope :localpart :matches "to" "*" { set "lhs" "${1}"; }
if envelope :domain :matches "to" "*" { set "rhs" "${1}"; }
execute :pipe :output "SCORE" "spamprobe" ["-c", "-d", "/home/u/${rhs}/home/${lhs}/.spamprobe", "receive"];
addheader :last "X-Spam" "${SCORE}";
if header :matches "X-Spam" "SPAM*" { fileinto "Spam"; }

ln -s sieve/spamprobe.sieve .dovecot.sieve

We need a .spamprobe directory with preferably a pre-seeded corpus of ham and spam but the filtering database will get auto created if you do not have any spam for pre-training. Optional: If you do not have a ham/spam corpus handy then you can use this one…

tar xf _etc_spamprobe.tgz
mv spamprobe .spamprobe
spamprobe -d .spamprobe counts # to check all is well

And finally restart Dovecot…

sudo systemctl restart dovecot

That is mostly it and with a bit of luck any incoming spam should end up in the Spam folder and any incorrectly tagged messages (spam messages in your Inbox or good messages in your Spam folder) can simply be dragged to or from the Spam folder to retrain the Spamprobe filtering database.