Mailsystem mit Spam-Filterung

Aus Tuxfutter

Wechseln zu: Navigation, Suche

Inhaltsverzeichnis

[Bearbeiten] Einleitung

Die folgende Anleitung beschreibt den Aufbau eines Mailsystems mit Spam-Filterung.

Die Zutaten:

und natürlich: Linux mit ein wenig Bash-Programmierung.

[Bearbeiten] Postfix

Zunächst wird Postfix installiert und konfiguriert.

Da procmail eingesetzt werden soll, muss die Auslieferung der Mails an die Mailboxen nicht von Postfix erfolgen, sondern dies wird procmail übernehmen. In der procmailrc, die unten beschrieben wird, wird die bearbeitete Mail an das Auslieferungsprogramm des IMAP-Servers übergeben.

Dazu wird die /etc/postfix/main.cf geändert:

default_privs = cyrus
mailbox_transport = procmail

In die /etc/postfix/master.cf wird – auch um den Cyrus-Server zu verwenden – folgendes eingetragen:

cyrus     unix  -       n       n       -       -       pipe
  flags=R user=cyrus argv=/usr/sbin/cyrdeliver -e -m ${extension} ${user}
procmail  unix -       n      n      -      -       pipe
  flags=R user=cyrus argv=/usr/bin/procmail -p USER=${user} EXTENSION=${extension} /etc/procmail/procmailrc

Danach nicht vergessen, den Postfix-Dienst neu zu starten!

[Bearbeiten] Cyrus IMAP-Server

Nach der distributionsabhängigen Installation muss der Cyrus IMAP-Server ggf. ein wenig konfiguriert werden.

Das System, das als Beispiel dient, hat folgende Cyruskomponenten installiert:

hauke@athene:/etc/postfix$ dpkg -l | grep cyrus
ii  cyrus-admin    1.5.19-9.1     CMU Cyrus mail system (administration tool)
ii  cyrus-common   1.5.19-9.1     CMU Cyrus mail system (common files)
ii  cyrus-imapd    1.5.19-9.1     CMU Cyrus mail system (IMAP support)
ii  cyrus-pop3d    1.5.19-9.1     CMU Cyrus mail system (POP3 support)
hauke@athene:/etc/postfix$

Der POP3d wird verwendet, da die meisten Benutzer noch immer per POP3 ihre Mails abholen.

Eingetragen muss in die Datei /etc/imapd.conf der Benutzer, der das IMAP-System verwalten darf. Dies kann ein unprivilegierter Benutzer sein, es darf auf keinen Fall root sein!

Eine Beispieldatei /etc/imapd.conf:

 # Debian Cyrus imapd.conf
 # See imapd.conf(5) for more information

 # Configuration directory
 configdirectory: /var/lib/cyrus

 # Which partition to use for default mailboxes
 defaultpartition: default
 partition-default: /var/spool/cyrus/mail
 # partition-default: /var/spool/mail

 # News setup
 partition-news: /var/spool/cyrus/news
 newsspool: /var/spool/news

 # Uncomment the following and add the space-separated users who
 # have admin rights
 admins: cyrus

 # No anonymous logins
 allowanonymouslogin: no

 # Minimum time between POP mail fetches in minutes
 popminpoll: 0

 # umask used by Cyrus programs
 umask: 077

 defaultacl: anyone lrsp

Für diese Anleitung wurde der Benutzer cyrus gewählt, der der Gruppe mail freundlicherweise angehört.

Da auch der Cyrus-Server eigene Benutzer für die Administration pflegt, muss dafür gesorgt werden, dass der pwcheckd läuft (zumindest auf Debian Woody).

Bitte nicht verwirren lassen: Es gibt einen Linux-Benutzer mit namen cyrus (gehört – wie gesagt – in die Gruppe mail) und es gibt einen Cyrus-internen Benutzer cyrus.

Der interne Benutzer wird für das Cyrus-Administrationstool cyradm verwendet!

Mit Hilfe des Programmes cyradm werden nicht nur die Benutzermailboxen angelegt, für diese Anleitung benötigt man – neben der INBOX, die automatisch erzeugt wird – auch die Mailordner

  • Spam
  • Unbekannt
  • Bogofilter

[Bearbeiten] Bogofilter

Bogofilter wird im laufenden Betrieb konfiguriert; will heißen: Der Filter wird nach und nach mit „guten“ Mails (Ham) und „bösen“ Mails (Spam) gefüttert. Das Programm legt dazu eine Datei wordlist.db an, die normalerweise innerhalb des Heimatbereiches eines Benutzers liegt und eine Wortliste enthält.

Die hier vorgestellte Lösung erwartet die Wortliste unter /etc/bogofilter/<benutzername>, da procmail über den Benutzer cyrus aufgerufen wird. Dadurch müssten Teile der Benutzerverzeichnisse (nämlich das verzeichnis, in dem die Wortliste liegt) für den Benutzer cyrus mit Schreib- und Leserecht versehen werden. Das ginge zwar, jedoch hat die hier gewählte Lösung den Vorteil, dass alle Wortlisten der Benutzer zentral gespeichert sind.

Das Verzeichnis /etc/bogofilter, incl. aller Unterverzeichnisse und darinliegender Dateien gehört dem Benutzer cyrus. Und auch nur dieser hat Schreib-, Lese- und Ausführungsrechte!

Dazu wird Bogofilter so eingestellt, dass es „Ham“, „Spam“ und „Unsure“ zurückmeldet.

Eine Beispieldatei /etc/bogofilter.cf, bei der Kommentare entfernt wurden:

 bogofilter_dir=~/.bogofilter

 spam_header_name=X-Bogosity

 spam_subject_tag=***SPAM***
 unsure_subject_tag=???UNSURE???

 stats_in_header=Yes

 spamicity_formats = %0.6f, %0.6f, %0.6f
 spamicity_tags = Spam, Ham, Unsure

 header_format = %h: %c, tests=bogofilter on athene, spamicity=%p, version=%v

 replace_nonascii_characters=N

 ham_cutoff = 0.45
 spam_cutoff= 0.99

Alles, was in obiger Datei nicht aufgeführt ist, wird nicht verwendet und kann als Kommentar gesehen werden.

[Bearbeiten] Procmail

Procmail kann Mails (vor-) bearbeiten und auch andere Programme aufrufen. Gesteuert wird procmail über Dateien, die Regeln enthalten und – wenn eine Regel erfüllt ist – Aktionen ausführen lassen.

Für diese Anleitung wird ein Verzeichnis /etc/procmail angelegt. Wenigstens die Gruppe mail muss Leserecht auf Dateien in diesem Verzeichnis haben.

Für die Steuerung von procmail wird eine Datei procmailrc in /etc/procmail angelegt:

 # Procmail
 PATH=/bin:/usr/sbin:/usr/bin:/usr/local/bin:/usr/local/sbin
 SHELL=/bin/sh
 LOGFILE="/var/log/procmail.log"
 VERBOSE=no

 # Mailbox-Zustellung
 DELIVERMAIL="/usr/sbin/cyrdeliver"
 INBOX="$DELIVERMAIL -a $USER -q -m user.$USER"
 SPAM="$INBOX.Spam"
 UNKNOW="$INBOX.Unbekannt"

 # bogofilter
 BOGOFILTER="/usr/local/bin/bogofilter -d /etc/bogofilter/$USER"

 # M$ Muell-Subj. korr.
 SUBJ_=`/usr/bin/formail -xSubject: \
       | expand | sed -e 's/^[ ]*//g' -e 's/[ ]*$//g' -e 's/^AW/Re/g' -e 's/AW://g'`

 # Auf Spam testen...
 :0 fw
 * < 200000
 | $BOGOFILTER -p -e

 # Subj korrigieren
 :0 fhw
 | formail -I "Subject: ${SUBJ_}"

 # Spam? Dann in den Spam-Ordner
 :0
 * ^X-Bogosity:.Spam
 | sed -e '/^From /d' | $SPAM
 # --- From-Zeile löschen, ---
 # --- sonst funktioniert cyrdeliver nicht !! ---

 # Unsicher? Dann in den Unbekannt-Ordner
 :0
 * ^X-Bogosity:.Unsure
 | sed -e '/^From /d' | $INBOX.Unbekannt
 # --- an INBOX zustellen ---
 :0w
 | sed -e '/^From /d' | $INBOX

 # --- und Schluss ---
 :0w
 {
 EXITCODE=$?
 }

Hinweis: Das Zustellprogramm von Cyrus heißt normalerweise deliver, bei Debian (Woody) jedoch cyrdeliver. Über die Paketverwaltung der Distribution lässt sich herausfinden, wie das Zustellprogramm genau heißt.

Die Beispieldatei korrigiert nebenbei auch die nicht RFC-konformen Antwortheader von Microsoft Outlook (AW: statt Re:).

Besonderen Augenmerk sollte man auf die Zeile

* < 200000

legen: Es werden in diesem Beispiel nur Mails an Bogofilter gegeben, die kleiner als 200.000 Zeichen umfassen. Der Wert sollte nicht zu hoch eingestellt werden.

Man stelle sich vor, dass man eine 13 MB große Mail bekommt, die ein AVI-File enthält. Bogofilter müsste die gesamte Mail in den Speicher laden, wenn obiger Wert nicht gesetzt wäre.

Bei einer ankommenden Mail würde das System die Datenmenge noch bewältigen können, aber bei 10 oder gar 1000 Benutzern, die Mails bekommen, käme das System schnell an seine Grenzen.

[Bearbeiten] Zwischenfazit

Bis hierhin ist das Mailsystem soweit fertig und sollte – nach (Neu-)Start der beteiligten Dienste Mails an die Benutzer ausliefern.

Getestet werden kann die per POP3-Abfrage, bzw. IMAP-Abfrage, mit IMAP- und POP3-fähigen Mail-Clients, wie z.B. Evolution oder KMail.

Der nächste Schritt ist die regelmäßige Leerung des Spam-Ordners und die automatische Pflege der Wortlisten von Bogofilter.

[Bearbeiten] Aus dem IMAP-Ordner in die Wortliste

Die Benutzer haben fleißig nicht erkannten Spam (der im Ordner Unbekannt einsortiert wurde) in den Ordner Bogofilter verschoben.

Nun muss der Werbemüll raus aus dem Verzeichnis und rein in die „Datenbank“ des Bogofilters. Am Besten natürlich auch in die richtige Datenbank, da jeder Benutzer andere Präferenzen hat.

Das folgende Skript feed-spam.sh, dass z.B. in /root/bin liegt, geht die Benutzer-Mails im Verzeichnis Bogofilter durch, füttert gefundene Spam-Mails an bogofilter, löscht die bearbeitete Mail und restauriert zum Schluss für den Cyrus Server das Verzeichnis wieder:

 #!/bin/sh

 cd /var/spool/cyrus/mail/user

 for user in * ; do
   echo "User: $user"
   if [ -e "$user/Bogofilter" ] ; then
     echo "...Bogofilter gefunden!"
     for spam in "$user/Bogofilter/"* ; do
       bogofilter -d "/etc/bogofilter/$user" -s < "$spam" && rm -f "$spam"
     done
     rm -f "$user/Bogofilter/cyrus."*
     # Mailbox aufraeumen
     su -c "reconstruct user.$user.Bogofilter" - cyrus
   fi
 done

 exit 0

Hinweis: Werden quotas verwendet, sollte man ab und zu ein su cyrus -c quota -f ausführen bzw. direkt ins script eingebinden, falls quota benutzt werden, da durch den reconstruct die quota informationen nicht repariert werden

(Die Echos sind nur für die ggf. zu versendende Mail ganz nützlich. Man kann die Ausgaben auch weglassen).

Dieses Skript läuft unter dem Benutzer „root“ (u.a. wegen des su-Befehls; reconstruct darf nur vom Benutzer cyrus ausgeführt werden!) und sollte in die crontab per crontab -e von root eingebunden werden:

0   7 * * *     /root/bin/feed-spam.sh

Damit wird das Skript jeden Morgen um 7 Uhr aufgerufen.

Nun hat man ein kleines Mailsystem, mit Spamfilter und dessen automatischer Fütterung.

'Persönliche Werkzeuge