Für das server-seitige Filtern beziehungsweise Vorsortieren von E‑Mails (zum Beispiel in verschiedene Ordner) mit Hilfe von Procmail oder Exim gibt es viele Anleitungen im Netz. Wenn aber keine Systemkonten verwendet werden, sondern die E‑Mail-Adressen in einer (MySQL-) Datenbank verwaltet werden, gibt es zu den einzelnen E‑Mail-Adressen kein passendes Home-Verzeichnis. Ich beschreibe in diesem Beitrag, wie man für diesen Fall beliebige Filter einrichten kann.
Sofern die E‑Mails mit Hilfe eines Systemkontos zugestellt werden, genügt eine .forward-Datei im Home-Verzeichnis (die Syntax dieser Datei ist unter anderem in der Exim-Hilfe erklärt). Mit folgendem Inhalt einer .forward-Datei kann man zum Beispiel alle E‑Mails, die in der Absenderadresse die Zeichenkette beispiel enthalten, automatisch in den E‑Mail-Ordner Beispiel einsortieren lassen.
# Exim filter if $header_from: contains "beispiel" then save "/.../.Beispiel/" endif
Nach der save-Anweisung muss der vollständige Pfad des Zielverzeichnises angegeben werden. Das Verzeichnis muss also bereits (durch ein E‑Mail-Programm) erstellt worden sein. Wo genau im Dateisystem sich dieses Verzeichnis befindet, kann man der Exim-Konfigurationsdatei entnehmen. In der Datei können beliebig komplexe Filter- beziehungsweise Sortiervorgänge definiert werden.
Wenn man die E‑Mail-Adressen (virtuell) über eine (MySQL-) Datenbank verwaltet, kann man den Inhalt einer .forward-Datei ebenfalls in der Datenbank speichern und von Exim auswerten lassen. Dazu muss man in der Konfigurationsdatei in dem Abschnitt, der mit begin routers beginnt, eine neue Regel wie folgt anlegen. (Falls die Exim-Konfiguration in mehrere Dateien aufgesplittet ist, befinden sich die Routing-Regeln womöglich in einem Verzeichnis wie /etc/exim4/conf.d/router. Dort muss dann der folgende Inhalt in eine neue Datei eingefügt werden, die vom Dateinamensschema zu den übrigenen Dateien passt.)
mysql_virtual_forward: driver = redirect allow_filter check_local_user = false data = ${lookup mysql {SELECT forward FROM Mailfilter WHERE email = '$local_part@$domain'}{$value}} no_verify no_expn check_ancestor file_transport = address_file pipe_transport = address_pipe reply_transport = address_reply directory_transport = address_directory user = Debian-exim group = Debian-exim
Als Werte unter user und group muss der Benutzername beziehungsweise der Gruppenname eingegeben werden, unter dem Exim auf dem Server läuft. Die Zeile data enthält eine SQL-Abfrage, die als Rückgabewert den Inhalt von genau einer .forward-Datei zurückliefern muss.
In meinem Fall hat die Tabelle Mailfilter eine sehr einfache Struktur:
CREATE TABLE IF NOT EXISTS `Mailfilter` ( `fid` int(11) NOT NULL auto_increment, `email` varchar(255) NOT NULL, `forward` text NOT NULL, PRIMARY KEY (`fid`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
Die Tabelle enthält neben einer ID ein Feld für die vollständige E‑Mail-Adresse, für die die in dem Feld forward angegebene „Filterdatei” angewandt werden soll. Der Wert des Feldes forward entspricht exakt dem Dateiinhalt wie zum Beispiel von obiger .forward-Datei.
Nun muss noch die geänderte Konfiguration von Exim eingelesen werden, und dann sollte es gehen. Falls nicht, hilft eventuell ein Blick in Exims mainlog (eventuell unter /var/log/exim4 zu finden).
Ein Dank geht an @MScDoc, der mich auf meine Twitter-Nachfrage hin auf den Beitrag Exim w/virtual users and procmail hinwies. Die in dieser Diskussion von Adam vorgeschlagene Lösung funktioniert zwar mit dem aktuellen Exim4 nicht mehr, aber nach kurzer Recherche habe ich herausgefunden, dass lediglich die früher gültige Anweisung filter durch allow_filter ersetzt werden muss, damit es auch unter Exim4 funktioniert.
[1. Aktualisierung, 8. Dezember] Ich habe mir zur Erzeugung einer korrekten .forward-„Datei” das folgende Perl-Skript geschrieben, dass von Nutzen ist für alle, die viele Mailinglisten filtern und den Überblick behalten wollen…
#!/usr/bin/perl -w $maildir = '/-pfad-zum-mail-verzeichnis-auf-dem-server/'; @r = ( ['-filterstring-im-to-oder-cc-feld-', '-verzeichnis/-unterverzeichnis-/'], # ['', ''], # ['', ''], # ['', ''], ); print "# Exim filter\n\n"; $i = 0; $condstr = ''; foreach(@r) { $i++; if ($i == 1) { $condstr = 'if'; } else { $condstr = 'elif'; } print $condstr . ' $header_to: contains "' . @$_[0] . '" or $header_cc contains "' . @$_[0] . '" then' . "\n"; print 'save "' . $maildir . @$_[1] . '"' . "\n\n"; } print "endif\n\n";
Schreibe einen Kommentar