85.1.23. pepsi-stage-list-bounce

score an inbound bounce against the member it names

Section du manuel:

1

85.1.23.1.1. Nom

pepsi-stage-list-bounce - l’étape de traitement des rejets de listes de diffusion du pipeline Pepsi.

85.1.23.1.2. Synopsis

pepsi-stage-list-bounce [GLOBAL-OPTIONS] worker

85.1.23.1.3. Description

pepsi-stage-list-bounce est un programme d’étape exécuté par pepsi-dispatch(1). Il consomme les rejets : un échec de remise revenu à l’adresse -bounces d’une liste est attribué au membre qu’il concerne et comptabilisé, et — dès que le score franchit le seuil de la liste — la remise est désactivée pour ce membre, celui-ci est averti, puis finalement désabonné.

Trois choses portent le nom de « bounce » dans cet arbre et ce ne sont pas les mêmes. Celle-ci lit un rapport d’échec entrant. pepsi-stage-bounce(1) génère un DSN pour un message que Pepsi lui-même n’a pas pu remettre. pepsi-failure-bouncer(1) récupère les messages sur lesquels le pipeline a renoncé et les confie à ce générateur. Une configuration qui pointe le NEXT_STAGE de cette étape vers le générateur répond à un rejet par un rejet ; pepsi-setup(1) la refuse.

On arrive à cette étape depuis pepsi-stage-list(1), le routeur, qui y envoie un message lorsque son destinataire d’enveloppe est l’adresse -bounces d’une liste. On n’y arrive jamais autrement : un message qui arrive ici sans le descripteur state.list du routeur échoue.

85.1.23.1.4. Attribution

Quatre étapes, par certitude décroissante. Les deux premières sont exactes, parce que c’est Pepsi qui a écrit l’adresse qu’elles lisent.

  1. L’enveloppe VERP. Chaque copie qu’une liste envoie porte l’expéditeur d’enveloppe <list>-bounces+<local>=<domain>@<host> ; un rejet de cette copie nomme donc le membre sans ambiguïté. La partie <list>-bounces doit correspondre à la boîte de rejets propre à cette liste avant que l’adresse soit crue : sans ce contrôle, n’importe qui pourrait faire comptabiliser un rejet contre n’importe quel membre de n’importe quelle liste en écrivant à une adresse inventée.

    Une correspondance VERP doit encore ressembler à un échec. Un échec temporaire est ignoré d’emblée, et un message VERP sans aucun échec reconnu est transféré et non comptabilisé — ce peut être une réponse d’absence ou le rapport d’un antivirus, arrivé à cette adresse au seul motif que c’est ce qui figurait sur l’enveloppe.

  2. Un jeton de sonde (<list>-bounces+<token>@<host>), lorsque BOUNCE_PROBES est actif. Voir Sondes.

  3. Les détecteurs heuristiques, sur tout le message. Voir Formats de rejet reconnus.

  4. Rien n’a pu être établi, auquel cas le rejet est emballé et transféré à un humain — voir Rejets non reconnus.

85.1.23.1.5. Comptabilisation

La logique est celle de GNU Mailman 3, reproduite pas à pas, parce que chaque attribut qu’elle lit est visible par l’API REST et que la documentation d’un serveur explique ce que chacun fait.

  1. la liste n’existe plus — abandon

  2. l’adresse n’est pas membre — abandon

  3. le rejet est une sonde — désactivation immédiate, sans comptabiliser ; un rejet de sonde est décisif

  4. le membre est déjà désactivé pour cause de rejets — rejet résiduel ; abandon

  5. un rejet a déjà été comptabilisé pour ce membre aujourd’hui — seul l’horodatage est mis à jour. Au plus une incrémentation par jour civil.

  6. aucun rejet antérieur, ou un rejet plus ancien que bounce_info_stale_after — le score est remis à 1 ; sinon il est incrémenté de un

  7. si bounce_notify_owner_on_bounce_increment est posé et (le score est sous le seuil ou les sondes sont désactivées) — les propriétaires sont informés

  8. à bounce_score_threshold ou au-delà : une sonde est envoyée si BOUNCE_PROBES est actif (ce qui remet le score à zéro), sinon le score est mis à zéro et la remise désactivée

  9. l’événement est marqué comme traité

L’étape 5 est la raison pour laquelle une tempête de rejets ne peut pas vider une liste en un après-midi : avec le seuil par défaut de 5, il faut à un membre des échecs sur cinq jours différents.

85.1.23.1.6. Avertissement et retrait

Désactiver un membre n’est pas le désabonner. Deux passes périodiques, exécutées par pepsi-list tasks --once (voir pepsi-list(1)), achèvent l’histoire :

  • avertir — un membre désactivé pour cause de rejets ayant reçu moins de bounce_you_are_disabled_warnings avertissements, et dont le dernier avertissement remonte à au moins bounce_you_are_disabled_warnings_interval, en reçoit un ;

  • retirer — une fois les avertissements épuisés et l’intervalle de nouveau écoulé, le membre est désabonné, et les propriétaires sont informés si bounce_notify_owner_on_removal est posé.

Un membre qui s’est désactivé lui-même ou qu’un modérateur a désactivé n’est touché par aucune des deux passes.

Mettre bounce_you_are_disabled_warnings à zéro retire un membre désactivé à la passe suivante sans aucun courrier d’avertissement. C’est le comportement documenté d’amont, et il est délibéré, non un cas limite.

Les notifications que ces passes envoient sont injectées à [pepsi-list] NOTICE_STAGE, parce que les passes tournent depuis une minuterie et non depuis une étape. pepsi-setup(1) refuse une configuration qui fait tourner cette étape sans elle : sans étape où injecter, un membre serait averti trois fois dans la base et pas une seule par courrier.

85.1.23.1.7. Sondes

Avec [pepsi-list] BOUNCE_PROBES = yes, franchir le seuil envoie au membre une sonde au lieu de le désactiver : un message adressé à lui seul, depuis un expéditeur d’enveloppe portant un jeton à usage unique, avec le rejet déclencheur en pièce jointe. Le score du membre est remis à zéro tant que la sonde est en cours. Si la sonde est rejetée, le jeton l’identifie exactement et la remise est désactivée aussitôt ; si elle ne l’est pas, rien ne se passe et il continue de recevoir du courrier.

Les sondes sont désactivées par défaut, comme chez amont. Le compromis : un message de plus vers une adresse probablement morte, contre le fait de ne pas désactiver un membre dont le fournisseur a eu un mauvais après-midi. Un jeton de sonde vaut dix jours et ne porte aucun en-tête Precedence: bulk — une sonde existe pour être rejetée, et cet en-tête invite certains systèmes à ne pas la rejeter.

85.1.23.1.8. Rejets non reconnus

Un rejet que rien n’a reconnu est emballé dans une notification explicative, l’original joint tel quel en message/rfc822, et envoyé à qui le forward_unrecognized_bounces_to de la liste désigne : administrators (par défaut), site_owner ou discard.

C’est une fonctionnalité et non un recours. Chaque rejet qui passe à travers est un format que le corpus n’a pas, et celui qui le reçoit peut envoyer l’échantillon aux mainteneurs de Pepsi afin que le détecteur soit écrit. Sous chaque disposition — discard compris — ce passage à travers est compté dans pepsi.event_log sous list.bounce.unrecognized, car sa fréquence est ce qui dit si un serveur a besoin de détecteurs supplémentaires.

85.1.23.1.9. Formats de rejet reconnus

Dix-sept détecteurs, essayés dans cet ordre, le premier qui correspond l’emportant. Ils sont portés depuis flufl.bounce (Apache-2.0, copyright Barry Warsaw), et chacun est testé contre les données de test de cette bibliothèque :

dsn, exim, sina, yahoo, yale, smtp32, postfix, qmail, groupwise, microsoft, caiwireless, exchange, netscape, aol, simplematch, simplewarning, llnl

Un seul d’entre eux — dsn, la RFC 3464 — est une norme ; les autres nomment un éditeur ou un site. En pratique, ils comptent bien moins ici qu’en amont : Pepsi applique VERP à chaque copie de chaque message, de sorte qu’un rejet d’un message envoyé par Pepsi est attribué par son enveloppe sans que rien de tout cela soit consulté. Les détecteurs sont ce qui lit un rejet parvenu à une liste par un autre chemin.

Un message qu’aucun détecteur ne reconnaît n’est pas un rejet du point de vue de cette étape, et il est transféré plutôt que deviné. La distinction vaut d’être connue à la lecture d’un journal : « Pepsi ne l’a pas reconnu » et « Pepsi a décidé que ce n’était pas un échec » sont deux phrases différentes.

85.1.23.1.10. Configuration

[stage-list-bounce]

PROGRAM

pepsi-stage-list-bounce.

NEXT_STAGE (obligatoire)

Où va un rejet non reconnu une fois emballé pour un humain : la remise ordinaire, pas une étape de liste. pepsi-setup(1) refuse une valeur qui désigne pepsi-stage-bounce(1) ou le routeur de listes.

RESPONSE_STAGE (obligatoire)

Où la sonde destinée au membre et les notifications aux propriétaires sont injectées — la queue de signature, pas l’étape de remise des listes. Cette étape n’accepte que la copie d’un membre issue de l’éclatement et fait échouer tout le reste, si bien qu’une notification envoyée là ne part jamais ; pepsi-setup(1) refuse la mauvaise valeur.

[pepsi-list]

NOTICE_STAGE

Où les passes périodiques d’avertissement et de retrait injectent leurs notifications. Obligatoire dès que cette étape existe.

BOUNCE_PROBES

yes ou no (par défaut no). Voir Sondes.

BOUNCE_EVENT_RETENTION

Durée de conservation d’une ligne d’événement de rejet traitée, en jours (par défaut 1). Une fois comptabilisées, les lignes n’ont plus qu’un intérêt de diagnostic. Ce n’est pas la décroissance du score — celle-ci est l’attribut par liste bounce_info_stale_after, et elle est appliquée paresseusement plutôt que par une passe nocturne.

Les neuf attributs par liste — process_bounces, bounce_score_threshold, bounce_info_stale_after, bounce_notify_owner_on_bounce_increment, bounce_notify_owner_on_disable, bounce_notify_owner_on_removal, bounce_you_are_disabled_warnings, bounce_you_are_disabled_warnings_interval et forward_unrecognized_bounces_to — résident dans la base de données, où l’API REST peut les voir. Positionnez-les avec pepsi-list list set.

85.1.23.1.11. Différences avec GNU Mailman 3

  • La comptabilisation est synchrone. Amont enregistre un événement de rejet et le comptabilise lors d’une passe ultérieure ; Pepsi le comptabilise dans la transaction qui l’enregistre. La règle « au plus une incrémentation par jour civil » est ce qui rend inoffensifs deux rejets simultanés pour un même membre.

  • L’historique des rejets d’un site migré n’est pas repris. L’importateur d’amont ne le lit pas non plus, de sorte qu’un membre migré part d’un score nul et qu’une adresse morte depuis longtemps reçoit une tentative de remise de plus.

85.1.23.1.12. Code de sortie

Le worker ne se termine avec un code non nul que lorsqu’il ne peut pas s’exécuter du tout. Un rebond qu’il ne parvient pas à interpréter est transmis, non mis en échec ; un rebond pour une liste qui n’existe plus, ou que l’analyseur MIME refuse, est abandonné avec une ligne de journal (il est arrivé à l’adresse -bounces propre à la liste, et y répondre est la façon dont naissent les boucles). Toute autre erreur est réessayée avec un back-off jusqu’à MAX_LIFETIME (voir pepsi-dispatch(1)).

Lorsqu’un rebond nomme plusieurs membres, les avis au propriétaire de chaque membre portent une étiquette dérivée de l’adresse du membre ainsi que de la position du propriétaire, de sorte que l’avis de chaque membre est envoyé, et non seulement le premier.

85.1.23.1.13. Voir aussi

pepsi-stage-list(1), pepsi-stage-list-post(1), pepsi-stage-list-command(1), pepsi-stage-list-deliver(1), pepsi-list(1), pepsi-stage-bounce(1), pepsi-failure-bouncer(1), pepsi-dispatch(1), pepsi.conf(5).