85.1.9. pepsi-stage-bounce¶
rewrite a message into a delivery-status bounce
- Section du manuel:
1
85.1.9.1.1. Nom¶
pepsi-stage-bounce - l’étape de génération de rebonds du pipeline Pepsi.
85.1.9.1.2. Synopsis¶
pepsi-stage-bounce [GLOBAL-OPTIONS] worker
85.1.9.1.3. Description¶
pepsi-stage-bounce est un programme d’étape : il est exécuté par pepsi-dispatch(1) comme un worker persistant, lisant les identifiants de message sur l’entrée standard, chacun identifiant une ligne de la table pepsi.workqueue. Il charge cette ligne, refusant d’agir sauf si son status est running, et lit sa propre configuration depuis la section [stage-<stage>] du message (voir pepsi.conf(5)).
Il réécrit le message sur place en une notification d’état de remise (DSN) RFC 3464 : l’expéditeur d’enveloppe devient l’expéditeur nul (<>), le destinataire d’enveloppe devient l’expéditeur du message original, et le corps devient un multipart/report citant les en-têtes originaux.
« L’expéditeur du message original » est state.srs.original lorsque pepsi-stage-srs(1) en a noté un, et la colonne mail_from sinon. La distinction compte sur tout chemin de relais, car SRS s’exécute nécessairement avant l’étape de remise : au moment où un DSN est composé ici, l’expéditeur d’enveloppe est l’un de nos propres alias SRS, et adresser le rapport à celui-ci reviendrait à l’envoyer vers le saut suivant puis de nouveau vers l’intérieur par notre propre MX pour être décodé — en survivant à tout le pipeline entrant en tant que message à expéditeur nul — pour n’aboutir qu’à une adresse qui figurait depuis le début sur la ligne. SRS est un chemin de retour pour un rebond que le saut suivant génère ; un rapport que nous écrivons nous-mêmes n’a pas besoin d’un tel détour. Voir pepsi.state(7). Par défaut, c’est un rebond d”échec (Action: failed) ; lorsque l’étape d’acheminement étiquette state.bounce avec kind = success, c’est à la place un rapport positif (Action: delivered). Le diagnostic et le destinataire sont pris dans le state que l’étape d’acheminement a laissé sur la ligne. Le From: du DSN est Mail Delivery Subsystem <POSTMASTER>, et POSTMASTER vaut par défaut postmaster@SERVER_NAME. Le DSN réécrit est laissé non signé ; la ligne est avancée vers le NEXT_STAGE de l’étape, normalement pepsi-stage-dkim-sign(1), qui le signe en DKIM (en tant que domaine du postmaster) avant qu’une étape de remise telle que pepsi-stage-relay-to-internet(1) le relaie.
Un message qui est déjà un rebond (il porte l’expéditeur d’enveloppe nul) n’est pas réécrit : il est supprimé et la suppression est journalisée. Un rebond ne rebondit jamais lui-même (RFC 5321 §6.1).
Un rapport n’est pas non plus envoyé à un expéditeur d’enveloppe que le message entrant n’a pas authentifié : une réussite SPF pour son domaine, ou une réussite DKIM alignée pour un From: de ce domaine. Le spam falsifie son expéditeur, si bien qu’un rebond le concernant atterrit chez un tiers innocent (backscatter), ce qui vaut à cet hôte de finir sur une liste noire. Un tel message est supprimé et journalisé. Le courrier soumis par nos propres utilisateurs, et les messages qu’une étape a elle-même créés, font toujours l’objet d’un rapport. BOUNCE_UNAUTHENTICATED = send désactive ce contrôle.
DSN (RFC 3461) : un rebond d’échec n’est généré que lorsque le NOTIFY du destinataire en échec a demandé FAILURE. Les NOTIFY/ORCPT/ENVID sur lesquels l’étape agit sont ceux que l’étape de remise d’acheminement a copiés sur l’objet state.bounce (depuis l’entrée state.dsn du destinataire). La valeur par défaut — aucun NOTIFY porté — est FAILURE, de sorte que le courrier ordinaire rebondit tout de même ; mais NOTIFY=NEVER (ou une liste NOTIFY sans FAILURE) signifie que l’expéditeur ne veut pas de rapport d’échec, et le message est alors abandonné sans rebond. Lorsque les ENVID et ORCPT originaux ont été fournis, ils sont renvoyés en écho dans le DSN sous Original-Envelope-Id et Original-Recipient.
Un rapport de succès (kind = success) n’est généré que lorsque le destinataire a explicitement demandé NOTIFY=SUCCESS (le succès, contrairement à l’échec, n’a pas de valeur par défaut implicite) ; l’étape d’acheminement n’en émet un que lorsque le ORIGINATE_SUCCESS_DSN global [pepsi] est activé. Un rapport de délai (kind = delay, Action: delayed) n’est généré que lorsque le destinataire a demandé NOTIFY=DELAY ; une étape de remise met en file une copie d’un message encore non remis ici (voir DELAY_DSN_AFTER dans pepsi-stage-relay-to-internet(1)) tandis que l’original continue d’être réessayé. Le success et le delay n’ont tous deux aucune valeur par défaut implicite.
La partie lisible par un humain (text/plain) du rebond est, par défaut, un avis intégré en anglais. Lorsque l’option BOUNCE_MESSAGE de l’étape nomme un modèle, cette partie est à la place rendue depuis bounce-<NAME>.<lang>.body sous le TEMPLATE_DIR [pepsi] (un modèle Mustache ; voir pepsi.conf(5)). <lang> est choisi d’après state.language dans son ordre q, avec repli sur en : le rebond part vers l’expéditeur du message d’origine, et la langue que pepsi-stage-detect-language(1) a trouvée dans le message qu’il a écrit est la meilleure indication disponible de ce qu’il lit. C’est une approximation, et là où aucune détection n’a eu lieu (couramment sur le chemin de soumission) l’avis est en anglais. Tout le state du message est le contexte de rendu — augmenté des variables de premier niveau server_name, postmaster, bounce_to, failed_recipient, diagnostic, action (failed/delayed/delivered) et des trois booléens failed / delayed / delivered — de sorte que le détail du saut suivant capturé par une étape de remise (state.bounce.remote_mta / smtp_code / enhanced_status / phase / reply_text) permet au rebond d’énoncer précisément pourquoi le MTA suivant a refusé le message. Le rendu se fait au mieux : tout échec retombe sur le texte intégré, de sorte qu’un rebond est toujours produit.
pepsi-stage-bounce n’effectue aucune remise réseau et n’émet aucune notification ; le message réécrit est remis par l’étape que nomme NEXT_STAGE.
85.1.9.1.4. Configuration¶
Les options de l’étape de rebond (SERVER_NAME, POSTMASTER, le NEXT_STAGE obligatoire, le modèle BOUNCE_MESSAGE facultatif, RET_FULL_MAX_SIZE et BOUNCE_UNAUTHENTICATED) sont documentées dans pepsi.conf(5).
85.1.9.1.5. Renvoyer le message (RET)¶
La troisième partie du DSN cite le message qui a échoué. Par défaut il s’agit de son bloc d’en-têtes, en text/rfc822-headers. Lorsque l’expéditeur d’origine a posé RET=FULL sur MAIL FROM — noté par pepsi-ingress(1) et transporté jusqu’à cette étape dans state.bounce.ret — c’est le message entier qui est renvoyé à la place, en message/rfc822, ce que demande la RFC 3461 §6.2.
L’exception est la taille. La §6.2 permet de ne renvoyer que les en-têtes lorsque le message « dépasse une taille définie par l’implémentation » ; RET_FULL_MAX_SIZE est cette taille (par défaut 256 Kio, mesurée sur l’ensemble du message stocké), au-delà de laquelle le DSN retombe silencieusement sur la forme en-têtes et le journalise. La valeur 0 désactive la limite, de sorte qu’un message RET=FULL est toujours renvoyé en entier. Le corps n’est lu depuis la base de données que pour un message qui l’a demandé et qui tient dans la limite, de sorte qu’un rebond ordinaire ne coûte toujours qu’un chargement des seuls en-têtes.
85.1.9.1.6. État¶
Entrées : state.bounce — le contexte de rapport que l’étape d’acheminement a laissé sur la ligne. Son kind (permanent ⇒ un rapport d’échec Action: failed, success ⇒ Action: delivered, delay ⇒ Action: delayed) sélectionne le type de rapport ; diagnostic et failed_recipient y sont cités ; les notify/orcpt/envid facultatifs décident si le rapport est émis ou non et ce qui est renvoyé en écho ; ret détermine si le message entier ou seulement ses en-têtes est renvoyé (voir ci-dessus) ; et les champs structurés facultatifs du saut suivant remote_mta/smtp_code/enhanced_status/phase/reply_text (écrits par les étapes de relais) sont exposés au modèle BOUNCE_MESSAGE et, pour enhanced_status, dans le champ Status: du DSN. Un message amené à la main à cette étape sans state.bounce produit un avis d’échec générique.
Sorties : l’étape réécrit le message sur place et remet ``state`` à null — le rebond est un nouveau message à expéditeur nul qui n’hérite d’aucune provenance de l’original (c’est la seule étape qui ne préserve pas state). La disposition de l’état est décrite dans pepsi.state(7).
Transitions :
un message entrant qui est lui-même un rebond (expéditeur nul) → terminer (abandonné, jamais renvoyé en rebond) ;
le
NOTIFYdu destinataire ne demande pas le rapport que cekindémettrait (l’échec a une valeur par défaut implicite ;success/delaynon) → terminer (abandonné sans DSN) ;sinon le message est réécrit sur place en un DSN et avancé vers NEXT_STAGE (la fin de chaîne signature/remise).
L’étape ne met jamais en pause, n’échoue ni ne réachemine.
85.1.9.1.7. Commandes¶
- worker
Exécuté comme un worker persistant de pepsi-dispatch(1), lisant les identifiants de message sur l’entrée standard.
85.1.9.1.8. Options globales¶
Ces options globales précèdent la sous-commande.
- -c FILE, –config FILE
Lit la configuration depuis FILE au lieu de parcourir les emplacements par défaut.
- -L LOGLEVEL, –log LOGLEVEL
Règle la verbosité de journalisation (
error,warn,info,debugoutrace; par défautinfo).- -v, –verbose
Affiche les messages de journal de toutes les sources, y compris les bibliothèques tierces.
- -h, –help
Affiche un résumé d’utilisation et quitte.
- -V, –version
Affiche la version et quitte.
85.1.9.1.9. Code de sortie¶
Le résultat de chaque message est rapporté à pepsi-dispatch(1) sur la ligne de statut du worker, et non par le code de sortie.
- 0
Le worker s’est exécuté jusqu’à la fermeture de son entrée standard.
- 1
Une erreur fatale s’est produite (configuration illisible, base de données impossible à ouvrir, ou échec de l’entrée/sortie standard). La raison est écrite dans le journal.
- 78
La section de l’étape ne s’analyse pas, ou ne nomme aucun NEXT_STAGE : le worker refuse de démarrer, et pepsi-dispatch(1) retient les messages de l’étape jusqu’à ce que la configuration soit corrigée.
85.1.9.1.10. Exemples¶
Exécuter l’étape de rebond sur le message 42 à la main (il doit être running)
echo 42 | pepsi-stage-bounce -c /etc/pepsi/pepsi.conf worker
85.1.9.1.11. Voir aussi¶
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. Bogues¶
Signalez les bogues au gestionnaire de tickets de Pepsi.