DSPAM automatisch trainieren

Wir setzen auf einigen Accounts DSPAM zur Filterung ein. Den Brückenschlag zwischen qmail und DSPAM schafft hierbei maildrop:

$ cat info/.qmail
|preline maildrop $HOME/dspamfilter

Der entsprechende Abschnitt in dspamfilter sieht dann so aus:

# DSPAM die Mail bewerten lassen
xfilter "/command/dspam --deliver=innocent,spam --stdout"

# Mail wegsortieren, wenn DSPAM das meint
if( /^X-DSPAM-Result: Spam/ )
{
  to "./Maildir/.0 Spamfilter.als Spam erkannt/"
}

# Ansonsten: In normales Maildir zustellen
to ./Maildir/

Nun basiert DSPAM letztlich auf Algorithmen aus dem Bereich der Statistik. Grob vereinfacht gesagt führt es eine Datenbank, in der er Wörter und Wortgruppen mit einem Wert zwischen 0 und 1 versieht, der aussagt, ob die Verwendung eher auf Spam (0) oder legitime Mails, also Ham (1) hindeutet. Anfangs haben alle Wörter einen mittleren Wert, der sich dann mit der Zeit durch Training nach oben oder unten verschiebt – oder in der Mitte bleibt, wenn ein Wort sowohl in Spam als auch in Ham häufig vorkommt.

Nun gibt es ab und zu aber Fälle, wo selbst das mehrfache Umlernen einer nicht als Spam erkannten Mail via „als Spam lernen“-Ordner einfach nicht den gewünschten Effekt erzielt; insbesondere dann, wenn sich DSPAM sowieso schon nicht so sicher ist, weil selbst die signifikantesten gefundenen Wörter und Wortgruppen eher im Mittelfeld liegen als gegen 0 oder 1 zu tendieren. Die Hauptforderung von Endkunden lautet dann schnell: „Setzt doch den Absender auf die Blacklist“. Diese Möglichkeit bietet qmail natürlich durch aus (wie control/badmailfrom), aber so global wollen wir solche Blacklists nicht pflegen. Aber in der Filterkonfiguration des Users, der sich das Blacklisting wünscht, können wir so etwas natürlich realisieren. Die einfachste Möglichkeit wäre sicherlich so etwas hier:

if( /^From: boeserspammer/ )
{
  to "./Maildir/.0 Spamfilter.als Spam erkannt/"
}

Allerdings würden wir ja schon gerne davon profitieren, dass die DSPAM-Treffergenauigkeit auch weiterhin berücksichtigt, dass der User diese Mails nicht haben will. Also haben wir an diesem Punkt ein automatisches Umlernen mit eingebaut, und damit das Filterscript flexibel bleibt, benutzen wir für die Liste der zu blacklistenden Adressen keinen fest eingebauten regulären Ausdruck, sondern die lookup-Funktion von maildrop, die reguläre Ausdrücke aus einer externen Datei einlesen kann.

Und so sieht’s aus:

# DSPAM die Mail bewerten lassen
xfilter "/command/dspam --deliver=innocent,spam --stdout"

# Wenn Mails von bekannten Spammern nicht als Spam erkannt wurden, als Spam umlernen
`test -f "dspamfilter-autolearn-spam"`
if( $RETURNCODE == 0 && ! /^X-DSPAM-Result: Spam/ && /^From:.*/ && lookup($MATCH, "dspamfilter-autolearn-spam") )
{
  xfilter "/command/dspam --class=spam --source=error --deliver=innocent,spam --stdout"
}

# Mail wegsortieren, wenn DSPAM das meint
if( /^X-DSPAM-Result: Spam/ || /^X-DSPAM-Reclassified: Spam/ )
{
  to "./Maildir/.0 Spamfilter.als Spam erkannt/"
}

# Ansonsten: In normales Maildir zustellen
to ./Maildir/

Es ist zu beachten, dass das X-DSPAM-Result trotz Umlernen identisch bleibt – DSPAM fügt lediglich noch einen X-DSPAM-Reclassified: Spam-Header hinzu. Also haben wir das Kriterium fürs Wegsortieren noch entsprechend erweitert.

Funktioniert prima; Kunde zufrieden. Die Pflege der Liste unerwünschter Adressen per einfacher Textdatei braucht praktisch keine Einarbeitung und kann schnell nebenbei erfolgen.