Mailsystem mit Spam-Filterung
Aus Tuxfutter
Inhaltsverzeichnis |
[Bearbeiten] Einleitung
Die folgende Anleitung beschreibt den Aufbau eines Mailsystems mit Spam-Filterung.
Die Zutaten:
- Postfix
- Cyrus IMAP-Server
- Bogofilter
- Procmail
- Cron
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.

