Spamassassin

Aus Knowledgebase
Version vom 11. April 2015, 15:10 Uhr von PoC (Diskussion | Beiträge) (→‎Beschleunigung durch Regelkompilation: Compiler notwendig)
(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)
Zur Navigation springen Zur Suche springen

Spamassassin ist ein weit verbreiter Spamfilter auf Perl-Basis, dadurch leider vergleichsweise ressourcenhungrig. Dieser auf Debian-basierte Systeme zugeschnittene Artikel soll ein paar Spezialitäten der Konfiguration aufzeigen.

Spamassassin schiebt die Mails durch ein umfangreiches Regelwerk aus Regular Expressions und vergibt auf zutreffende Regel(gruppen) Punkte: Positive Zahlen für "riecht nach Spam", negative für "riecht nach Ham", also nach erwünschter Mail. Überschreitet die Summe dieser Punkte einen Schwellwert (Default: 5), wird die Mail als Spam eingestuft.

Was nun mit der entsprechend kategorisierten Mail geschieht, ist wiederum abhängig vom Drumrum.

Struktur

Spamassassin ist zweigeteilt:

  • Spamd ist der eigentliche Scanner, dieser wird üblicherweise einmal beim Systemstart gestartet, macht ein fork() und wartet auf einem Socket auf Arbeit,
  • Spamc ist ein winziger Client, der schnell gestartet ist und Mails an den eigentlichen Spamd verfüttert.

Diese Zweiteilung ermöglicht es, eine Lastverteilung zu realisieren, denn der Spamd kann auch auf einem Inet-Socket lauschen.

Daneben existiert noch:

Bayes-Filterung

Der Bayes-Filter ist ein statistisches Verfahren, um Wortabfolgen mit weichen Prüfsummen zu versehen. Kurz gesagt kann man dem Spamassassin (meist pro Benutzer einer Maschine) eine Datenbank unterschieben, die dann diese Prüfsummen mit dem Vermerk auf Ham und Spam speichert. Näheres später.

AWL

In der Auto-Whitelist werden Absenderadressen mit IP-Blöcken, einem Zähler und einem Score gespeichert. Dieser Mechanismus sorgt dafür, dass eine Mailadresse von einem gegebenen Absendermailserver, die bisher immer nur Ham versendet hat, eine entsprechende Vorspannung bekommt. Sollte dann tatsächlich mal eine Mail zuviel Spam-Merkmale aufweisen, kompensiert die AWL-Vorspannung diesen und die Mail wird nicht als Spam gehandhabt. Damit dient dieser Mechanismus primär zur Vermeidung von Falscherkennungen.

Installation und Grundkonfiguration

Installation:

apt-get install spamassassin

Die Installation zieht noch ein paar Pakete hinterher, das ist aber notwendig. Hernach muß die Datei /etc/default/spamassassin editiert werden:

ENABLED=1
CRON=1
OPTIONS="--create-prefs --max-children 5 --helper-home-dir --listen-ip=127.0.0.1"

Soll diese Spamd-Instanz auch remote zugänglich sein, so muss --listen-ip angepasst, und einige weitere Optionen gesetzt werden:

OPTIONS="--create-prefs --max-children 5 --helper-home-dir --listen-ip=0.0.0.0 --allowed-ips=127.0.0.1,217.28.99.242,192.168.63.10 --allow-tell"

Jetzt ist die Datei /etc/spamassassin/local.cf dran. Ich empfehle folgende Settings:

internal_networks 192.168.59.0/24
report_safe 0
required_score 5.0
use_bayes 0
  • Internal_networks muss auf die eigene LAN-Range geändert werden.

Jetzt kann Spamassassin gestartet werden:

/etc/init.d/spamassassin start

Logmeldungen landen in /var/log/mail.log.

Mit dem Aufruf von

perldoc Mail::SpamAssassin::Conf

kann die Dokumentation zur Konfiguration eingesehen werden.

Die Konfigurationsparameter whitelist_from und blacklist_from sollten als Notlösung, als Holzhammermethode verstanden werden. Hier besteht ein Einfallstor für nicht erkannten Spam, Absenderadressen lassen sich beliebig fälschen. Hat man bereits Mails von diesem Absender erhalten, kann es eher sinnvoll sein, den entsprechenden Scorewert in der (SQL-basierten) AWL anzupassen.

Benutzerbezogene Konfiguration

Pro User, der den Spamfilter benutzen möchte, legt sich eine Datei .procmailrc in seinem Home an. Inhalt:

:0fw:
|/usr/bin/spamc

Anhand der in der Mail hinzugefügten Header kann das Mailprogramm[1] nun die Mails sortieren. Das kann man —so man IMAP Zugriff hat oder mit Pine Mails bearbeitet— auch schon von procmail(1) vorsortieren lassen. An obige .procmailrc muss dazu folgendes angehängt werden:

:0:
* ^X-Spam-Status: Yes, .*$
mail/Spam

Damit landen die als Spam erkannten Mails dann automatisch in einem Ordner "Spam".

Erweiterungen

Über Erweiterungen der Konfiguration kann die Funktion vom Spamassassin verbessert werden. Die folgenden Konfigurationserweiterungen können als Module verstanden werden, die beliebig miteinander kombiniert werden können.

Nach jeder Änderung der Konfigurationsdateien in /etc/spamassassin empfehle ich einen Neustart vom Spamassassin:

/etc/init.d/spamassassin restart

Unerwünschte Sprachen filtern

Ab 2009 kann eine Zunahme von Spam in fremden Sprachen und/oder anderen Zeichensätzen beobachtet werden. Was man nicht übersetzen oder gar lesen kann, ist daher höchstwahrscheinlich unerwünscht. Dazu müssen folgende Konfigurationsanpassungen durchgeführt werden:

In /etc/spamassassin/v310.pre

loadplugin Mail::SpamAssassin::Plugin::TextCat

(ist auskommentiert, muss einkommentiert werden)

In /etc/spamassassin/local.cf:

ok_languages en de
ok_locales en

Die Liste kann man nach Gusto anpassen. Achtung, dieses Modul ist sehr umfangreich und braucht dementsprechend CPU-Ressourcen.

Beschleunigung durch Regelkompilation

Um die CPU-Last bei hohem Maildurchsatz wieder etwas in den Griff zu bekommen, empfiehlt sich das Vorkompilieren der Regelsätze. Dazu wird re2c, ein Übersetzer von Regexp nach C-Quellcode verwendet. Ebenso muss dann auch ein C-Compiler installiert sein:

apt-get install re2c build-essential

In /etc/spamassassin/v320.pre muss die folgende Zeile einkommentiert werden:

loadplugin Mail::SpamAssassin::Plugin::Rule2XSBody

Danach genügt ein Aufruf von sa-compile, um den Vorgang anzustossen. Ein Neustart des SA wird diesen veranlassen, die Binärregeln zu verwenden.

Das Updatescript sa-update wird nach dem Update auch wieder sa-compile benutzen, um die neuen Regeln zu übersetzen.

Gefälschte Bounces

Über eine Headeranalyse kann Spamassassin Backscatter und als Bounce getarnten Spam filtern. Dazu muss er wissen, welche Mailrelays trusted sind, also von welchen Mailrelays normalerweise legitimerweise Bounces an einen selbst erzeugt werden. In der Regel ist das der eigene Server und der providerseitige Mailserver, dessen Namen man anhand der Received-Headerzeilen feststellen kann.

In /etc/spamassassin/local.cf:

whitelist_bounce_relays leela.pocnet.net ci.pocnet.net

Razor

Razor ist eine Software von Cloudmark, die man sich am einfachsten als verteilte Bayes-Datenbank vorstellen kann. Spamassassin kann Razor nutzen, um zusätzliche Anhaltspunkte über die Spammigkeit einer Mail zu erhalten.

apt-get install razor

Nach einem Neustart vom SA steht Razor automatisch zu Verfügung. Ggfs. muss der TCP-Port 2703 an einer vorhandenen Firewall nach draußen geöffnet werden.

Wenn man den eigenen Spam bei Cloudmark als Spam melden möchte, kann man sich mit

razor-admin -register

bei Cloudmark registrieren. Das Programm würfelt einen Benutzernamen und Paßwort selbst aus.

Danach muss die eigene .procmailrc angepasst werden:

:0c
* ^X-Spam-Status: Yes, .*$
|/usr/bin/razor-report -f

Dieser Regelsatz wirkt als Filter und muss irgendwo zwischen die Regeln für Durch-Spamc-Schieben und Nach-Spamordner-Verschieben eingefügt werden.

iXhash

Siehe dazu auch die Apache-Projektseite bzw. die Erklärung, was dahinter steckt. Kurz gesagt handelt es sich um eine DNS-basierte Liste von IP-Adressen, die durch Spamversand aufgefallen sind.

Nach Download und Auspacken des Archives befindet sich im Archivordner ein weiterer Unterordner namens iXhash. Beide Dateien iXhash.cf und iXhash.pm werden nach /etc/spamassassin/ verschoben.

In iXhash.cf wird danach die erste Zeile mit dem Pfad zur .pm-Datei angepasst. Damit ist die Installation abgeschlossen. SA-Restart nicht vergessen.

Bayes

Die Erkennungsrate mit dem Standardspamassassin ist lächerlich gering. Daher empfehle ich, den SA als lernfähige Variante einzusetzen. Ein sehr großer Vorteil wäre, an dieser Stelle bereits eine ganz erhebliche Menge an Ham- und Spammails gebunkert zu haben, also pro Kategorie ≥ 1000 Stück. Hier ist Menge ein großer Vorteil: Beispiele für den Bayes-Mechanismus, was man haben möchte und was nicht. Je mehr, je besser.

Es wird nicht empfohlen, Mails aus der Outbox zu verfüttern: Der Mechanismus wird ja auch nur eingehende Mails klassifizieren, nicht ausgehende.

Konfiguration

In /etc/spamassassin/local.cf:

use_bayes 1   # Steht von oben noch als 0 drin, kann aber auch ganz gelöscht werden 
lock_method flock
bayes_learn_during_report 0  # Das erst ab ca. 1000 Spam/Ham Mails einschalten
bayes_expiry_max_db_size 500000
bayes_auto_expire 0
bayes_learn_to_journal 1
bayes_auto_learn_threshold_spam 6
# Rewrite scoring a bit to get more dependency on bayes
score BAYES_99 (6)
bayes_ignore_header X-Bogosity
bayes_ignore_header X-Spam-Flag
bayes_ignore_header X-Spam-Status
  • bayes_auto_expire bedeutet, dass die Datenbank sich selbst bereinigt, wenn die Anzahl der ntoks über bayes_expiry_max_db_size steigt. Die Wahrscheinlichkeit, dass dies Tagsüber passiert, ist hoch. Je nach Serverperformanz und Wert von bayes_expiry_max_db_size dauert diese Bereinigung dann 5-20 Minuten. Währenddessen kann der SA nicht auf die Datenbank zugreifen. Dadurch wird die Mailzustellung erheblich verzögert. Es wird daher empfohlen, die Expiry per Cronjob auf eine definierte Zeit zu legen, wo diese nicht stört. Aufruf:
sa-learn --force-expire
  • bayes_learn_to_journal empfiehlt sich bei hohem Maildurchsatz. Damit landet nicht sofort jede Mailprüfsumme in der Datenbank, was den Nachteil hat, dass diese nicht zur Klassifizierung herangezogen wird, aber auch den Vorteil, dass Schreibvorgänge in die Datenbank seltener werden, was sich in einer im Mittel höheren Scangeschwindigkeit zeigt.

Datenbank

Nun muss man eine Datenbank mit Prüfsummen aufbauen. Diese liegt in der Regel im Homeverzeichnis des Benutzers[2], der die oben beschriebene .procmailrc erstellt hat. Die Datenbank wird über Berkeley-DB abgebildet. Dieser Benutzer muss auch die beschriebenen Schritte durchführen, damit die Mails in der richtigen Datenbank landen. Hier wird angenommen, dass die Mails:

  • lokal auf dem Server liegen (IMAP),
  • als MBox vorliegen. Sa-learn kann auch mit Maildir umgehen.

Mailordner mit "guten" Mails in die DB einlesen:

sa-learn --progress --mbox --ham /var/mail/poc

Mailordner mit "schlechten" Mails in die DB einlesen:

sa-learn --progress --mbox --spam mail/Spam

Wenn bayes_min_ham_num gute und bayes_min_spam_num (Default: 200) schlechte Mails zusammengesammelt wurden, setzt der Bayes-Mechanismus ein und klassifiziert diese dann zusätzlich.

Wieviele Mails schon klassifiziert wurden kann mit

sa-learn --dump magic

feststellen. nham und nspam sind die Variablen, auf die es ankommt.

Wenn mal eine Menge Mails zusammengekommen ist (an die 1000 Stück pro Kategorie), dann kann bayes_learn_during_report auf 1 gesetzt werden. Der SA lernt dann selbständig Mails mit Score ≥ 6 als Spam und Mails mit Score ≤ 0.5 als Ham an und trainiert sich damit fortlaufend selbst. Ab diesem Punkt kann man den SA normalerweise vor sich hinwerkeln lassen und vergessen.

Diese Variablen oben herunterzusetzen, damit Bayes früher anspringt, ist möglich, man muss aber dann mehr Handarbeit durch Fehlklassifizierungen einkalkulieren und ist nicht wirklich sinnvoll.

Die Routinen zum Erzeugen der Datenbank erzeugen übrigens in Verbindung mit ext3-Dateisystemen (Journal) ganz erhebliche Plattenlast, was gerade bei PATA-Maschinen dafür sorgen dürfte, dass man nebenher wenig vernünftig arbeiten kann. Wenn man also z. B. sein mehrere 100 MB über 10 Jahre umfassendes Mailarchiv einlesen möchte, so empfiehlt es sich, dies nicht auf einer ext3-Partition zu tun:

  • Ext3 vorher ausschalten (je nach dem nur mit Reboot möglich),
  • sa-learn einen anderen Pfad für die Datenbank mitgeben,
  • Letzten Punkt kombinieren mit einer RAM-Disk.

Diese manuellen Aufrufe kann man natürlich alle per cron automatisieren. Mails, die schon klassifiziert wurden, werden nicht nocheinmal in der Datenbank vermerkt. Wenn eine Mail vorher allerdings (versehentlich) als schlecht klassifiziert wurde und wird nochmal neu mit --ham klassifiziert, so fliegt der Spameintrag aus der DB raus und es wird ein Hameintrag daraus. Dadurch kann man die Mailordner schadlos immer wieder einlesen und falsch klassifizierte Mails einfach in der Gegend herumschieben bis sie im richtig zu klassifizierenden Ordner gelandet sind.

Datensicherung/Datenaustausch

Die benutzerbezogene Datenbank kann mit

sa-learn --backup > backupdatei.txt

in eine Textdatei exportiert werden, zur Datensicherung.

sa-learn --clear
sa-learn --restore backupdatei.txt

liest dieses Backup wieder ein, nachdem die vorige Datenbank gelöscht wurde; siehe hierzu auch oben die Punkte zur Geschwindigkeit in Sachen Datenbank.[3]

Dieser Mechanismus kann auch dazu verwendet werden, Benutzern schonmal einen gewissen Grundstock an Prüfsummen zu Verfügung zu stellen.

Datenbankchecks

Von Zeit zu Zeit empfiehlt es sich, die DBM-Dateien auf Konsistenz zu prüfen. Dazu sind die jeweils aktuellen Berkeley-DB Programme zu installieren:

apt-get install db4.6-util

Die Überprüfung geschieht mit

db4.6_verify ${HOME}/.spamassassin/bayes_seen
db4.6_verify ${HOME}/.spamassassin/bayes_toks
db4.6_verify ${HOME}/.spamassassin/auto-whitelist

Keine Fehlermeldung ist gut, Fehlermeldung bedeutet i. d. R. eine defekte Datei. Recovery ist relativ einfach:

  1. Backup der defekten Datenbank anlegen,
  2. Alte Datenbank löschen,
  3. Backup einspielen.

Während dieser Vorgänge sollte verhindert werden, dass die Datenbank benutzt wird, also z. B. durch Stoppen des Mailsystems.

Möglicherweise kann eine Reparatur auch mit db4.6_recover erfolgen.

MySQL als Datenbank

MySQL als Datenbank hat gewisse Vorteile gegenüber den DBM-Dateien:

  • Besseres Locking[4],
  • Daten sind einfacher zugänglich als in DBM-Dateien, daher
    • Möglichkeit der einfachen AWL-Bereinigung bzw. Anpassung von Scorewerten,
  • Möglichkeit, eine zentrale Datenbank für mehrere SA-Instanzen auf verschiedenen Rechnern zu verwenden.

Zuallererst muss MySQL vorbereitet werden. Nach Anmeldung am MySQL-Monitor (mysql -uroot -p) wird die Datenbank angelegt, sowie die Berechtigungen konfiguriert:

CREATE DATABASE spamassassin DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_general_ci;
GRANT ALL ON spamassassin.* TO spamassassin IDENTIFIED BY 'spamassassin';
GRANT ALL ON spamassassin.* TO spamassassin@localhost IDENTIFIED BY 'spamassassin';

Es empfiehlt sich, ggfs. mit pwgen(1) ein anderes Passwort zu würfeln und jenes auch zu verwenden.

Der MySQL-Monitor kann nun verlassen werden, damit die Tabellenstrukturen angelegt werden können:

cat /usr/share/doc/spamassassin/sql/bayes_mysql.sql /usr/share/doc/spamassassin/sql/awl_mysql.sql \
  mysql -uspamassassin -pspamassassin spamassassin

Zur Datenmigration sollte nun ein Backup angelegt werden, siehe weiter oben.

Jetzt kann die Konfiguration angepasst werden, dazu muss in /etc/spamassassin/local.cf ergänzt werden:

bayes_store_module Mail::SpamAssassin::BayesStore::MySQL
auto_whitelist_factory Mail::SpamAssassin::SQLBasedAddrList

bayes_sql_dsn DBI:mysql:spamassassin:localhost
bayes_sql_username spamassassin
bayes_sql_password spamassassin

user_awl_dsn DBI:mysql:spamassassin:localhost
user_awl_sql_username spamassassin
user_awl_sql_password spamassassin
user_awl_sql_table awl

Gelöscht werden sollte:

  • bayes_learn_to_journal
  • lock_method

Weiterhin ist in /etc/default/spamassassin:

  • --helper-home-dir zu löschen,
  • -u spamassassin -q -x zu ergänzen.

Nun kann (nach dem obligatorischen SA-Neustart) das Backup wieder eingespielt werden. Achtung, spätestens hier sollte überlegt werden, ob weiterhin jeder Benutzer seine eigene Datenbasis haben soll oder ob eine systemweite Datenbank, von der alle Benutzer etwas haben, nicht sinnvoller wäre.[5]

Das Einspielen der/des Datenbankbackup(s) muss mit dem jeweiligen Benutzer geschehen, damit die Zuordnung der Datensätze zu den Benutzern automatisch passt. Es ist nicht möglich, Datenbanken zusammenfzuführen, bei einer Migration von Benutzer nach Systemweit muss also geprüft werden, wessen Datenbasis als Ausgang für die systemweite Datenbank genutzt wird.

Die systemweite Einbindung für alle Benutzer würde dann über /etc/procmailrc geschehen, im Beispiel hier beherbergt der Benutzer spamassassin die Datensätze für alle Benutzer:

DROPPRIVS=yes
:0fw:
|/usr/bin/spamc -u spamassassin

Sämtliche Pflege und Abfrage der Datenbank muss ab jetzt mit dem Benutzer spamassassin erfolgen, entweder über su(1) oder direktem Login. Crontabs sind daher unbedingt zu prüfen und bereinigen.

Nicht mehr auf dem System befindliche Benutzer haben noch immer Daten in der Datenbank, das kann mit

sa-learn --clear

unter der jeweiligen Benutzerid erledigt werden.

AWL-Bereinigung

Die AWL kann mit Bordmitteln des SA nicht bereinigt werden. Sie wächst im Laufe der Zeit immer weiter und erreicht relativ schnell Größen, bei denen signifikante Geschwindigkeitseinbußen beim Scannen festgestellt werden können. Die Datenbank füllt sich schnell mit Werten, da ein Großteil des Spam heutzutage von Zombierechnern über Einwahl-IPAs stammt. Eine Analyse[6] hat gezeigt, dass über 90% der Datensätze einer 6 Monate alten AWL einen Zählerstand von 1 aufweisen.

Eine einfache Ergänzung der Tabellendefinition hilft bei der Feststellung, wie alt diese Datensätze sind:

mysql -uspamassassin -pspamassassin spamassassin -e \
  "ALTER TABLE awl ADD `last_update` timestamp NOT NULL \
  default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP"

Es hat sich gezeigt, dass nach einer Woche ab dieser Änderung noch immer über 80% der aktualisierten/hinzugefügten Datensätze weiterhin einen Zählerstand von 1 aufweisen und daher verwaist sind. Ebenso besteht wenig Notwendigkeit, Datensätze mit beliebigen Zählerständen aufzubewahren, die über einen gewissen Zeitraum hinweg nicht mehr benutzt (aktualisiert) wurden. Diese Datensätze können mit einer AWL in MySQL sehr einfach gelöscht werden, was die Datenbank klein hält und daher zur Performanceverbesserung beiträgt.

mysql -uspamassassin -pspamassassin spamassassin -e \
  "DELETE FROM awl WHERE (count=1 AND last_update<DATE_SUB(NOW(), INTERVAL 1 WEEK)) OR \
  (last_update<DATE_SUB(NOW(), INTERVAL 1 MONTH))"

Die o. g. Datenbank wurde damit von über einer Million Datensätze befreit, die Scanzeit ging von 30s pro Mail auf 1,5-3s zurück.

Dieses Aufräumen lässt sich prima über Cron automatisieren.

Statistiken über die Daten können folgendermassen erhalten werden:

mysql -uspamassassin -pspamassassin spamassassin -e \
  "SELECT COUNT(*) AS Loeschbar FROM awl WHERE \
  (count=1 AND last_update<DATE_SUB(NOW(), INTERVAL 1 WEEK)) OR \
  (last_update<DATE_SUB(NOW(), INTERVAL 1 MONTH)); \
  SELECT COUNT(*) AS Gesamt FROM awl;"
Datenbanksharing

In einer verteilten Umgebung ist es sinnvoll, eine gemeinsame Bayes-Datenbank für alle Hosts zu verwenden. Das ist über reine MySQL-Verbindungen nicht sauber abbildbar, da Spamassassin keine Prüfung auf duplicate keys vornimmt, was eine eventuelle Replikation nachhaltig stört. Eine bessere Lösung ist, die Möglichkeit, die Trennung von spamd von spamc auszunutzen. Allerdings kommt die Scanlast dann auf dem Host zu liegen, der den spamd vorhält.

Dazu sind folgende Anpassungen notwendig:

  • In /etc/default/spamassassin: OPTIONS=--listen-ip=0.0.0.0 --allowed-ips=127.0.0.1,… --allow-tell muss ergänzt werden. Ggfs. bei den allowed-ips weitere Adressen mit Zugriffsberechtigung hinterlegen.
  • Beim Aufruf von spamc ist die Option -d zusätzlich zu benutzen.
Datenbankpflege-Cronjobs

Falls die Scorewerte für Spam und Rejecting unterschiedlich konfiguriert wurden, rutschen einige Spammails durch, die zwar erkannt und getaggt wurden, aber wegen nicht ausreichendem Score halt trotzdem in der Inbox auftauchen. Diese kann man per Regel in einen eigenen Ordner schieben, zwecks manueller Sichtung.

Diesen eigen- und ggfs. auch fremdbestückten Spamordner kann man auch automatisiert anlernen lassen. Und weitere Dinge tun. Es empfiehlt sich, einen Ordner ~/.spamassassin/jobs/ anzulegen, in welchen die folgenden Shellscripte (die ggfs. noch anzupassen sind!) abgelegt werden:

  • 01-sa-verify:
#!/bin/bash

if [ -f ${HOME}/.spamassassin/bayes_seen ]; then
 	db4.6_verify ${HOME}/.spamassassin/bayes_seen
fi

if [ -f {HOME}/.spamassassin/bayes_toks ]; then
	db4.6_verify {HOME}/.spamassassin/bayes_toks
fi

if [ -f ${HOME}/.spamassassin/auto-whitelist ]; then
 	db4.6_verify ${HOME}/.spamassassin/auto-whitelist
fi
  • 02-sa-backup:
#!/bin/bash

# Nur für user lesbar machen
umask 077

test -f /etc/spamassassin/local.cf || {
	echo "Spamassassin configuration not found. Exit."
	exit 1
}

test -d ${HOME}/.spamassassin/backups || {
	echo "Spamassassin Backup Dir not found, creating..."
	mkdir ${HOME}/.spamassassin/backups
}

# Backups machen
if ! grep -q '^bayes_sql_dsn[[:space:]]\+DBI:mysql:' /etc/spamassassin/local.cf; then
	sa-learn --backup |gzip -c9 > \
		"${HOME}/.spamassassin/backups/bayes-`date +%Y-%m-%d`.gz"
fi

# Alte Backups löschen
find ${HOME}/.spamassassin/backups -maxdepth 1 -type f -a \
	-name "*.gz" -a -mtime +1 -exec rm {} \;
  • 03-sa-expire:
#!/bin/bash

if [ `date +%w` -eq 1 ]; then
	CNF="/etc/spamassassin/local.cf"
	if [ -f "${CNF}" ]; then
		if grep -q '^auto_whitelist_factory[[:space:]]\+Mail::SpamAssassin::SQLBasedAddrList$' ${CNF}; then
			MYSQL_HOST=`grep '^user_awl_dsn' ${CNF} |head -1 |sed 's/^user_awl_dsn[[:space:]]\+DBI:[[:alpha:]]\+:[[:alpha:]]\+:\([0-9A-Za-z\.]\+\)$/\1/'`
			MYSQL_USER=`grep '^user_awl_sql_username' ${CNF} |head -1 |awk '{print $2}'`
			MYSQL_PASS=`grep '^user_awl_sql_password' ${CNF} |head -1 |awk '{print $2}'`
			MYSQL_DB=`grep '^user_awl_dsn' ${CNF} |head -1 |sed 's/^user_awl_dsn[[:space:]]\+DBI:[[:alpha:]]\+:\([[:alpha:]]\+\):[0-9A-Za-z\.]\+$/\1/'`
			MYSQL_AWL=`grep '^user_awl_sql_table' ${CNF} |head -1 |awk '{print $2}'`

			if [ -z "${MYSQL_AWL}" ]; then
				MYSQL_AWL=awl
			fi

			MYSQLCMD="`which mysql` -B -N"
			if [ "${MYSQL_HOST}" != "localhost" ]; then
				MYSQLCMD="${MYSQLCMD} -h${MYSQL_HOST}"
			fi

			if [ ! -z "${MYSQL_USER}" ]; then
				MYSQLCMD="${MYSQLCMD} -u${MYSQL_USER}"
			fi

			if [ ! -z "${MYSQL_PASS}" ]; then
				MYSQLCMD="${MYSQLCMD} -p${MYSQL_PASS}"
			fi

			if [ ! -z "${MYSQL_DB}" ]; then
				MYSQLCMD="${MYSQLCMD} -D${MYSQL_DB}"
			fi

			MYSQLCMD="${MYSQLCMD} -e "

			# Gather stats
			ALLWL=$(${MYSQLCMD} "SELECT COUNT(*) FROM ${MYSQL_AWL}")
			WLEXP=$(${MYSQLCMD} "SELECT COUNT(*) FROM ${MYSQL_AWL} WHERE (count=1 AND last_update<DATE_SUB(NOW(), INTERVAL 1 WEEK)) OR (last_update<DATE_SUB(NOW(), INTERVAL 1 MONTH))")
			echo "AWL-Cleanup: ${ALLWL} entries, ${WLEXP} to expire"

			# Do the actual expiry
			${MYSQLCMD} "DELETE FROM ${MYSQL_AWL} WHERE (count=1 AND last_update<DATE_SUB(NOW(), INTERVAL 1 WEEK)) OR (last_update<DATE_SUB(NOW(), INTERVAL 1 MONTH))"
		fi
	fi
	sa-learn --force-expire
fi
  • 04-sa-learngood:
#!/bin/bash

umask 077
 
sa-learn --mbox --ham /var/mail/poc /home/poc/mail/Groff
  • 05-sa-learnspam:
#!/bin/bash

umask 007

if [ -s ${HOME}/mail/Spam ]; then
	mv ${HOME}/mail/Spam ${HOME}/mail/Spam~
	touch ${HOME}/mail/Spam
	sa-learn --mbox --spam ${HOME}/mail/Spam~ && \
	rm -f ${HOME}/mail/Spam~
fi
  • 06-sa-dump:
#!/bin/bash

sa-learn --dump magic

Aufgerufen wird die Scripterei dann mittels

run-parts -v .spamassassin/jobs

in der Crontab.

Einbindung als Milter

In der oben gezeigten Konfiguration kommen die als Spam erkannten Mails noch immer in den Postfächern der Benutzer an. Diese können sie zwar filtern und verschieben, aber der psychologische Effekt ist längst nicht so gross, wie wenn diese unerwünschten Mails erst gar nicht mehr bis zu den Benutzern durchdringen würden.

Nun ist es rechtlich relativ pikant, Mails einfach nicht zuzustellen, sondern zu verwerfen. Viel interessanter ist die Möglichkeit, Mails, die als Spam erkannt wurden, schon gar nicht mehr anzunehmen, sondern mit einer entsprechenden Fehlermeldung zurückzuweisen. Damit wurden die Mails niemals in die eigene Infrastuktur zugestellt und die damit einhergehenden Verpflichtungen fallen weg.[7] Legitime Absender erhalten eine Bouncemessage und werden dadurch informiert, dass eine Mail nicht zugestellt werden konnte.

Als Schnittstelle dient spamass-milter, das mit apt-get installiert werden kann. Die Konfiguration findet in /etc/default/spamass-milter statt.

OPTIONS="-u spamassassin -i 127.0.0.1,192.168.59.0/24 -I -r -1 -m -- -u spamassassin"
  • Die Optionen können in der zugehörigen Manpage nachgelesen werden,
  • -i sind IPAs bzw. Netzwerkranges, die nicht gescannt werden sollen, wie z. B. Mails aus dem eigenen LAN,
  • bei Zustellung über fetchmail ist 127.0.0.1 unbedingt aus der Ignoreliste zu entfernen, sonst werden diese nicht gescannt.
  • -r -1 sorgt dafür, dass als Spam erkannte Mails zurückgewiesen werden.
  • Bei einer geteilten Datenbank kann mit -d ein Host angegeben werden, der einen spamd beherbergt.
Sendmail-PoC

Die Ausführungen gelten für das vom Autor zu Verfügung gestellte Debian-Paket Sendmail.

Die Einbindung geschieht über /etc/mail/sendmail.mc:

INPUT_MAIL_FILTER(`spamassassin', `S=local:/var/run/spamass/spamass.sock, F=T,T=S:4m;R:4m;E:10m')dnl
define(`confMILTER_MACROS_ENVRCPT',`r, v, Z, b')dnl

Danach ist in /etc/mail ein make abzuetzen und Sendmail neu zu starten.

Weitere Rejects

Dies gehört nicht direkt zum Thema Spamassassin, aber zum Thema Lastvermeidung. Mails, die nicht durch den Spamassassin durchmüssen, erzeugen keine Last auf dem Server. Das kann durch ein hartes Rejecting anhand bestimmter Parameter geschehen:

  • Abfrage DNS-basierter Blacklisten,
  • Konsistenzprüfung der Absender-IPA-Hostnamens-Konfiguration.

Nachteilig ist, dass diese Mails aber dann auch nicht für ein Anlernen in die Datenbank zu Verfügung stehen.

Folgende Konfigurationsparameter in sind /etc/mail/sendmail.mc hierfür interessant:

FEATURE(`delay_checks')dnl
HACK(`require_rdns')dnl
FEATURE(`dnsbl',`ix.dnsbl.manitu.net',`"554 Rejected " $&{client_addr} " found in ix.dnsbl.manitu.net"')dnl
FEATURE(`dnsbl',`zen.spamhaus.org',`"554 Rejected " $&{client_addr} " found in zen.spamhaus.org"')dnl

Die ersten beiden Zeilen schalten die Konsistenzprüfung für die DNS Auflösungen ein, die beiden weiteren Zeilen befragen DNSBLs ob die Absender-IPA in der abzufragenden Blackliste steht. Eine eventuelle iXhash-Installation im Spamassassin ist dadurch überflüssig und kann entfernt werden.

Danach ist in /etc/mail ein make abzusetzen und Sendmail neu zu starten.

Beide Parameter sorgen für ein gewisses Mass an Falscherkennungen:

  • Manche Systemadministratoren senden ihre Mails direkt über Einwahl-IPAs zu den MXern. Da dies genau der Vorgehensweise von Spambots entspricht, sollten dynamische Adressen (oft anhand unsauberer DNS-Konfiguration als solche erkennbar) Mails über einen (meist providerseitig vorhandenen) Mailserver versenden.
    • Einige Administratoren wissen nicht um diese Thematik und haben einen legitimen Mailserver als MX (eingehend), ausgehend aber keine saubere DNS-Auflösung, konfiguriert. Diese Absenderserver treffen die DNS-Checks ebenso.
  • DNS-Blacklists und dynamische IPAs bergen einen gewissen Zündstoff. Ein Spambotrechner kann bis z. B. zur Zwangstrennung soviel Spam versendet haben, dass die momentante Adresse in einer DNSBL landet. Nach der Zwangstrennung steckt ein sauberer Rechner hinter der Adresse, der nun aber aus den genannten Gründen ebenfalls keine Mails direkt zustellen darf. Auch hier bietet der Versand über einen (meist providerseitig vorhandenen) Mailserver Abhilfe.

Beschwerden treffen meist den Administrator des Empfängerservers, dass ein Absender sich telefonisch beklagen würde, er könne keine Mails an einen Empfänger auf dem Empfängerserver senden. Hier zu vermitteln, dass der Absender sich auf seiner Seite ein Ei gelegt hat, erfordert oft nicht unerhebliches Fingerspitzengefühl. Das Argument, dass viele der größeren Mailserverbetreiber inzwischen ebenso pauschal keine Mails mehr von dynamischen IPAs annehmen zieht dagegen meist. Die Probleme sind hausgemacht und nicht auf den Empfängerserver beschränkt.

Letztlich muss jeder selbst entscheiden, ob der Gewinn (weniger Spammails kommen durch, Verringerung der Serverlast) den Verlust (wahrnehmbare Zahl an Falscherkennungen) rechtfertigt.

Mit allen beschriebenen Konfigurationen erhält der Autor nahezu 100% Spamfreiheit, bei einer Falscherkennungsrate von 1-2 Mails pro Jahr[8], bei einem Gesamtmailaufkommen von ca. 450 Mails pro Tag.

Eigene Regeln

Eigene Regeln für den Spamassassin können Falscherkennungen unterdrücken als auch hartnäckig nicht erkannte Spammails mit genügend Score versehen, dass sie nicht mehr durchrutschen. Letzteres ist allerdings nur in Ausnahmefällen notwendig. Beispiel:

header   SCANNER_WHITELIST      X-Mailer =~ /^LEXMARK Email Diag System Alert Info$/
score    SCANNER_WHITELIST      -6
describe SCANNER_WHITELIST      Mails from internal Scanning device

Debugging

Um festzustellen, warum eine Mail als Spam erkannt wurde, können:

  • die Header,
  • das Mailserverlogfile

analysiert werden. Dort fügt der Spamassassin eigene Einträge hinzu, die bei der Diagnose helfen. Weitere Informationen können danach aus den Regeldateien in /usr/share/spamassassin/ gegrept werden.

Die Mails von obigem Lexmark-Scanner entsprechen z. B. in einigen Punkten nicht den geltenden RFCs. Spamassassin vergibt daher hierzu fleissig Punkte und die Mails würden nicht mehr ankommen.

  • BASE64_LENGTH_79_INF: Base64-enkodierte Dateien sollen eine Länge von 77 Zeichen haben. Der Scanner erzeugt 996-Zeichen pro Zeile.
  • BAYES_50: Die Bayes-Datenbank meldet eine 50%ige Spamwahrscheinlichkeit zurück.[9]
  • INVALID_DATE: Datum im Header nicht im von RFC 2822 erwünschten Format.
Date: 16 Oct 2009 08:20:04 (falsch)
Date: Sat, 2 Jan 2010 09:45:05 +0100 (richtig)
  • TVD_RCVD_IP und TVD_RCVD_IP4: Der Autor der Firmware hat hier die Höflichkeit von SMTP falschherum verstanden und meint, er müsse dem Gegenüber nochmal versichern, wer er ist.[10] 2 ist der Mailserver, 200 ist der Scanner.
Received: from 192.168.30.2 (lexmark [192.168.30.200])
       by mailserver (8.13.8/8.13.8) with SMTP id n9G7IKan006751
       for <blah@blubb.de>; Fri, 16 Oct 2009 09:18:20 +0200
  • TVD_SPACE_RATIO: Hier ist die Anzahl der Leerstellen atypisch.

Oft hilft dies nicht bei der konkreten Behebung des Fehlers, sondern bei der Unterstützung des Absenders, seine Mails konformer zu gestalten und so auch bei anderen Spamassassin-Installationen die Chance auf Falscherkennungen zu reduzieren.

Fussnoten

  1. Ausser Outlook. Microsoft findet wohl, dass man die Benutzer nicht mit Regeln basierend auf Internetkopfzeilen belasten sollte. Diese Benutzer sollten rewrite_header subject "[SPAM]" zur Konfiguration hinzufügen, damit sie zumindest anhand des veränderten Betreffs sortieren können.
  2. Unterverzeichnis .spamassassin/.
  3. Dazu muss berücksichtigt werden, dass die Datenbankdateien ca. den zehnfachen Platz einnehmen, den der Plaintextexport benötigt, egal ob DBM oder MySQL.
  4. Frühere SA-Versionen erzeugten regelmäßig beschädigte DBM-Dateien.
  5. Neudeutsch: Synergieeffekte.
  6. Vom Autor, auf dem Mailcluster beim Arbeitgeber.
  7. Das ist kein anwaltlich überprüfter Rat und somit bitte nicht als absolute Wahrheit zu sehen.
  8. Rückmeldung von Bekannten per Telefon.
  9. Das ist nicht unbedingt dem Gerät anzulasten.
  10. So typisch menschlich: HELO, Herr Gegenüber.