Hallo! den Betreff habe ich mal in etwas Seriöseres geändert um damit einer mittlerweile sachlicheren Diskussion Rechnung zu tragen. Außerdem haben sich ja schon einige (künstlich) aufgeregt über den Kasperfilter-Thread! * Jörg Rossdeutscher <ratti@gesindel.de> [2003-11-17 21:49] schrieb:
* Am So, den 16.11.2003 schrieb Mathias Bauer um 21:54:
Und oft genug divergieren Diskussionen soweit, daß unter den Betreffs später vernünftige Sachen auftauchen. Zum Beispiel diskutieren wir gerade über gute Kasperfilter in einem verloren geglaubten Thread. :-)
Ich bin auch nur beim Überfliegen der ausgefilterten Emails auf diesen Thread gestoßen :->
[falsch aussortierte Emails]
False positives wären natürlich nicht akzeptabel. Ich sehe aber eigentlich ein größeres Problem: <jammermodus> Bei der wachsenden Anzahl an grottigen MUAs, Webmailern </jammermodus> würde ich eher die Gefahr sehen, daß die Referenzen Schwachsinn enthalten. Hier in der Liste läuft ja kaum ein Thread über mehr als 5 Replies, bis ein Outlook "oder whatever" daherkommt und ihn zerreisst. Mir wird etwas Angst und Bange bei dem Gedanken, _was_ da alles in den Refernezen steht, wenn sie überhaupt existieren. Zweistellige Zahlen oder so. Uh...
... oder das @localhost in des Message-ID. Alles seeehr hilfreich! Leider kann man manche Macken mit procmail nur notdürftig beheben (z.B. Attachments von Outlook).
[Hinweis auf Email "Vier Emailfilter mit procmail" vom 31.10.2003] Leider erhielt ich wegen der beiden Megathreads um Boykott-Briefe und den Verkauf von SuSE damals kein Feedback :-(
Ich schätze, die Liste kann ein Repost vertragen.
Repost!
Bitte sehr! Bitte gleich! ... Ich freue mich über jeden Kommentar dazu. Vielleicht nützt es ja dem einen oder anderen. Gleich vorweg: ich verwende fetchmail, procmail und mutt -- mit Sicherheit dürfte einiges auch für KMail und andere MUAs verwendbar sein, die ich aber nicht im Detail kenne. In meinem (SuSE 7.2-)System setze ich nacheinander die folgenden vier Filter ein: (1) Threadfilter (2) Domainfilter (3) Absenderfilter (4) Duplikatfilter Danach werden Mailinglisten aussortiert und mit dem Spambouncer www.spambouncer.org der Müll weggeräumt. (Großer `Sperrmüll' wird gar nicht erst abgeholt: vor dem fetchmail-Aufruf starte ich den mailfilter (mailfilter.sourceforge.net).) Beide Programme kann ich nur empfehlen. Soweit die grobe Beschreibung, nun zu den Details: 1. Threadfilter --------------- Das Ziel besteht im Ausfiltern von zukünftigen Beiträgen eines Diskussionsfadens (Threads), den man aufgrund der bereits eingetroffenen Beiträge als uninteressant bzw. unerwünscht eingestuft hat. Eine Filtrierung basierend auf den Betreffzeilen scheidet aus, weil sie nicht treffsicher genug ist. Selbst wenn man annimmt, dass unterschiedliche Threads mit identischen Betreffzeilen selten sind, kann es vorkommen dass einzelne Subthreads nicht korrekt ausgefiltert werden. Dies geschieht insbesondere dann, wenn die Betreffzeilen Umlaute oder andere Sonderzeichen enthalten -- die Filtrierung scheitert nämlich an dem für die Kodierung dieser Zeichen zuständigen `=?iso-8859-1?q?=...'! Die `Re:'-`Fwd:'-Problematik macht eine Betreffzeilen-Filtrierung nur noch zusätzlich fehleranfällig. Exakter lässt sich mit Hilfe der Message-IDs filtern. Verwendet werden dazu die Kopfzeilen `Message-ID:', `In-Reply-To:' und `References:'. Ich fasse hier mal kurz RFC 2822, Abschnitt 3.6.4 zusammen: Jede Email soll die Kopfzeile `Message-ID:' und -- falls es sich um eine Antwort handelt -- zusätzlich die Kopfzeilen `In-Reply-To:' und `References:' besitzen. Dabei gilt: - `Message-ID:' enthält genau eine ID. - In einer Antwort enthält `In-Reply-To:' die Message-ID jener Eltern-Email, auf die sich die Antwort bezieht. - `References:' enthält das gleichnamige Feld der Eltern-Email, ergänzt um deren Message-ID. Mit den IDs in 'References:' kann man also den Thread rekonstruieren. (Weitere Details im RFC.) Werden also von allen Beiträgen eines uninteressanten bzw. unerwünschten Threads die `Message-ID:'s gespeichert, dann können später ankommende Beiträge aufgrund deren Angaben in `References:' und `In-Reply-To:' zuverlässig ausgefiltert werden. In mutt erledigt das Speichern der Message-IDs folgendes Makro: ---------- in $HOME/.muttrc ---------- macro index <esc>Ft "<pipe-message>threadfilter.sh --add<enter>" \ "Filtere Diskussionsfaden (Thread) aus" -------------------------------------- (Das Skript threadfilter.sh berücksichtigt jede Einstellung von `pipe-split'. D.h. es ist irrelevant, ob die ausgewählten Emails als Ganzes oder jede einzeln durch die Pipe geschickt werden.) Für KMail gibt es sicher auch eine entsprechende Möglichkeit, Emails auszuwählen und durch eine Pipe zu schicken. KMail kenne ich nicht so genau. 2. Der Domainfilter ------------------- Alle Emails, die aus bestimmten Domains kommen, werden ausgefiltert. Der Filtrierung zugrunde liegen die Kopfzeilen `From:', `Sender:' und `X-Sender:'. Die unerwünschten Domains sind in einer normalen Textdatei aufgelistet und ein awk-Skript besorgt die Umwandlung dieser Liste in eine procmail-Regel. 3. Der Absenderfilter --------------------- Ganz analog werden alle Emails ausgefiltert, die von bestimmten Personen kommen. Der Filter verwendet die gleichen Kopfzeilen wie der Domainfilter. Die Absender(adressen!), die in einer Textdatei enthalten sind, werden ebenfalls durch ein awk-Skript umgewandelt. Natürlich gibt es analog zum Threadfilter auch hier mutt-Makros, die die Extraktion von Domains bzw. Absenderadressen aus Emails in die `schwarzen Listen' vornehmen und (nach manueller Nachbearbeitung) die procmail-Regeln automatisch erstellen. Das lass' ich jetzt aber mal als Übung ... :-) 4. Der Duplikatfilter --------------------- Dieser Filter erwischt mehrfache identische Emails, der Vergleich beruht wieder auf den Message-IDs. Den Kern kann man aus `man 5 procmailex' entnehmen; ich habe den Filter nur etwas umgebaut (s.u.). Die Skripte: ---------- in $HOME/.procmailrc ---------- INCLUDERC = ${HOME}/.procmail/filterrc ------------------------------------------ ---------- $HOME/.procmail/filterrc ---------- # $HOME/.procmail/filterrc # Filterquartett für Procmail # # Hinweis: filterrc verwendet folgende *externe* Variablen: # - MAILDIR : Mailverzeichnis # - PMDIR : Procmail-Verzeichnis # - FORMAIL : /usr/bin/formail # Threadfilter FILTERTHREADS = yes THREADFOLDER = ${MAILDIR}/muell MSGIDTHREADCACHE = ${PMDIR}/msgid.thread.cache THREADFILTERSCRIPT = ${PMDIR}/threadfilter.sh # Domainfilter FILTERDOMAINS = yes DOMAINFOLDER = ${MAILDIR}/muell # Absenderfilter FILTERSENDERS = yes SENDERFOLDER = ${MAILDIR}/muell # Duplikatfilter FILTERDUPS = yes DUPFOLDER = ${MAILDIR}/muell MSGIDDUPCACHE = ${PMDIR}/msgid.dup.cache MSGIDDUPSIZE = 64000 ## ## Ende des Konfigurationsabschnitts ## # Interne Variablen NEWLINE=" " # Threadfilter # ============ :0 * FILTERTHREADS ?? yes * ! THREADFOLDER ?? ^^^^ * ! FORMAIL ?? ^^^^ * ! THREADFILTERSCRIPT ?? ^^^^ * ! MSGIDTHREADCACHE ?? ^^^^ { :0 Whc : ${MSGIDTHREADCACHE}.lock | ${THREADFILTERSCRIPT} --filter :0 a { :0 c | ${THREADFILTERSCRIPT} --add :0 fhw | ${FORMAIL} -A "X-Filter: Thread" LOG = " Filter: Thread${NEWLINE}" :0 : ${THREADFOLDER} } # Kriterien für den Beginn uninteressanter bzw. unerwünschter # Threads; d.h. im Prinzip ein Killfile für Autoren *und* von # *ihnen* begonnene Threads. :0 * 1^0 ^(From|(X-|)Sender):[ \t]+.*\<?marcel-stein@arcor\.de\>? * 1^0 ^(From|(X-|)Sender):[ \t]+.*\<?marcel-stein@t-online\.de\>? * 1^0 ^(From|(X-|)Sender):[ \t]+.*\<?suse@nitwit\.de\>? * 1^0 ^(From|(X-|)Sender):[ \t]+.*\<?timo@nitwit\.de\>? { :0 c | ${THREADFILTERSCRIPT} --add :0 fhw | ${FORMAIL} -A "X-Filter: Thread" LOG = " Filter: Thread${NEWLINE}" :0 : ${THREADFOLDER} } } # Domainfilter # ============ # # Regeln nach folgendem Muster: # * 1^0 ^(From|(X-|)Sender):[ \t]+.*@\/.*domain.com\>? :0 * FILTERDOMAINS ?? yes * ! DOMAINFOLDER ?? ^^^^ * ! FORMAIL ?? ^^^^ { INCLUDERC = ${PMDIR}/domainfilter } # Absenderfilter # ============== # # Regeln nach folgendem Muster: # * 1^0 ^(From|(X-|)Sender):[ \t]+\/.*\<?eine\.email@adresse\.de\>? :0 * FILTERSENDERS ?? yes * ! SENDERFOLDER ?? ^^^^ * ! FORMAIL ?? ^^^^ { INCLUDERC = ${PMDIR}/senderfilter } # Duplikatfilter # ============== :0 * FILTERDUPS ?? yes * ! DUPFOLDER ?? ^^^^ * ! FORMAIL ?? ^^^^ * ! MSGIDDUPCACHE ?? ^^^^ * ! MSGIDDUPSIZE ?? ^^^^ { :0 Whc : ${MSGIDDUPCACHE}.lock | ${FORMAIL} -D ${MSGIDDUPSIZE} ${MSGIDDUPCACHE} :0 a { :0 fhw | ${FORMAIL} -A "X-Filter: Duplikat" LOG = " Filter: Duplikat${NEWLINE}" :0 : ${DUPFOLDER} } } # Ende. ---------------------------------------------- ---------- $HOME/.procmail/threadfilter.sh ---------- #! /bin/sh # $HOME/.procmail/threadfilter.sh # Thread-Filter für Procmail # Konfiguration MSGIDCACHE="$HOME/.procmail/msgid.thread.cache" MAXIDCOUNT=2500 # Skript PROGNAME="${0##*/}" test -f "$MSGIDCACHE" || touch "$MSGIDCACHE" test $# -eq 0 && { echo "$PROGNAME: Keine Parameter." exit 1 } case "$1" in -a|--add) lockfile "$MSGIDCACHE".lock && { formail -s formail -czx message-id: >>"$MSGIDCACHE" rm -f "$MSGIDCACHE".lock } ;; -f|--filter) # Exitcode: 0 : Mail gehört zum Thread --> ausfiltern # 1 : Mail in Ordnung TMPFILE="$(mktemp -q /tmp/threadfilter-XXXXXX)" test $? -ne 0 && exit 1 formail -cz -x in-reply-to: -x references: | \ sed 's/</\ </g; s/>/>\ /g;' | \ sed -n '/^<[^[:blank:]]\+@[^[:blank:]]\+>$/p' | \ sort -u >"$TMPFILE" grep -qis -f "$TMPFILE" "$MSGIDCACHE" EXITCODE=$? rm -f "$TMPFILE" test "$EXITCODE" -ne 0 && exit 1 ;; -u|--update) lockfile "$MSGIDCACHE".lock && { COUNT="$(cat "$MSGIDCACHE" | wc -l)" test $COUNT -gt $MAXIDCOUNT && { tail -n $MAXIDCOUNT "$MSGIDCACHE" >"$MSGIDCACHE".new mv "$MSGIDCACHE".new "$MSGIDCACHE" } rm -f "$MSGIDCACHE".lock } ;; *) echo "$PROGNAME: Parameter '$1' unbekannt." exit 1 ;; esac exit 0 # Ende. ----------------------------------------------------- Zur Erzeugung der Domain- und Absenderfilter dienen die beiden folgenden awk-Skripte. Hier sind sie zwar nicht schön, dafür aber wenigstens platzsparend. Das Updaten der Filter kann man ja z.B. mit einem Makefile oder einem Cronjob lösen. ---------- $HOME/.procmail/domainfilter.awk ---------- # $HOME/.procmail/domainfilter.awk # Erstellt den Domainfilter für Procmail BEGIN { print "# Domainfilter für Procmail"; printf "# Automatisch erstellt am %s\n\n:0\n", strftime(); } END { printf "{\n\t:0 fhw\n\t| ${FORMAIL} -A \"X-Filter: Domain\"\n\n"; printf "\tLOG = \" Filter: Domain (${MATCH})${NEWLINE}\"\n\n"; printf "\t:0 :\n\t${DOMAINFOLDER}\n}\n\n# Ende.\n"; } ! /^(\#.*|[[:blank:]]*)$/ { domain = gensub("\\\.", "\\\\.", "g"); printf "* 1^0 ^(From|(X-|)Sender):"; printf "[ \\t]+.*@\\/.*%s\\>?\n", domain; } # Ende. ------------------------------------------------------ und beinahe analog ---------- $HOME/.procmail/senderfilter.awk ---------- # $HOME/.procmail/senderfilter.awk # Erstellt den Absenderfilter für Procmail BEGIN { print "# Absenderfilter für Procmail"; printf "# Automatisch erstellt am %s\n\n:0\n", strftime(); } END { printf "{\n\t:0 fhw\n\t| ${FORMAIL} -A \"X-Filter: Absender\"\n\n"; printf "\tLOG=\" Filter: Absender (${MATCH})${NEWLINE}\"\n\n"; printf "\t:0 :\n\t${SENDERFOLDER}\n}\n\n# Ende.\n"; } ! /^(\#.*|[[:blank:]]*)$/ { sender = gensub("\\\.", "\\\\.", "g"); printf "* 1^0 ^(From(X-|)|Sender):"; printf "[ \\t]+\\/.*\\<?%s\\>?\n", sender; } # Ende. ------------------------------------------------------ Bin gespannt auf eure Reaktionen, Mathias -- Das Briefgeheimnis sowie das Post- und Fernmeldegeheimnis sind unverletzlich. Grundgesetz, Artikel 10, Abs. 1 Infos rund um Email-Verschlüsselung --> www.gnupp.de Mein OpenPGP-Schlüssel 0x3B458473 --> blackhole.pca.dfn.de