Policyguard - Early-Reject Postfix Policy Spamfilter für Google & Co.

PolicyGuard — Intelligenter Postfix-Spamfilter mit automatischer Lernfunktion

PolicyGuard ist ein in Python geschriebener Policy-Daemon für den Mail Transfer Agent Postfix. Er schaltet sich in den SMTP-Dialog ein und entscheidet in Echtzeit — noch bevor eine E-Mail vollständig angenommen wird — ob eine eingehende Nachricht zugestellt, abgelehnt oder temporär zurückgestellt wird.

Wie es mit Postfix zusammenarbeitet

Postfix leitet bei jeder eingehenden Verbindung Metadaten an den Daemon weiter: Absenderadresse, Empfänger, IP-Adresse des sendenden Servers, HELO-Name und Client-Hostname. PolicyGuard wertet diese Daten aus und antwortet mit einer Postfix-Direktive — entweder dunno (durchlassen), reject (sofort ablehnen) oder defer (temporär zurückstellen). Die eigentliche E-Mail wird dabei gar nicht erst übertragen, was den Server-Ressourcenverbrauch minimal hält.

Mehrstufige Filterkaskade

Jede eingehende E-Mail durchläuft mehrere Prüfebenen in fester Reihenfolge:

Empfänger-Blocklist — bestimmte Zieladressen werden pauschal abgewiesen

Client-Hostname-Blocklist — bekannte Spam-Infrastrukturen (z. B. google-usercontent) werden direkt geblockt

Regex-Filter — verdächtige Absender-Muster, typisch für Google-Groups-Missbrauch, werden erkannt

SPF-Prüfung — der sendende Server wird gegen den SPF-Eintrag der Absender-Domain geprüft; bei fail wird die Mail abgelehnt, bei Google-HELO zusätzlich softfail und permerror

Firebase-Erkennung — Domains, die Firebase-Mailversand nutzen, werden über SPF-Includes und TXT-Records erkannt und geblockt

Hunter.io-Erkennung — Domains, die im Abuse-Verzeichnis von Hunter.io gelistet sind, werden blockiert

Unbekannte Clients — Server ohne rDNS erhalten ein temporäres defer 450, was legitime Mailserver automatisch wiederholen lässt, Spam-Schleudern jedoch oft nicht

Das lernende Kernelement: die Auto-Blocklist

Das intelligenteste Feature ist die automatische Blocklist, die sich aus dem eigenen Mail-Journal aufbaut. Das Programm liest fortlaufend die Postfix-Logs via journalctl aus und zählt pro Absender-Domain, wie viele E-Mails blockiert versus akzeptiert wurden. Überschreitet eine Domain den konfigurierbaren Schwellenwert — standardmäßig 76% Blockierrate bei mindestens 4 Mails in den letzten 50 Tagen — wird sie automatisch zur Blocklist hinzugefügt. Das System lernt also aus dem eigenen Filterverhalten, ohne manuelles Eingreifen.

Effizienz durch Caching und inkrementelles Logging

Um bei jedem eingehenden Mail nicht neu rechnen zu müssen, hält PolicyGuard sämtliche Daten im RAM: die Auto-Blocklist, SPF-Auflösungen, DNS-TXT-Abfragen und Hunter.io-Ergebnisse werden gecacht. Die Journal-Daten vergangener Tage werden in einer lokalen JSON-Datei persistiert und nur einmalig eingelesen. Während des Betriebs liest das Programm lediglich inkrementell neue Journal-Einträge ein — höchstens alle 30 Sekunden — und aktualisiert die Blocklist bei Bedarf im Hintergrund. Über eine einfache Textschnittstelle lassen sich per stats- und blocklist-Kommando jederzeit Einblicke in das Filtergeschehen abrufen.


Installation unter Proxmox Mail-Gateway

Voraussetzungen

PolicyGuard läuft als Postfix Policy-Daemon unter Proxmox Mail Gateway (PMG). Für die Installation werden Root-Rechte benötigt.

1. Python-Abhängigkeiten installieren

apt install python3-spf python3-dnspython

2. Skript installieren

Das Skript nach /usr/local/bin/ kopieren und ausführbar machen:

cp policyguard.py /usr/local/bin/policyguard.py
chmod +x /usr/local/bin/policyguard.py

3. Arbeitsverzeichnis anlegen

PolicyGuard benötigt /t/ für den Journal-Cursor und den Cache:

mkdir -p /t/
chmod 777 /t/

4. Journal-Zugriff für nobody erlauben

PolicyGuard läuft unter dem Benutzer nobody und benötigt Lesezugriff auf das systemd-Journal. Dazu eine sudo-Regel anlegen:

visudo -f /etc/sudoers.d/policyguard

Folgenden Inhalt eintragen und speichern:

nobody ALL=(root) NOPASSWD: /usr/bin/journalctl

5. PMG-Konfigurationstemplates vorbereiten

Damit Änderungen an der Postfix-Konfiguration PMG-Updates überstehen, müssen die Templates in das Override-Verzeichnis kopiert werden — sofern noch nicht geschehen:

mkdir -p /etc/pmg/templates/
cp /var/lib/pmg/templates/master.cf.in /etc/pmg/templates/
cp /var/lib/pmg/templates/main.cf.in /etc/pmg/templates/

6. Postfix konfigurieren
main.cf.in — Sender-Restriktionen erweitern

In /etc/pmg/templates/main.cf.in den Policy-Dienst zu den smtpd_sender_restrictions hinzufügen:

smtpd_sender_restrictions =
                   check_policy_service unix:private/policygrd

Bestehende Restriktionen bleiben erhalten — die neue Zeile einfach in die vorhandene Liste einreihen.

master.cf.in — Daemon-Eintrag ergänzen

Am Ende von /etc/pmg/templates/master.cf.in folgende zwei Zeilen einfügen:

policygrd unix - n n - 0 spawn
    user=nobody argv=/usr/local/bin/policyguard.py

7. Konfiguration übernehmen

Nach dem Bearbeiten der Templates die PMG-Konfiguration neu generieren und Postfix neu laden:

pmgconfig sync --restart 1

Überprüfung und Test

apt install socat
socat - UNIX-CONNECT:/var/spool/postfix/private/policygrd

blocklist domo
==== BEGIN CURRENT BLOCKLIST ====
domointelligence.com
==== END CURRENT BLOCKLIST ====
stats domo
==== TOTAL DOMAIN STATS (all days + today) ====
  domointelligence.com           accept: 4  blocked: 31  total: 35  percent blocked: 88 %
==== END TOTAL DOMAIN STATS ====
stats 60 80
==== TOTAL DOMAIN STATS (all days + today) ====
  texbangla.com                  accept: 6  blocked: 24  total: 30  percent blocked: 80 %
  dachser.com                    accept: 8  blocked: 29  total: 37  percent blocked: 78 %
  rsgsv.net                      accept: 5  blocked: 18  total: 23  percent blocked: 78 %
  premium-box.eu                 accept: 11  blocked: 34  total: 45  percent blocked: 75 %
  hipalanet.com                  accept: 6  blocked: 18  total: 24  percent blocked: 75 %
  dubaidutyfreetennischampionships.com accept: 2  blocked: 6  total: 8  percent blocked: 75 %
  bobsbonsai.com                 accept: 6  blocked: 16  total: 22  percent blocked: 72 %
  momentstudio.ca                accept: 7  blocked: 18  total: 25  percent blocked: 72 %
  table.media                    accept: 2  blocked: 5  total: 7  percent blocked: 71 %
  carvertical.com                accept: 2  blocked: 4  total: 6  percent blocked: 66 %
  andia-international.com        accept: 7  blocked: 14  total: 21  percent blocked: 66 %
  mandrillapp.com                accept: 2  blocked: 4  total: 6  percent blocked: 66 %
  o2lenses.com                   accept: 3  blocked: 6  total: 9  percent blocked: 66 %
  equinestar.net                 accept: 6  blocked: 11  total: 17  percent blocked: 64 %
==== END TOTAL DOMAIN STATS ====

 

Quellcode und config (/etc/policyguard.toml)

policyguard.py

policyguard.toml