qmail und Greylisting: Implementierung

Auf unseren internen System evaluieren wir derzeit den Einsatz von Greylisting mittels qmail. Am Beginn der Suche stand hier zunächst, einen geeigneten Patch zu finden. Genauer gesagt sind es gleich mehrere. Um das Ergebnis vorwegzunehmen: Die finale Struktur sieht wie folgt aus …

  1. qmail-smtpd wird derart gepatcht, dass es bin/qmail-envelope-scanner aufruft. Der Patch hierfür ist klein und überschaubar und agnostisch, was den eigentlichen die Header beurteilenden Vorgang betrifft. Er sorgt lediglich dafür, dass der Exitcode von qmail-envelope-scanner ausgewertet wird und dementsprechend qmail-smtpd dann einen temporären oder permanenten Fehler zurückliefert. Einen Autor für diesen Patch habe ich nicht finden können; Jeremy Kusnetz hat offensichtlich die „beste“ Version aus verschiedenen Schnipseln zusammengesetzt, die auf der Mailingliste herumgingen.
  2. Der eigentliche qmail-envelope-scanner stammt von Martin Dempsey. Martin hatte zunächst local_scan als Greylisting-Erweiterung für Exim entwickelt. Als Standalone-Tool war es aber nicht weit davon entfernt, auch von qmail aus genutzt zu werden. Der qmail-envelope-scanner ist nur ein Wrapper (33 Zeilen) um das eigentliche local_scan herum.

Die aus meiner Sicht praktikabelste Zusammenstellung der Patches stammt schließlich von Bill Shupp. Wer hier weiter nach unten scrollt, findet dort den Abschnitt „EXPERIMENTAL: greylisting patch“. Er fasst die beiden obigen Patches zusammen mit einem Patch für das Makefile von netqmail-1.05 zusammen.

Bei uns waren noch zwei Änderungen nötig, die jedoch spezifisch für das von uns eingesetzte CentOS sind:

  • Der Verweis auf /usr/lib/libmysqlclient.a im Makefile muss auf /usr/lib/mysql/libmysqlclient.a geändert werden, da die Bibliotheken bei CentOS in diesem Unterverzeichnis liegen.
  • In conf-cc muss noch ein „-lssl“ ergänzt werden, da die libmysqlclient bei CentOS mit SSL-Support kompiliert wurde und sich von daher nicht benutzen lässt, wenn nicht auch gleichzeitig gegen die OpenSSL-Library gelinkt wird.

Ansonsten müssen nur noch Bills Anweisungen befolgt werden: Es sollte ein periodischer Job eingerichtet werden, der veraltete Einträge aus der Datenbank entfernt werden, und es muss eine Tabelle für die Daten angelegt werden.

Die Konfiguration kann in dieser Version sehr praktisch – Dank an Joshua Megerman – durch Umgebungsvariablen geregelt werden, für die ich empfehlen würde, sie in /service/qmail-smtpd/run unterzubringen. Bei dieser Gelegenheit würde ich auch die Expire-Werte anpassen, da mir ein erstes Akzeptieren eines Tripels erst 55 Minuten nach dem ersten Zustellversuch doch reichlich spät erscheint:

export MYSQLHOST="..."
export MYSQLUSER="..."
export MYSQLPASS="..."
export MYSQLDB="..."
# minutes until email is accepted
export BLOCK_EXPIRE="5"
# minutes until record expires
export RECORD_EXPIRE="500"
# days until record expires after accepting email
export RECORD_EXPIRE_GOOD="36"
export LOCAL_SCAN_DEBUG="1"

(Hier würde sich empfehlen, die Zugangsdaten zu MySQL in einem separaten Shellscript auszulagern, das dann sowohl vom rund-Script als auch vom Aufräumjob eingebunden wird. Ich hab’s nicht so gern, wenn Daten auf zig Orte verstreut werden.)

Erstes Ergebnis: Nur rund 1,5 Prozent aller Zustellversuche werden wiederholt. Es ist also davon ausgehen, dass die restlichen 98,5 Prozent in erster Linie Spammer sein werden. Wir bleiben dran.