Zur e-Mail Filterung kommt hauptsächlich Procmail zum Einsatz. Damit alleine einen wirksamen Spamschutz aufzubauen ist allerdings sehr mühsam. Dennoch, erstens können die spezialisierten Filter sehr gut hier eingebunden werden, und zweitens kann man diesen Filtern durch ein wenig Vorverarbeitung eine Menge Arbeit ersparen.
Die Konfigurationsdatei für Procmail befindet sich im Homeverzeichnis des Users unter dem Namen .procmailrc. In der Regel beginnt diese Konfigurationsdatei mit ein paar allgemeinen Einstellungen:
#VERBOSE=YES LANG="de_DE" SHELL="/bin/bash" LOGFILE=/home/siegfried/procmail.log SPAMCACHE=/etc/mail/spamcache KNOWN=NO
Schleife
Danach folgt optional eine Anweisung, die Mailschleifen verhindert. Diese Anweisung habe ich bei mir derzeit nicht drin, da ich keine Mail automatisch um- oder weiter leite, aber das kann sich in Zukunft ändern:
:0 H * ^X-Loop: siegfried@rorkvell.de /dev/null
Dieser header-Eintrag wird so von keinem Mailprogramm erzeugt. Diesen erzeuge ich hier, und zwar immer genau dann, wenn ich eine Mail um-oder weiter leite. Es ist eine Art Merker, der mir zeigt, daß diese Mail schon mal hier gewesen ist und schon mal behandelt wurde. Ein zweites Mal ist überflüssig. Also direkt und dauerhaft wegwerfen.
Als Nächstes folgt eine sofortige und direkte Zustellung ohne weitere Prüfung, wenn diese Mail mit pgp oder gpg signiert ist, die Signatur gültig ist und ich diesen öffentlichen Schlüssel in meinem Schlüsselbund habe:
# Signierte mails :0 HB * ^Content-Type: multipart/signed * ? /home/siegfried/gpgchk { LOG="GPG signature verified " :0 $DEFAULT }
Näheres hierzu siehe hier.
Ganz normal
Als nächstes folgen ein paar Regeln, die gewisse Standardmails grundsätzlich zustellen. Dies sind Mails von meinem Provider sowie Mails, die ich lokal selber generiere, sogenannte System-Messages. Desweiteren befindet sich hier die Behandlung für meine Blog-Kommentare, die ich allerdings bis auf Weiteres abgestellt habe, da ich hier 100% Spam erhalte:
# Blog response :0 H * ^To: bcomment@rorkvell.de { LOG="No Comment " :0 /dev/null } # The daily spam report from 1&1 :0 H * ^From: Spamreport * ^Sbject: Daily report mailbox 2212-361 folder Spam * ^To: Mailbox ........ { LOG="Spam Report " :0 $DEFAULT } # Rechnung von 1&1 :0 H * ^From: .*<rechnungsstelle@1und1.de> * ^Received: from cgi by .*\.einsundeins.de with local { LOG="Rechnung " :0 $DEFAULT } # System messages :0 H * ^From: root@rorkvell.de * ^To: siegfried@rorkvell.de * ^Subject: Cron <siegfried@mx> { LOG="System message " :0 $DEFAULT }
Die genaue Mailbox Bezeichnung des Spam Reports habe ich natürlich entfernt. Alle diese Regeln sind so eine Art Whitelist, nur die Blogkommentare sind zur Zeit ein Wegwerfkriterium. Man beachte, daß signierte Mails an diese Adresse trotzdem ankommen, wenn sie gültig signiert sind mit einem mir bekannten Schlüssel.
Mailinglisten
Es folgt ein weiterer Block mit einer Art Whitelist: Eine Liste aller Mailinglisten, die ich abonniert habe, sowie Benachrichtigungen aus Foren, in denen ich aktiv bin. Mailinglisten haben normalerweise ein header-Feld namens List-Id, durch die die Liste identifiziert wird. Leider haben das nicht Alle. Aber die von mir zur Zeit abonnierten haben solch eine ID, bis auf eine, bei der aber kein wiedererkennbares Muster vorhanden ist. Es wird immer mal wieder gewechselt. Naja, dann landet eben ein Teil davon im Spam.
# Abonnierte Mailinglisten :0 w * ? formail -x"List-Id:" | fgrep -isq -f $HOME/procmail/mailing.lst { LOG="Mailing list " :0 $DEFAULT }
Die Textdatei mailing.lst enthält all die Kennzeichnungen aller Mailinglisten, die ich abonniert habe. Mit formail extrahiere ich dieses Feld und prüfe per fgrep, ob sich dieser Inhalt in der Liste befindet. Wenn ja, wird die Mail zugestellt.
Spam
Es folgen nun eine Reihe von Regeln, die besonders dreisten Spam sofort wegwerfen:
:0 H * ^From: "Automatic Email Delivery Software" { LOG="From spam software " :0 /dev/null } :0 H * ^From: Offres gratuites { LOG="From is spam " :0 /dev/null } :0 H * ^To: undisclosed-recipients { LOG="To whole world spam " :0 /dev/null }
Ausländisch
Diese einfachen Regeln werfen den Spam der allerdümmsten Spammer weg. Es folgen ein paar Regeln, bei denen ich nicht weiß, ob damit Spam oder nicht Spam bezeichnet wird. Es ist schlicht so, daß ich Japanisch nicht lesen kann, und daher spielt es für mich keine Rolle, ob es sich hier um Spam handelt oder nicht, ich kann die Mail sowieso nicht lesen. Also weg damit:
:0 H * ^Content-Type:.*charset="?(big5|iso-2022-jp|ISO-2022-KR|euc-kr|gb2312|ks_c_5601-1987)" { LOG="Strange encoding " :0 /dev/null } :0 H * ^Subject:.*=\?(big5|iso-2022-jp|ISO-2022-KR|euc-kr|gb2312|ks_c_5601-1987)\? { LOG="Strange encoding " :0 /dev/null }
Von dort nur Spam
Aus bestimmten Ländern bekomme ich ebenfalls ausschließlich Spam. Dies sind vor Allem Japan, Korea, Russland, Polen und Ungarn. Folgende einfache Regel wirft solche Mails ebenfalls weg:
:0 H * ^(Return-Path|Reply-To|From):.*[:alnum:]+([[:alnum:]_-]+)*@[[:alnum:]_-]+(\.[[:alnum:]_-]+)*\.(jp|kr|ru|pl|hu) { LOG="Spam country " :0 /dev/null }
Nixspam
Das Nixspam System aus dem Heise Verlag ist ein sehr interessantes System, um bekannten Spam mit Hilfe sogenannter unscharfer (fuzzy) Prüfsummen wiederzuerkennen. Dabei macht man sich zunutze, daß Spam weitgehend redundant ist. Zwar ändern sich die Worte, aber die Struktur bleibt gleich. Also bildet man eine Prüfsumme über die Struktur der Mail:
# Voraussetzung für erste Checksumme: Mindestens ein Zeilenumbruch # und ein paar Leerzeichen oder Tabs :0 B * .$+ * [:space:].+[:space:].*$?.*$?.*[:space:] { # Erste Checksum: Nur Returns und Leerraum :0 bw MD5HASH=|tr -s '[:space:]'\ |tr -d '[:graph:]'\ |md5sum\ |tr -d '-' # Checksumme bereits in Datei? :0 Aw * ? fgrep -s $MD5HASH $SPAMCACHE { KNOWN=YES } } # Voraussetzungen für zweite Checksumme: Satzzeichen, url o.Ä. im Body :0 H * ! $KNOWN=YES * ([<>()|@*'!?,]|//) { :0 bw # Ziffern, Buchstaben, '=' und Returns entfenen # %&# entfernen (html-Schweinereien) # Unterstriche in Punkte umwandeln MD5HASH2=|tr -d '[:cntrl:][:alnum:]%&#;=äöüÄÖÜß'\ |tr '_' '.'\ |tr -s '[:print:]'\ |md5sum\ |tr -d '-' # Hashsumme bereits in Datei? :0 Aw * ? fgrep -s $MD5HASH2 $SPAMCACHE { KNOWN=YES } # Hashsummen zusammenführen :0 A * $MD5HASH2 ?? . { MD5HASH="$MD5HASH $MD5HASH2" } } # Default Checksumme, falls bislang noch nichts gefunden :0 B * ! $MD5HASH ?? . * ....... { :0 bw MD5HASH=|tr -d '[:cntrl:][:space:]='\ |tr -s '[:graph:]'\ |md5sum\ |tr -d '-' :0 Aw * ? fgrep -s $MD5HASH $SPAMCACHE { KNOWN=YES } } :0 * $KNOWN ?? YES { :0 fhw * ^Subject:\/.* | formail -i "Subject: [Known Spam]$MATCH" :0 Efhw | formail -I "Subject: [Known Spam]" :0 $DEFAULT }
Und der Rest
Damit werden bekannte Spam-Mails als solche markiert und zugestellt. Das Einsortieren in den Spam-Folder überlasse ich dann einem einfachen Filter im Mail User Agent. Der Rest wird nun SpamAssassin vorgeworfen:
:0 f * ! ^X-Spam-Status: Yes |/usr/bin/spamc -d mx :0 { LOG="Default " :0 $DEFAULT }
Zunächst werden alle übriggebliebenen Mails schlicht durch SpamAssassin gefiltert und eventuell als Spam markiert. Die Zustellung, ob markiert oder unmarkiert, erfolgt mit der letzten Regel.