
Ich habe einen (Linux) Mailserver, der besteht auspostfix
zum Empfangen von Post,amavisd-new
zur Inhaltsfilterung (mit clamav
und SpamAssassin
) unddovecot
für Zustellung und IMAP.
Ich möchte es so einrichten, dass jedes Mal, wenn eine E-Mail an ein bestimmtes Postfach zugestellt wird, ein Skript gestartet wird. Das Skript muss nicht unbedingt etwas über den Inhalt oder die Header der Nachricht wissen. Ich kenne zumindest ein paar Optionen:
Verwenden
postfix
Integrierte Filterung. Richten Sie eine Header-Prüfung ein, um alle für dieses Postfach bestimmten E-Mails an mein Skript umzuleiten, das sie dann wieder an weiterleiten kannpostfix
. Der Nachteil dabei ist, dass alles voramavis
der Filterung von geschieht, sodass mein Skript auch für E-Mails ausgelöst wird, die vor der Zustellung blockiert werden. Es kann auch zu Leistungseinbußen und dem Risiko verlorener E-Mails kommen, wenn ich die Weiterleitung der E-Mail an nichtpostfix
ordnungsgemäß durchführe.Fügen Sie mein Skript als Inhaltsfilter hinzu
amavis
. Dies könnte eine Leistungsverbesserung gegenüber dem vorherigen sein und scheint einfach ein besserer Ort dafür zu sein. Leider leidet es immer noch darunter, dass es ausgeführt wird, bevor die Go/No-Go-Entscheidung für die Nachricht getroffen wurde. Darüber hinaus konnte ich keine Dokumentation finden, in deramavis
detailliert beschrieben wird, wie dies tatsächlich durchgeführt werden soll, und die Conf-Dateien sind nicht wirklich schlüssig.
Der letzte dovecot
Zustellungsschritt scheint der beste Weg zu sein, um nur gefilterte E-Mails zu erhalten, aber ich bin nicht sicher, ob es eine Möglichkeit gibt, das zum Laufen zu bringen.
Vorschläge? Übersehe ich etwas?
Bearbeiten:Ich habe vergessen hinzuzufügen, dass ich Polling-Lösungen (Überwachungsprotokolle, IMAP-Client-Skripts usw.) vermeiden möchte.
Antwort1
Ich habe eine andere Option gefunden, die sich als ausreichend gute Lösung erweisen könnte: das Entführen der Nachricht bei der Übermittlung von postfix
an dovecot
.
Für postfix
ändere ich folgende Zeilen in master.cf
:
dovecot unix - n n - - pipe
flags=DRhu user=vmail:mail argv=/usr/lib/dovecot/dovecot-lda -d $(user)@$(domain)
Zu:
dovecot unix - n n - - pipe
flags=DRhu user=vmail:mail argv=/scripts/emaildeliverycheck.py $(user)@$(domain)
Erstellen Sie dann /scripts/emaildeliverycheck.py
Folgendes (Python 3.4):
#!/usr/bin/python3
from sys import argv, stdin, exit
from subprocess import Popen, check_call, CalledProcessError
# Define recipients that should trigger the script here
notifyusers = ('[email protected]',
'[email protected]')
recipient = argv[1]
if recipient in notifyusers:
# Run the script. Use Popen so that we don't have to wait for the
# script to finish
Popen(['/scripts/myscript.py', recipient])
try:
# Now pass the email to dovecot-lda. Use check_call because we *do*
# want to wait for it to finish
check_call(['/usr/lib/dovecot/dovecot-lda', '-d', recipient], stdin=stdin)
except CalledProcessError as error:
# Propagate any error codes back to Postfix
exit(error.returncode)
Der Postfix- pipe
Prozess übergibt die E-Mail zur endgültigen Zustellung an das obige Skript statt direkt an dovecot-lda
. Das Skript gleicht den Empfänger (der über die Befehlszeile übergeben wird, sodass es die Nachricht überhaupt nicht einsehen muss) anhand einer Liste ab und startet ein weiteres Skript, wenn eine Übereinstimmung vorliegt. Dann leitet es die Nachricht an weiter dovecot-lda
, das nicht erkennen sollte, dass es sie nicht direkt von Postfix erhält, und gibt den Beendigungsstatus an den pipe
Prozess zurück.
Funktioniert im ersten Test einwandfrei. Dadurch erhalte ich nur nachgefilterte E-Mails, und das ist mein Ziel.
Antwort2
Ich verwende procmail
als lokalen Zustellagenten. Dies ermöglicht eine umfassende Filterung anhand von Regeln, die für den Benutzer gelten. Es sollte möglich sein, Postfix so zu konfigurieren, dass procmail die Filterung und, falls gewünscht, die Zustellung der E-Mail übernimmt.
procmail
verfügt über umfangreiche Funktionen zum Anwenden von Filtern auf Kopfzeilen, Inhalte oder beides. Sie können jedes Programm als Filter verwenden, sodass Sie Ihr Skript für jede an den angegebenen Benutzer gesendete E-Mail auslösen können.