für die Spamabwehr nutze ich auf meinem Mailserver Spamassassin (mit MySQL-Backend) als Postfix-Milter. Damit Nutzer den Filter selbstständig trainieren können, ist sa-learn über Dovecots IMAPSieve-Plugin angebunden. Meine Konfiguration entspricht soweit der Beispielkonfiguration aus dem Dovecot-Wiki.
Auf den ersten Blick scheint es keine Probleme zu geben: Beim Verschieben einer Mail in den Spam-Ordner wird das entsprechende Sieve-Skript aufgerufen, dieses ruft erfolgreich das Shellscript auf und dieses wiederum überreicht die Mail an sa-learn. Nun der Haken: Es sieht so aus, als würde Spamassassin die gelernten Token nicht speichern. Aufgefallen ist es dadurch, dass Spamassassin immer wieder dieselben Spammails durchlässt, obwohl diese bereits mehrfach als Spam markiert wurden. Das Problem lässt sich verifizieren, indem eine Mail, die durch den Nutzer in das Spam-Verzeichnis verschoben wurde (und somit bereits bekannt sein sollte), erneut manuell über die Shell an sa-learn übergeben wird. Das Ergebnis des Shellaufrufs ist wider Erwarten:
Code: Alles auswählen
Learned tokens from 1 message(s) (1 message(s) examined)
Zu Debug-Zwecken habe ich das Shellscript angepasst:
Code: Alles auswählen
#!/bin/sh
curUser=$(whoami)
user=${1}
mail="$(cat -)"
result=`echo "$mail" | /usr/bin/sa-learn -u $user -D --spam 2>&1`
echo "curUser: $curUser\nResult: $result\nUser: $user\nNachricht:\n\n$mail" | sendmail root
Code: Alles auswählen
...
Oct 31 11:34:56.585 [2521] dbg: bayes: baa517a4b89f38e7a73491cdae87643ef0e1d915@sa_generated already learnt as opposite, forgetting first
Oct 31 11:34:56.585 [2521] dbg: plugin: Mail::SpamAssassin::Plugin::Bayes=HASH(0x561800fd0240) implements 'forget_message', priority 0
Oct 31 11:34:56.585 [2521] dbg: check: pms new, time limit in 299.984 s
Oct 31 11:34:56.702 [2521] dbg: bayes: tokenized body: 327 tokens
Oct 31 11:34:56.703 [2521] dbg: bayes: tokenized uri: 144 tokens
Oct 31 11:34:56.703 [2521] dbg: bayes: tokenized invisible: 0 tokens
Oct 31 11:34:56.704 [2521] dbg: bayes: tokenized header: 42 tokens
Oct 31 11:34:56.988 [2521] dbg: bayes: tokenized body: 327 tokens
Oct 31 11:34:56.989 [2521] dbg: bayes: tokenized uri: 144 tokens
Oct 31 11:34:56.989 [2521] dbg: bayes: tokenized invisible: 0 tokens
Oct 31 11:34:56.989 [2521] dbg: bayes: tokenized header: 42 tokens
Oct 31 11:34:57.077 [2521] dbg: bayes: seen (baa517a4b89f38e7a73491cdae87643ef0e1d915@sa_generated) put
Oct 31 11:34:57.105 [2521] dbg: bayes: learned 'baa517a4b89f38e7a73491cdae87643ef0e1d915@sa_generated', atime: 1540974680
Oct 31 11:34:57.106 [2521] dbg: plugin: Mail::SpamAssassin::Plugin::Bayes=HASH(0x561800fd0240) implements 'learner_close', priority 0
Learned tokens from 1 message(s) (1 message(s) examined)
Auffällig ist: Bei einer Einlieferung über Dovecot lautet die Rückgabe von sa-learn stets Learned tokens from 1 message(s) (1 message(s) examined) - auch, wenn die Mail bereits zuvor über die Shell gelernt wurde. Wird das Skript hingegen über die Shell aufgerufen, so ist die Ausgabe (nach dem initialen Lernen) richtigerweise Learned tokens from 0 message(s) (1 message(s) examined). Der Shell-Aufruf lautet wie folgt:
Code: Alles auswählen
cat spam.txt | sudo -H -u vmail bash -c '/usr/lib/dovecot/sieve/sa-learn-spam.sh anonym@empfaeng.er'
Der Vollständigkeit halber hier noch die übrige Konfiguration:
Code: Alles auswählen
plugin {
# https://wiki2.dovecot.org/HowTo/AntispamWithSieve
sieve_plugins = sieve_imapsieve sieve_extprograms
# From elsewhere to Spam folder
imapsieve_mailbox1_name = Junk
imapsieve_mailbox1_causes = COPY
imapsieve_mailbox1_before = file:/usr/lib/dovecot/sieve/report-spam.sieve
# From Spam folder to elsewhere
imapsieve_mailbox2_name = *
imapsieve_mailbox2_from = Junk
imapsieve_mailbox2_causes = COPY
imapsieve_mailbox2_before = file:/usr/lib/dovecot/sieve/report-ham.sieve
sieve_pipe_bin_dir = /usr/lib/dovecot/sieve
sieve_global_extensions = +vnd.dovecot.pipe +vnd.dovecot.environment
}
Code: Alles auswählen
require ["vnd.dovecot.pipe", "copy", "imapsieve", "environment", "variables"];
if environment :matches "imap.user" "*" {
set "username" "${1}";
}
pipe :copy "sa-learn-spam.sh" [ "${username}" ];