E-Mail-Verwaltung – Spam

Gestern habe ich zwar endlich die neuen Spambekämpfungsmaßnahmen scharf geschaltet, aber im Spamfilter und in den Spamordnern unserer Mitarbeiter hat sich in den letzten Monaten schon einiges angesammelt. Auch kann es sicherlich nicht schaden, SpamAssassin mit den neuen Treffern zu trainieren, auf dass die derzeitige Falsch-Positiv-Rate von 0,5 ‰ noch weiter sinkt und hoffentlich noch mehr Spamnachrichten, die es durch die Vorfilterstufen schaffen, von ihm richtig markiert werden.

Der folgende Artikel illustriert zuerst anhand der Kopfdaten den Weg einer E-Mail durch unsere Univention-Architektur bis zum Empfänger und die damit einhergehenden Konsequenzen. Dabei erläutere ich auch anhand eines tatsächlichen Ereignisses, wie und warum man alle ein- und ausgehenden E-Mails zusätzlich in einem Archiv speichern sollte und wie man sie nach einer angemessenen Frist flott und simpel löschen kann.

Zuletzt wird das manuelle Training des Spamfilters gezeigt, wie man die trainierten E-Mails ohne Umweg und womöglich überforderte E-Mail-Clients entsorgt Zuerst muss man wissen, wie unsere Architektur aufgebaut ist und das sieht man am besten anhand der Kopfdaten einer E-Mail:

Return-Path:
Received: from localhost (localhost [127.0.0.1])
     by srv1 (Cyrus v2.2.13-Debian-2.2.13-14.71.201008092117) with LMTPA;
     Mon, 25 Oct 2010 06:13:28 +0200
X-Sieve: CMU Sieve 2.2
Received: from localhost (localhost [127.0.0.1])
    by srv1.tao.invalid (Postfix) with ESMTP id 9B9DA97401;
    Mon, 25 Oct 2010 06:13:28 +0200 (CEST)
Received: from localhost (localhost [127.0.0.1])
    by srv1.tao.invalid (Postfix) with ESMTP id 8C93497403;
    Mon, 25 Oct 2010 06:13:28 +0200 (CEST)
X-Virus-Scanned: by amavisd-new-2.6.1 (20080629) (Debian) at tao.invalid
X-Spam-Flag: NO
X-Spam-Score: 1.131
X-Spam-Level: *
X-Spam-Status: No, score=1.131 tagged_above=-1000 required=5
    tests=[BAYES_50=0.001, DNS_FROM_OPENWHOIS=1.13]
Received: from srv1.tao.invalid ([127.0.0.1])
    by localhost (srv1.tao.invalid [127.0.0.1]) (amavisd-new, port 10024)
    with ESMTP id hQWs7Zvfe2Dk; Mon, 25 Oct 2010 06:13:28 +0200 (CEST)
Received: from srv2.tao.invalid (srv2.tao.invalid [10.2.1.1])
    by srv1.tao.invalid (Postfix) with ESMTP id 2AB3397401
    for ; Mon, 25 Oct 2010 06:13:28 +0200 (CEST)
Received: from localhost (localhost [127.0.0.1])
    by srv2.tao.invalid (Postfix) with ESMTP id 28A1D832645;
    Mon, 25 Oct 2010 06:13:28 +0200 (CEST)
Received: from localhost (localhost [127.0.0.1])
    by srv2.tao.invalid (Postfix) with ESMTP id 09CFD832655;
    Mon, 25 Oct 2010 06:13:28 +0200 (CEST)
X-Virus-Scanned: by amavisd-new-2.6.1 (20080629) (Debian) at tao.at
X-Spam-Flag: NO
X-Spam-Score: 1.066
X-Spam-Level: *
X-Spam-Status: No, score=1.066 tagged_above=-1000 required=5 tests=[AWL=0.066,
    BAYES_60=1]
Received: from srv2.tao.invalid ([127.0.0.1])
    by localhost (srv2.tao.invalid [127.0.0.1]) (amavisd-new, port 10024)
    with ESMTP id Tavo8NSvesTn; Mon, 25 Oct 2010 06:12:58 +0200 (CEST)
X-policyd-weight: using cached result; rate: -8.5
Received: from mx.example.com (mx.example.com [555.81.27.7])
    by srv2.tao.invalid (Postfix) with ESMTP id A835D832645
    for ; Mon, 25 Oct 2010 06:11:23 +0200 (CEST)
TO:
Subject: Watching our mail srvs at work :)
Message-Id: <20101025041133.A835D832645@srv2.tao.invalid>
Date: Mon, 25 Oct 2010 06:11:23 +0200 (CEST)
From: leonhard.preis@example.com
X-Kolab-Scheduling-Message: FALSE

Showing how our e-mail system works.
  1. Einer unserer öffentlichen Mailserver, in diesem Fall srv2.tao.invalid, empfängt das E-Mail. Dabei durchläuft es die Vorfilterstufen (X-policyd-weight zeugt davon), einen Virenscan (X-Virus-Scanned), und schließlich die erste Prüfung durch SpamAssassin (X-Spam-*) . In den Klammern angegeben waren die durch diese Filter hinzugefügten Header.
  2. Der empfangende Server schickt eine Kopie an das lokale Postfach des Benutzers archiv@tao.invalid und stellt das E-Mail dem Heimat-Server des empfangenden Benutzers – sofern nicht er selbst diese Rolle innehat.
  3. Am Heimat-Server wird das E-Mail gegebenenfalls einer erneuten Prüfung auf Viren unterzogen, nochmals durch SpamAssassin gejagt und im Archiv abgelegt, bevor Postfix die E-Mail endlich an Cyrus überstellt.
  4. Cyrus ruft nun das Sieve-Script des Benutzers auf, welches die X-Spam-Flag-Header prüft. Ist einer davon “positiv”, schickt das Skript die E-Mail weiter an spam@tao.invalid, dessen Sieve-Skript es wiederum in seinen Ordner Spam schiebt. Andernfalls landet das E-Mail in meinem Posteingang.

Manch einer wird sich bezüglich der Archivierung aller ein- und, um genau zu sein, auch ausgehenden E-Mails wundern, wozu das gut sein soll. Dazu gibt es eine Geschichte von vor mehreren Jahren, in der die Verkettung von bescheuerter Softwarearchitektur, Verbindungsproblemen, ein paar weiteren idiotischen Zufällen und einer darauf beruhenden Fehleinschätzung der Situation trotz aktueller und täglicher Sicherung zum Totalverlust mehrerer Monate E-Mail-Verkehr einer Mitarbeiterin geführt haben. Die häufigen Probleme mit dem Toltec Connector, den wir damals eingesetzt haben, um Microsoft Outlook dazu zu überreden, mit unseren Servern zu sprechen, haben irgendwann die Einrichtung eines neuen Outlook-Profils notwendig gemacht. Das ist an sich keine große Sache: Neues Profil erstellen, Outlook starten, schauen ob alles geht, altes Profil aus Platzgründen löschen – ist ja kein Problem, im Zweifelsfall ist ja eh alles am Server vorhanden. Haha. Denkste.

Böse Überraschung

Der Hersteller des Toltec Connectors wollte sich nämlich offensichtlich die Lizenzgebühren für Microsofts MAPI-Schnittstelle sparen und hat ein paar widerliche Tricks verwendet, um dennoch eine ähnliche Funktionalität zu gewährleisten. Dazu gehört unter anderem, dass alle Nachrichten aus dem “Wurzelverzeichnis” der Benutzermailbox, “INBOX/” erstmal per POP3 heruntergeladen und in einen Ordner “Posteingang“, am Server als INBOX/Posteingang/ präsent, zu verschieben, von wo sie via IMAP wieder auf den Server hochgeladen werden. Weiß der Henker wieso, aber bei besagter Mitarbeiterin funktionierte zwar das Herunterladen per POP3 einwandfrei, nicht jedoch das Hinaufladen per IMAP. Weil das POPen aber alle fünf Minuten geschah, solange Outlook lief, fanden sich zum Zeitpunkt der Sicherung mitten in der Nacht praktisch keine relevanten E-Mails mehr am Server. Und Outlook-Profile / -Datendateien wiederherzustellen … Mir wurde noch nie effektiver die Problematik gewisser binärer, proprietärer Datenformate bewusst. Seitdem werden bei uns alle ein- und ausgehenden E-Mails automatisch ins Server-Archiv kopiert. Dummerweise umfasst dieses Archiv aber auch alle E-Mails, die in den globalen Spamordner gehen und außerdem natürlich jede noch so kleine E-Mail und jeden Anhang, die die Nutzer in ihren eigenen Postfächern womöglich längst (gewollt) gelöscht haben. Daraus resultiert ein steiles Wachstum des Umfangs des Archives und der Belegung der Inodes, die bei mehreren hunderttausend kleinen E-Mail-Dateien durchaus eine Rolle spielt. Darum ist es notwendig, dass wir das das Archiv regelmäßig zurechtstutzen, zumeist auf die E-Mails der letzten drei Monate. Das wird zukünftig wohl ein Cronjob übernehmen, aber bislang wird das noch manuell durchgeführt.

Die letzten 90 Tage

$> sudo find /var/spool/cyrus/mail/domain/t/tao.invalid/a/user/archiv/ 
   -mtime +90 -exec rm {} ;
$> sudo -u cyrus cyrreconstruct -C /etc/imapd/imapd.conf 
   user/archiv@tao.invalid

Der erste Befehl kümmert sich um die Löschung, der zweite um die Wiederherstellung der Mailbox – damit Cyrus auch weiß, dass einige E-Mails physisch nicht mehr vorhanden sind. Die automatische Archivierung aller E-Mails ist übrigens ganz einfach zu erreichen. Man muss nur ein Postfach für das Archiv erstellen, z.B. “archiv@tao.invalid” und den Wert der “Univention Configuration Registry“-Variable mail/archivefolder z.B. auf diese Adresse einstellen. Nach einem abschließenden Postfix-Neustart werden alle E-Mails dorthin kopiert.

Flaggen & Barhocker

Bleibt noch das Kontrollieren der Spamordner. Dafür verwende ich bevorzugt einen IMAP-Client, dessen Eigenschaften die Kontrolle zehntausender Spam-E-Mails nach Möglichkeit beschleunigen. Genau diese Anforderungen erfüllt für mich Opera M2, der im Webbrowser Opera integrierte E-Mail-Client, dank seiner sehr schnellen Suche und des ungewöhnlichen Filterkonzepts, dem noch Thunderbirds “virtuelle Ordner” am nächsten kommen. Opera verwendet, von den im IMAP existierenden selbst abgesehen, nämlich keine Ordner im herkömmlichen Sinn, sondern wirft alles in einen Ordner, der nach bestimmten Kriterien gefiltert werden kann. Wichtig für uns ist der “Ungelesen”-Filter, der standardmäßig eingerichtet ist und schnell erklärt ist: Er zeigt alle ungelesenen E-Mails – und nur die. Wir verwenden zur Kontrolle der Spamfilter ein eigenes Benutzerkonto, weshalb es keine eigentlichen ungelesenen E-Mails gibt. Außerdem schafft M2 problemlos den Umgang mit der Menge an E-Mails, auch bei Such- und Sortierungsvorgängen und hat auch einen eigenen bayesschen Spamfilter, der, wenn man ihn bei jeder Kontrolle trainiert, durchaus hilfreich sein kann. Einzig die Verbindung zum Server kann sich als Bremse erweisen. Zu aller erst konfigurieren wir M2 so, dass er optimal unsere Anforderungen für diesen Job erfüllt. Dazu klicken wir im “Ungelesen”-Filter auf die Schaltfläche “Ansicht” und wählen aus dem Untermenü “Darstellung” “Nur die Liste” aus. M2 wird nun den Inhalt von Nachrichten nur abrufen, wenn wir die E-Mail explizit öffnen; außerdem können natürlich deutlich mehr E-Mails angezeigt werden.

Geschwindes Durchmustern großer Mengen Spam

Anfänglich widmen wir uns den offensichtlichen Kandidaten: Was im Spamfilter gelandet ist und eines der Stichwörter Viagra, Codein, Ciali(s|z), Pfizer, Hydrocodone, Fahne, Flagge, Barhocker, Diploma, Degree, University, Watch, Rolex, Omega, Casino oder Gaming aufweist, wird en gros und unbesehener als gelesen makiert. Dazu geben wir einfach im Suchfeld das Stichwort ein und dann Tabulator, Strg+A, g, fertig. Als nächstes widmen wir uns allen E-Mails, die einen ähnlichen Betreff haben oder ungewöhnliche Buchstaben (Kyrillisch, Kanji); dazu sortieren wir nach Betreff. Beim Durchblättern sieht man dadurch dutzende kleinere und größere Blöcke von E-Mails ähnlichen oder gar gleichen Begriffs. Dabei handelt es sich schon per Definition mit hoher Wahrscheinlichkeit um Spam, ein Blick auf den Betreff verschafft blitzschnell Klarheit. Block markieren und als gelesen markieren – wieder ein paar Spam-E-Mails “kontrolliert”. Diese Methode wendet man anschließend auch auf die Absender an, auch wenn hierbei die Wahrscheinlichkeit, dass es sich um legitime E-Mails handelt, höher ist. Legitime E-Mails werden von uns in den “Ham“-Ordner verschoben, von wo wir sie später, nach dem Spamfiltertraining, an die eigentlichen Empfänger weiterleiten bzw. in deren Ordner verschieben. Dabei ist zu beachten, das Opera Dinge aus dem “Ungelesen”-Filter nicht verschiebt, sondern kopiert. Das führt dazu, dass die E-Mails im “Ungelesen”-Filter doppelt aufscheinen. Rechtsklick auf “Ham” –> Alle als gelesen markieren und danach die beiden verbliebenen Elemente im Strom löschen um sie aus dem Spamordner zu entfernen. Bevor man den Spamfilter trainiert, sollte man unbedingt noch den virtuellen Papierkübel von Opera ausleeren, um sicherzugehen, dass die E-Mails auch wirklich am Server aus dem Spamordner gelöscht wurden. Damit hat man die Menge der zu kontrollierenden E-Mails hoffentlich erfolgreich auf nicht mehr als ein paar tausend verbleibende reduziert, die man “einzeln” kontrollieren kann. Dabei sieht man sieht man den meisten Kandidaten auf den ersten Blick ihren Inhalt an und kann sie dementsprechend behandeln: Spam als gelesen markieren, Ham kopieren und aus dem Spam-Ordner löschen. Mit etwas Erfahrung ist man dazu in der Lage, sehr schnell zu erfassen, ob auf der aktuellen Seite strittige / falsch-positive Kandidaten vorliegen oder ausnahmslos Spam vorliegt, ohne wirklich jeden Absender und Betreff zu lesen. Dieses Durchmustern wird meines Erachtens zusätzlich begünstigt, wenn man den ganzen Block makiert, wodurch er mit einem eintönigen Blau hinterlegt wird. Eine legitime E-Mail unterbricht das “Muster” des Spams und man kann von unterbewusster Wahrnehmung auf gezielte Suche umschalten. Ich kann nicht beweisen, dass diese Methode sehr treffsicher ist, aber ich habe einerseits 14 E-Mails aus etwas mehr als 28 000 Spam-E-Mails im einen und andererseits 153 aus knapp 14 700 Spam-E-Mails im anderen Filter gefunden. Die Unterschiede sind dabei eindeutig auf die unterschiedliche Ausrichtung der jeweiligen Standorte zurückzuführen, so befanden sich im letzteren Filter deutlich mehr Technik- und Web 2.0-Newsletter. Wer seinem Unterbewusstsein nicht traut, kann natürlich auch jede E-Mail einzeln kontrollieren.

Die Krux mit gefälschten und nicht gefälschten Absendern

Damit kommen wir zur Kontrolle von nicht eindeutigen Kandidaten. Als solcher Kandidat hat sich bei mir beispielsweise Twitter herausgestellt. Am schnellsten klärt man den Status, indem man die E-Mail öffnet und über die Links fährt, die auf Twitter zeigen sollten. Tun sie das, ist die E-Mail mit hoher Wahrscheinlichkeit legitim. Im aktuellen Fall war es so, dass nur die Newsletter und ein “xyz folgt dir”-E-Mail wirklich von Twitter kamen.

Fütterungszeit!

Nun, nachdem mutmaßlich alle legitimen E-Mails erfolgreich aussortiert wurden, können wir endlich den Spamfilter trainieren:

$> sudo -s
$> cd /var/spool/cyrus/mail/domain/t/tao.invalid/s/user/spam/
$> sa-learn --spam --dbpath /var/lib/amavis/.spamassassin --progress Spam/*.

Anschließend kann man die E-Mails löschen. Entweder über den verwendeten Client, was bei den üblichen Spamzahlen recht lange dauert, oder direkt über das Dateisystem. Dabei müssen aber die Cyrus-Verwaltungsdateien repariert werden.

$> rm Spam/*.
$> sudo -u cyrus cyrreconstruct -C /etc/imapd/imapd.conf user/spam/Spam@tao.at

Mir ist es auch schon passiert, dass ich die Fehlermeldung

Argument list too long

bekam. In diesem Fall sei auf find und xargs verwiesen. Wer allerdings etwas Geduld hat, kann das Löschen aber auch z.B. Opera durchführen lassen, dann erspart man sich auch das Reparieren der Verwaltungsdateien. Explizit nicht eignet sich jedoch Microsoft Outlook 2003. Das stürzt gerüchtweise schon bei ungefähr hundert gleichzeitig zu löschenden Nachrichten ab. Anschließend trainieren wir den Filter noch im Bezug auf “Ham”, die “guten” E-Mails. Dazu wechseln wir erst einmal in das Verzeichnis des verwendeten Nutzers:

$> cd ../../../s/user/spamcontrol/
$> sa-learn --ham --dbpath /var/lib/amavis/.spamassassin --progress Ham/*.

Dieses Training kann man in der Mailbox (Mailbox, nicht nur dem Inhalt des Ordners Ham) jedes Benutzers wiederholen um die Treffsicherheit des Filters zu erhöhen. Univention trainiert den Spamfilter bei gesetzter UCR-Variable mail/antispam/learndaily täglich mit den Inhalten der Ordner Ham & Spam. Man kann dies mit univention-sa-learn ohne Angabe von Argumenten auch selbst veranlassen.