85.1.9. pepsi-stage-bounce¶
rewrite a message into a delivery-status bounce
- Handbuchabschnitt:
1
85.1.9.1.1. Name¶
pepsi-stage-bounce - die Bounce-Erzeugungs-Stage der Pepsi-Pipeline.
85.1.9.1.2. Übersicht¶
pepsi-stage-bounce [GLOBAL-OPTIONS] worker
85.1.9.1.3. Beschreibung¶
pepsi-stage-bounce ist ein Stage-Programm: Es wird von pepsi-dispatch(1) als persistenter Worker ausgeführt, der Nachrichten-IDs von der Standardeingabe liest, von denen jede einen Datensatz der pepsi.workqueue-Tabelle identifiziert. Es lädt diesen Datensatz, weigert sich zu handeln, sofern sein status nicht running ist, und liest seine eigene Konfiguration aus dem [stage-<stage>]-Abschnitt der Nachricht (siehe pepsi.conf(5)).
Es schreibt die Nachricht an Ort und Stelle in eine RFC-3464-Zustellungsstatusbenachrichtigung (DSN) um: Der Umschlagabsender wird zum Null-Absender (<>), der Umschlagempfänger zum Absender der ursprünglichen Nachricht, und der Nachrichtentext wird zu einem multipart/report, der die ursprünglichen Header zitiert.
„Der Absender der ursprünglichen Nachricht“ ist state.srs.original, wenn pepsi-stage-srs(1) einen solchen festgehalten hat, und andernfalls die mail_from-Spalte. Der Unterschied zählt auf jedem weiterleitenden Pfad, denn SRS läuft notwendigerweise vor der Zustell-Stage: Wenn hier eine DSN verfasst wird, ist der Umschlagabsender einer unserer eigenen SRS-Aliase, und den Bericht an ihn zu adressieren hieße, ihn hinaus zum nächsten Hop und über unseren eigenen MX wieder herein zum Dekodieren zu schicken — wobei er als Null-Absender-Nachricht die gesamte eingehende Pipeline überstehen müsste — nur um bei einer Adresse anzukommen, die die ganze Zeit auf dem Datensatz stand. SRS ist ein Rückweg für einen Bounce, den der nächste Hop erzeugt; ein Bericht, den wir selbst schreiben, braucht diesen Umweg nicht. Siehe pepsi.state(7). Standardmäßig ist dies ein Failure-Bounce (Action: failed); wenn die routende Stage state.bounce mit kind = success markiert, ist es stattdessen ein positiver (Action: delivered-)Bericht. Die Diagnose und der Empfänger werden dem state entnommen, den die routende Stage auf dem Datensatz hinterlassen hat. Das From: der DSN ist Mail Delivery Subsystem <POSTMASTER>, und POSTMASTER ist standardmäßig postmaster@SERVER_NAME. Die umgeschriebene DSN bleibt unsigniert; der Datensatz wird zum NEXT_STAGE der Stage weitergeschaltet, normalerweise pepsi-stage-dkim-sign(1), das sie (als Domain des Postmasters) DKIM-signiert, bevor eine Zustell-Stage wie pepsi-stage-relay-to-internet(1) sie weiterleitet.
Eine Nachricht, die bereits ein Bounce ist (sie hat den leeren Umschlagabsender), wird nicht umgeschrieben: Sie wird gelöscht und die Löschung protokolliert. Ein Bounce wird nie selbst gebounct (RFC 5321 §6.1).
Ein Bericht wird auch nicht an einen Umschlagabsender gesendet, den die eingehende Nachricht nicht authentifiziert hat: ein SPF-Pass für seine Domain oder ein ausgerichteter DKIM-Pass für ein From: an dieser Domain. Spam fälscht seinen Absender, sodass ein Bounce dafür bei einem unbeteiligten Dritten landet (Backscatter), und das bringt diesen Host auf Blocklisten. Eine solche Nachricht wird verworfen und geloggt. Mail, die unsere eigenen Benutzer eingeliefert haben, und Nachrichten, die eine Stage selbst erzeugt hat, werden immer gemeldet. BOUNCE_UNAUTHENTICATED = send schaltet die Prüfung ab.
DSN (RFC 3461): Ein Failure-Bounce wird nur erzeugt, wenn das NOTIFY des fehlgeschlagenen Empfängers FAILURE angefordert hat. Die NOTIFY/ORCPT/ENVID, an denen die Stage handelt, sind diejenigen, die die routende Zustell-Stage auf das state.bounce-Objekt kopiert hat (aus dem state.dsn-Eintrag des Empfängers). Der Standardwert — kein mitgeführtes NOTIFY — ist FAILURE, sodass gewöhnliche Mail weiterhin bounct; aber NOTIFY=NEVER (oder eine NOTIFY-Liste ohne FAILURE) bedeutet, dass der Absender keinen Fehlerbericht will, und die Nachricht wird dann ohne Bounce verworfen. Wenn das ursprüngliche ENVID und ORCPT angegeben waren, werden sie als Original-Envelope-Id und Original-Recipient in die DSN übernommen.
Ein Success-Bericht (kind = success) wird nur erzeugt, wenn der Empfänger ausdrücklich NOTIFY=SUCCESS angefordert hat (Success hat, anders als Failure, keinen impliziten Standardwert); die routende Stage gibt einen ausschließlich dann aus, wenn das globale [pepsi]-ORIGINATE_SUCCESS_DSN aktiviert ist. Ein Delay-Bericht (kind = delay, Action: delayed) wird nur erzeugt, wenn der Empfänger NOTIFY=DELAY angefordert hat; eine Zustell-Stage reiht hier eine Kopie einer noch nicht zugestellten Nachricht ein (siehe DELAY_DSN_AFTER in pepsi-stage-relay-to-internet(1)), während das Original weiterhin wiederholt wird. Sowohl success als auch delay haben keinen impliziten Standardwert.
Der menschenlesbare (text/plain-)Teil des Bounces ist standardmäßig ein eingebauter englischer Hinweis. Wenn die BOUNCE_MESSAGE-Option der Stage eine Vorlage benennt, wird dieser Teil stattdessen aus bounce-<NAME>.<lang>.body unter dem [pepsi]-TEMPLATE_DIR gerendert (eine Mustache-Vorlage; siehe pepsi.conf(5)). <lang> wird aus state.language in dessen q-Reihenfolge gewählt, mit Rückfall auf en: Der Bounce geht an den Absender der ursprünglichen Nachricht, und die Sprache, die pepsi-stage-detect-language(1) in der von ihm geschriebenen Nachricht gefunden hat, ist der beste verfügbare Anhaltspunkt dafür, was er liest. Das ist eine Näherung, und wo keine Erkennung lief (üblicherweise auf dem Submission-Pfad), ist der Hinweis englisch. Das gesamte Nachrichten-state ist der Rendering-Kontext — ergänzt um die Variablen der obersten Ebene server_name, postmaster, bounce_to, failed_recipient, diagnostic, action (failed/delayed/delivered) und die drei Wahrheitswerte failed / delayed / delivered —, sodass die von einer Zustell-Stage erfassten Detailangaben zum nächsten Hop (state.bounce.remote_mta / smtp_code / enhanced_status / phase / reply_text) den Bounce genau angeben lassen, warum der nächste MTA die Nachricht abgelehnt hat. Das Rendering erfolgt nach bestem Bemühen: Jeder Fehler fällt auf den eingebauten Text zurück, sodass immer ein Bounce erzeugt wird.
pepsi-stage-bounce führt keine Netzwerkzustellung durch und gibt keine Benachrichtigung aus; die umgeschriebene Nachricht wird von der Stage zugestellt, die NEXT_STAGE benennt.
85.1.9.1.4. Konfiguration¶
Die Optionen der Bounce-Stage (SERVER_NAME, POSTMASTER, die erforderliche NEXT_STAGE, die optionale BOUNCE_MESSAGE-Vorlage, RET_FULL_MAX_SIZE und BOUNCE_UNAUTHENTICATED) sind in pepsi.conf(5) dokumentiert.
85.1.9.1.5. Die Nachricht zurücksenden (RET)¶
Der dritte Teil der DSN zitiert die fehlgeschlagene Nachricht. Standardmäßig ist das ihr Header-Block, als text/rfc822-headers. Wenn der ursprüngliche Absender RET=FULL bei MAIL FROM gesetzt hat — von pepsi-ingress(1) festgehalten und auf state.bounce.ret zu dieser Stage getragen —, wird stattdessen die ganze Nachricht zurückgesendet, als message/rfc822, worum RFC 3461 §6.2 bittet.
Die Ausnahme ist die Größe. §6.2 erlaubt es, allein die Header zurückzusenden, wenn die Nachricht „eine implementierungsspezifische Größe überschreitet“; RET_FULL_MAX_SIZE ist diese Größe (Standardwert 256 KiB, gemessen über die gesamte gespeicherte Nachricht), oberhalb derer die DSN stillschweigend auf die Header-Form zurückfällt und protokolliert, dass sie es getan hat. Der Wert 0 schaltet die Grenze ab, sodass eine RET=FULL-Nachricht stets vollständig zurückgesandt wird. Der Nachrichtentext wird nur für eine Nachricht aus der Datenbank gelesen, die darum gebeten hat und hineinpasst, sodass ein gewöhnlicher Bounce weiterhin ein Laden nur der Header kostet.
85.1.9.1.6. State¶
Eingaben: state.bounce — der Berichtskontext, den die routende Stage auf dem Datensatz hinterlassen hat. Sein kind (permanent ⇒ ein Failure-Action: failed-Bericht, success ⇒ Action: delivered, delay ⇒ Action: delayed) wählt den Berichtstyp; diagnostic und failed_recipient werden darin zitiert; die optionalen notify/orcpt/envid entscheiden, ob der Bericht überhaupt ausgegeben wird und was übernommen wird; ret wählt, ob die ganze Nachricht oder nur ihre Header zurückgesendet werden (siehe oben); und die optionalen strukturierten Felder zum nächsten Hop remote_mta/smtp_code/enhanced_status/phase/reply_text (von den Relay-Stages geschrieben) werden der BOUNCE_MESSAGE-Vorlage und, für enhanced_status, dem DSN-Status:-Feld zugänglich gemacht. Eine von Hand eingereihte Nachricht ohne state.bounce ergibt einen generischen Fehlerhinweis.
Ausgaben: Die Stage schreibt die Nachricht an Ort und Stelle um und setzt ``state`` auf null — der Bounce ist eine neue Null-Absender-Nachricht, die keine der Herkunftsdaten des Originals erbt (dies ist die eine Stage, die state nicht bewahrt). Das State-Layout wird in pepsi.state(7) beschrieben.
Übergänge:
eine eingehende Nachricht, die selbst ein Bounce ist (Null-Absender) → abschließen (verworfen, nie erneut gebounct);
das
NOTIFYdes Empfängers fordert nicht den Bericht an, den dieseskindausgeben würde (Failure hat einen impliziten Standardwert;success/delaynicht) → abschließen (ohne DSN verworfen);andernfalls wird die Nachricht an Ort und Stelle in eine DSN umgeschrieben und zu NEXT_STAGE weitergeschaltet (das Signier-/Zustell-Ende).
Die Stage pausiert nie, schlägt nie fehl und leitet nie um.
85.1.9.1.7. Befehle¶
- worker
Läuft als persistenter pepsi-dispatch(1)-Worker, der Nachrichten-IDs von der Standardeingabe liest.
85.1.9.1.8. Globale Optionen¶
Diese globalen Optionen stehen vor dem Unterbefehl.
- -c FILE, –config FILE
Liest die Konfiguration aus FILE, statt die Standardorte zu durchsuchen.
- -L LOGLEVEL, –log LOGLEVEL
Setzt die Log-Ausführlichkeit (
error,warn,info,debugodertrace; Standardwertinfo).- -v, –verbose
Zeigt Log-Meldungen aus allen Quellen, einschließlich Drittanbieter-Bibliotheken.
- -h, –help
Gibt eine Verwendungsübersicht aus und beendet sich.
- -V, –version
Gibt die Version aus und beendet sich.
85.1.9.1.9. Exit-Status¶
Das Ergebnis jeder Nachricht wird pepsi-dispatch(1) auf der Statuszeile des Workers gemeldet, nicht als Exit-Status.
- 0
Der Worker lief, bis seine Standardeingabe geschlossen wurde.
- 1
Ein fataler Fehler ist aufgetreten (unlesbare Konfiguration, die Datenbank konnte nicht geöffnet werden, oder Standardein-/-ausgabe schlug fehl). Der Grund wird in das Journal geschrieben.
- 78
Der Abschnitt der Stage lässt sich nicht parsen oder nennt keine NEXT_STAGE: Der Worker verweigert den Start, und pepsi-dispatch(1) hält die Nachrichten der Stage zurück, bis die Konfiguration korrigiert ist.
85.1.9.1.10. Beispiele¶
Die Bounce-Stage von Hand auf Nachricht 42 ausführen (sie muss running sein):
echo 42 | pepsi-stage-bounce -c /etc/pepsi/pepsi.conf worker
85.1.9.1.11. Siehe auch¶
pepsi-config(1), pepsi.conf(5), pepsi.state(7), pepsi-stage-dkim-sign(1), pepsi-dispatch(1), pepsi-stage-relay-to-internet(1), pepsi-stage-relay-to-smarthost(1), pepsi-setup(1)
85.1.9.1.12. Fehler¶
Melden Sie Fehler an den Pepsi-Issue-Tracker.