
Wir haben einen header_checks-Regexp, der an den „Cleanup“-Prozess übergeben wird, dieser verarbeitet den Header jedoch nicht als einzelnen Header, wenn er sich über mehrere Zeilen erstreckt.
header_check (Wert des Headers an FILTER übergeben):
/^X-OurHeader:\s+(.*?)/ FILTER $1
master.cf:
cleanup_service. unix n - y - 0 cleanup
-o header_checks=regexp:/etc/postfix/header_check
Beispiel einer mehrzeiligen Kopfzeile, bei der es fehlschlägt:
X-OurHeader: a_special_filter_command:my.sub.domain
b.mail.whatever.com
Der ursprüngliche vollständige Header vor der Mehrzeilenerweiterung lautet:
X-OurHeader: a_special_filter_command:my.sub.domainb.mail.whatever.com
Das an FILTER übergebene Ergebnis lautet dann: a_special_filter_command:my.sub.domain
und es fehlt der verbleibende Hostname aus der zweiten Zeile b.mailwhatever.com
.
Wenn ich stattdessen header_check folgendermaßen ändere, wird die nächste Zeile erfasst:
/^X-OurHeader:\s+([\s\S]*)/ FILTER $1
Die $1-Erfassungsgruppe enthält dann die zweite Zeile, aber im erfassten Text ist immer noch ein Leerzeichen (und vermutlich auch ein Zeilenumbruch), sodass das nicht funktioniert. Das sieht dann so aus:
X-OurHeader: a_special_filter_command:my.sub.domain b.mail.whatever.com
Wenn wir uns die Protokolle des ersten Ansatzes ansehen, sehen wir
postfix/cleanup[123456]: 27429A1FE8: filter: header X-OurHeader: a_special_filter_command:my.sub.domain? b.mail.whatever.com
Gibt es einen alternativen Ansatz hierzu, den jemand vorschlagen könnte? Das Endziel ist, dass wir einen Header mit einem speziellen cmd:hostname-Wert markieren, der an den FILTER gesendet werden muss, aber wir möchten unterstützen, dass dieser HDR-Wert in mehrere Zeilen aufgeteilt wird, damit ein langer Header dem Standard „Länge SOLLTE < 78 sein“ entspricht.
Antwort1
Wenn Sie wissen oder sicherstellen können, dass es nur eine bestimmte Anzahl von Variationen gibt, fügen Sie zusätzliche Ausdrücke hinzu, um diese separat zu erfassen. /..:(.*) (.*)$/ -> /..:$1$2/
Wenn kein Leerzeichen vorhanden ist, fährt Postfix mit dem nächsten Ausdruck fort. Halten Sie die Muster also einfach, indem Sie die komplexe Übereinstimmung an den Anfang setzen.
Wenn nicht, aber immer noch innerhalb der Möglichkeiten regulärer Ausdrücke, gibt es vielleicht eine Möglichkeit,Verketten mehrerer Suchvorgänge. Aus dem Stegreif kann ich nicht alles zusammenschustern, aber wenn es auf Ihrer Distribution verfügbar ist und überhaupt funktioniert, sollte die Dokumentation hilfreich sein. Beginnen Sie mit dem header_checks
Handbuch und der DATABASE_README
Datei.
pipemap:{pcre:/extract/category.pcre,pcre:/map/category/to/filter/command.pcre}
Grundidee: Informieren Sie sich zunächst allgemein (z. B. MYFILTER: $1
) und nehmen Sie erst dann die erforderlichen Änderungen vor, um daraus einen gültigen Postfix-Befehl zu machen. Stellen Sie dabei sorgfältig sicher, dass alle Eingaben zu einer gültigen Ausgabe führen ( MYFILTER: (valid1|valid2) -> FILTER host:port
plus einer Fallback-Zeile MYFILTER:
-> FILTER: default:port
).
Wenn dies nicht gelingt, eskalieren Sie normalerweise zur Turing-Vollständigkeit, wenn Sie Dinge tun möchten, die für reguläre Ausdrücke und Header-Checks zu mächtig sind:
Eine ausreichend dynamische Suche. Wenn Sie beispielsweise SQL mögen, sollte dies zu einem Ergebnis führen, das nicht allzu schlecht lesbar/wartungsfreundlich ist. Achten Sie auf unbeabsichtigte logische Ergebnisse aus mehreren Suchvorgängen.
header_checks = sqlite:/path/to/definition.conf pcre:/remaining/simpler/rules.pcre
Ein Milter/Policy-Daemon. Sie könnten sogar externe Binärdateien aufrufen, ohne die Nachricht überhaupt umzuleiten. Abhängig von der Schnittstelle Ihrer aktuellen Vorstellung des nächsten Filters in der Reihe kann dies mehr oder weniger praktisch sein.
Ich glaube auch, dass es Möglichkeiten gibt, Postfix richtig zu bekommenTransporteine bestimmte Nachricht bei Bedarf durch mehrere Instanzen von Header_Checks, aber ich würde diesen Weg nicht empfehlen, da er sich nicht gut mit anderen (mehr oder weniger dynamischen) Routing-Entscheidungen kombinieren lässt.