85.1.32. pepsi-stage-secretary¶
hold mail from unknown senders until they confirm by replying
- Section du manuel:
1
85.1.32.1.1. Nom¶
pepsi-stage-secretary - l’étape de confirmation à l’envoi du pipeline Pepsi.
85.1.32.1.2. Synopsis¶
pepsi-stage-secretary [GLOBAL-OPTIONS] worker
85.1.32.1.3. Description¶
pepsi-stage-secretary est un programme d’étape exécuté par pepsi-dispatch(1) comme un worker persistant lisant les identifiants de message sur l’entrée standard. Il met en œuvre la confirmation à l’envoi, à la manière du qsecretary de qmail : le courrier d’un expéditeur qu’aucune liste blanche ne connaît est retenu, et l’expéditeur est prié — dans sa langue — de confirmer en répondant. La réponse ajoute l’expéditeur à la liste blanche et libère chaque message retenu pour lui ; son courrier ultérieur est reconnu par pepsi-stage-check-whitelist(1) en amont de cette étape et n’est plus jamais retenu.
Faute de réponse avant HOLD_TIME, le courrier retenu prend le chemin d’expiration : il est réacheminé vers BOUNCE_STAGE lorsqu’une telle étape est branchée (un DSN, une quarantaine, une suppression — au choix de l’opérateur), et supprimé sinon.
Le bloc d’en-têtes est chargé, le corps jamais : un défi ne cite rien du message retenu, hormis un bref aperçu de son sujet.
85.1.32.1.4. Ce qu’elle arrête et ce qu’elle n’arrête pas¶
La confirmation à l’envoi est plus faible que le péage à l’envoi (pepsi-stage-anti-spam(1)). Un spammeur disposant d’une boîte aux lettres fonctionnelle peut automatiser la réponse, et la déclaration à laquelle l’expéditeur consent (PENALTY) est un moyen de dissuasion juridique, non économique. Elle reste utile : la plupart du courrier de masse provient d’adresses qui ne peuvent pas recevoir, et elle coûte à un correspondant légitime une réponse, une seule fois. Les deux se combinent — voir UNCHALLENGEABLE_STAGE.
85.1.32.1.5. Par message¶
L’étape décide dans cet ordre :
Une réponse à un défi. Un destinataire est l’adresse de réponse
<CONTROL_LOCAL_PART>-<cookie>@<domain>, où<cookie>fait 32 chiffres hexadécimaux et<domain>est l’un des LOCAL_DOMAINS (par défaut[pepsi-ingress] ACCEPTED_DOMAINS). Une ligne qui mêle adresses de réponse et destinataires ordinaires est d’abord scindée, les deux moitiés revenant à cette étape. Ensuite :une réponse à expéditeur nul signifie que le défi a rebondi : son adresse ne peut pas recevoir, de sorte que les messages retenus sont réveillés et prennent le chemin d’expiration immédiatement plutôt qu’après HOLD_TIME ;
une réponse marquée comme automatique —
Auto-Submitted:autre queno,Precedence: bulk|list|junk, unX-Auto-Response-Suppress:couvrant les réponses automatiques, un corpsmultipart/report— est ignorée : un répondeur d’absence qui répond auFrom:plutôt qu’à l’expéditeur d’enveloppe nul ne doit pas consentir au nom de son propriétaire ;toute autre réponse confirme, pourvu que son expéditeur d’enveloppe ou l’addr-spec de son
From:soit l’adresse ayant reçu le défi. L’expéditeur est ajouté à la liste blanche, chaque message retenu pour le défi est libéré, et le défi est supprimé. Une réponse à un cookie inconnu ou expiré, ou venant de quelqu’un d’autre, est journalisée et ne change rien.
La réponse elle-même est consommée (supprimée) dans tous les cas.
Un message à expéditeur nul (un rebond) et le courrier soumis localement (
state.local_origin) passent vers NEXT_STAGE.state.spam = false(un expéditeur en liste blanche) passe ; un message libéré par une confirmation passe aussi, en recevantstate.spam = falsepour qu’une étape de péage à l’envoi en aval soit d’accord.state.spam = trueprend aussitôt le chemin d’expiration.Un message retenu qui se réveille : abandonné (son défi a rebondi) ou au-delà de son échéance → le chemin d’expiration, le défi étant supprimé avec le dernier message qu’il retenait ; réveillé trop tôt → remis en pause jusqu’à l’échéance.
Première rencontre. Les destinataires sont regroupés selon la liste blanche vers laquelle WHITELIST_NAME se développe pour chacun (un modèle
{login}/{localpart}peut nommer une liste différente par destinataire), et un message dont les destinataires relèvent de plusieurs groupes est éclaté en une ligne par groupe. Le message est alors non soumis au défi, et va vers UNCHALLENGEABLE_STAGE, lorsque :une règle de la RFC 3834 dit qu’il ne faut pas y répondre (les mêmes règles que celles qu’applique pepsi-stage-vacation(1) : courrier de liste de diffusion,
Precedence: bulk,Auto-Submitted:, expéditeurs de service commenoreply@, rapports de remise) ;l’expéditeur est aussi l’un des destinataires ;
From:ne nomme pas exactement une boîte aux lettres, ou son addr-spec n’est pas l’expéditeur d’enveloppe — le défi part vers MAIL FROM et la liste blanche compareFrom:, les deux doivent donc être une seule et même adresse ;REQUIRE_AUTHENTICATED est activé et ni
state.auth.spfnistate.auth.dmarcne vautpass;l’expéditeur a reçu MAX_CHALLENGES_PER_SENDER défis au cours des dernières 24 heures, toutes listes blanches confondues ;
WHITELIST_NAME ne se développe pas pour les destinataires (un modèle
{login}et un destinataire sans compte), ou il n’y a aucun domaine servi où placer l’adresse de réponse.
Sinon, le message rejoint le défi ouvert pour sa paire (liste blanche, expéditeur), ou en ouvre un et envoie le défi, puis il est mis en pause jusqu’à l’expiration du défi. Un message qui rejoint un défi existant hérite de son expiration, non d’un nouveau HOLD_TIME ; seul le message qui a ouvert un défi en envoie un.
Une ligne retenue note state.secretary : challenge (le cookie), deadline (secondes depuis l’epoch) et whitelist, puis confirmed ou abandoned ; le courrier envoyé vers UNCHALLENGEABLE_STAGE porte state.secretary.unchallengeable (la raison). Le chemin d’expiration retire entièrement state.secretary. Voir pepsi.state(7).
85.1.32.1.6. Le défi¶
Le défi est un message text/plain injecté à RESPONSE_STAGE, où il est signé et relayé comme tout courrier sortant. Il a l”expéditeur d’enveloppe nul et Auto-Submitted: auto-replied (RFC 3834), de sorte qu’un pair conforme — y compris un autre secrétaire Pepsi — n’y répond jamais. Il est adressé (To:) à l’expéditeur d’enveloppe ; From: est l’adresse de réponse, affichée avec l’adresse du destinataire protégé comme nom d’affichage, et Reply-To: la répète, de sorte que la fonction Répondre de n’importe quel client de messagerie l’atteint. Il s’insère dans le fil du message retenu via In-Reply-To:/References: et porte Content-Language:.
Il ne cite jamais le corps ni les pièces jointes du message retenu : un défi part vers une adresse qui, pour du spam, est généralement falsifiée, de sorte que tout ce qu’il citerait serait remis par nous à un inconnu.
85.1.32.1.6.1. Le texte¶
Par langue, de la plus haute priorité à la plus basse :
MESSAGE_<LANG>dans la section propre de l’étape — redéfinissable par adresse, donc le texte propre d’un utilisateur via pepsi-settings(1) ou pepsi-stage-edit-settings(1) ;<TEMPLATE>.<lang>.bodysous[pepsi] TEMPLATE_DIR(par défautsecretary-challenge.<lang>.body).
La première source l’emporte par langue, et non globalement : le MESSAGE_EN d’un utilisateur ne supplante pas le modèle allemand livré pour un expéditeur germanophone. La langue est choisie comme pepsi-stage-vacation(1) la choisit : state.language par confiance décroissante, puis DEFAULT_LANGUAGE, chacune par étiquette exacte, sous-étiquette primaire ou étiquette de région affinante. Les mêmes règles s’y appliquent : deux espaces dans un texte deviennent un saut de ligne, et les champs ci-dessous sont rendus tels quels quel que soit le style d’accolades employé.
Le sujet est SUBJECT_<LANG> pour la langue dans laquelle le texte a été choisi, sinon SUBJECT ; c’est aussi un texte Mustache. Si rien ne se rend (aucun texte pour la langue ni pour la langue par défaut, ou un modèle qui ne compile pas), le texte anglais intégré est envoyé et un avertissement journalisé — un défi qui n’est pas envoyé coûte son message à l’expéditeur.
85.1.32.1.6.2. Champs¶
{{SENDER_NAME}}Le nom d’affichage du
From:de l’expéditeur, ou son adresse.{{RECIPIENT}}Le ou les destinataires d’enveloppe du message retenu, séparés par des virgules.
{{SUBJECT_HINT}}Le sujet du message retenu, décodé selon la RFC 2047 et tronqué à SUBJECT_HINT_LENGTH caractères (avec
…en cas de troncature) — assez pour qu’un correspondant reconnaisse son courrier, trop peu pour transporter une charge utile. Absent pour un sujet vide ou une longueur de 0.{{ORIGINAL_DATE}}Le
Date:du message retenu — absent lorsqu’il n’en a pas.{{DEADLINE}}Le moment où le défi expire, sous la forme
YYYY-MM-DD HH:MM UTC.{{REPLY_ADDRESS}}L’adresse de réponse.
{{PENALTY}}La PENALTY configurée — absente lorsqu’il n’y en a pas, de sorte qu’un modèle omet la phrase avec
{{#PENALTY}}…{{/PENALTY}}.
85.1.32.1.6.3. L’avis de confirmation¶
Avec CONFIRM_NOTICE activé, un expéditeur confirmé est aussi informé que son courrier a été remis : un avis à expéditeur nul provenant de <CONTROL_LOCAL_PART>@<domain>, dont le texte provient de CONFIRM_MESSAGE_<LANG> ou de secretary-confirmed.<lang>.body (avec un repli anglais intégré) et dont le sujet est fixe.
85.1.32.1.8. Options¶
Toutes ces options sont redéfinissables par adresse.
- NEXT_STAGE
Là où va le courrier qui passe, en liste blanche ou confirmé. Obligatoire.
- RESPONSE_STAGE
Étape à laquelle le défi (et l’avis de confirmation) est injecté, afin qu’il soit signé et relayé. Obligatoire.
- BOUNCE_STAGE
Le chemin d’expiration. S’il n’est pas défini, le courrier expiré est supprimé. Un défi resté sans réponse signifie en général un expéditeur falsifié, de sorte qu’un DSN ici est une seconde dose de backscatter ; l’assistant de pepsi-setup(1) le laisse non défini.
- UNCHALLENGEABLE_STAGE
Là où va le courrier qui ne doit pas être soumis au défi (voir ci-dessus). S’il n’est pas défini, ce courrier prend le chemin d’expiration. Pointez-le vers une étape pepsi-stage-anti-spam(1) pour demander plutôt à ces expéditeurs de payer, vers NEXT_STAGE pour le remettre, ou vers un filtre anti-spam.
- WHITELIST_NAME
L’unique liste blanche à laquelle un expéditeur confirmé est ajouté ; peut être un modèle
{login}/{localpart}développé par destinataire, exactement comme dans pepsi-stage-check-whitelist(1). Obligatoire. Une étape check-whitelist placée en amont de celle-ci doit la consulter, faute de quoi un expéditeur confirmé reçoit un nouveau défi à chaque message (pepsi-setup(1) avertit).Chaque inconnu qui répond à un défi est inscrit dans cette liste, de sorte qu’un propriétaire de compte ne peut la faire pointer que vers son propre espace de noms : une valeur qu’il définit par courrier via pepsi-stage-edit-settings(1) doit se développer, pour son adresse, en un nom
<login>/...du compte auquel cette adresse se résout ({login}/friends, par exemple), ou être la whitelist que la configuration de l’opérateur nomme déjà pour lui. Un nom global, la liste d’un autre utilisateur, ou toute valeur pour une adresse qui ne correspond à aucun compte local y est refusé, et rien ne change.L’opérateur peut nommer n’importe quelle whitelist, y compris une whitelist partagée, dans le fichier INI, dans
pepsi.config_overrideà n’importe quelle portée (globale,domain:,address:) et dans une lignepepsi.settingsécrite avec pepsi-settings(1). L’étape utilise la valeur effective telle qu’elle la trouve.- CONTROL_LOCAL_PART
La partie locale par laquelle commencent les adresses de réponse. Par défaut
secretary. Au plus 30 lettres ASCII, chiffres,.,_ou-.- HOLD_TIME
Durée pendant laquelle un message retenu attend son expéditeur. Par défaut
120 h. Utilisez les unitésh/m/s.- REQUIRE_AUTHENTICATED
N’envoyer de défi qu’à un expéditeur dont le domaine a réussi SPF ou DMARC. Par défaut
yes: c’est la barrière contre le backscatter.- MAX_CHALLENGES_PER_SENDER
Nombre de défis qu’une adresse peut recevoir par 24 heures, toutes listes blanches confondues. Par défaut
5;0signifie sans limite. Un défi qui rebondit compte quand même.- DKIM_REQUIRED
auto(par défaut),yesouno: ledkim_requiredde la ligne de liste blanche écrite pour un expéditeur confirmé.autoreflète le courrier retenu — exigé si l’un des messages retenus pour le défi a réussi DKIM (ou ARC conjointement avec DMARC).- CONFIRM_NOTICE
Informer un expéditeur confirmé que son courrier a été remis. Par défaut
no.- PENALTY
Texte libre nommant ce que l’expéditeur accepte de payer si son message n’était pas sollicité (par exemple
EUR:50). Non défini par défaut.- SUBJECT_HINT_LENGTH
Nombre de caractères du sujet retenu cités dans le défi. Par défaut
8;0omet l’aperçu ; au plus64.- TEMPLATE
Nom de base des fichiers de modèle du défi. Par défaut
secretary-challenge.- SUBJECT
Sujet du défi lorsqu’aucun
SUBJECT_<LANG>ne convient. Par défautPlease confirm your message to {{RECIPIENT}}.- DEFAULT_LANGUAGE
Langue utilisée lorsqu’aucune des langues détectées de l’expéditeur n’a de texte. Par défaut
en; pepsi-setup(1) exige un texte pour elle.- MESSAGE_<LANG>, SUBJECT_<LANG>, CONFIRM_MESSAGE_<LANG>
Redéfinitions par langue du texte du défi, de son sujet et du texte de confirmation.
- LOCAL_DOMAINS, TARGETS, RECIPIENT_DELIMITER
Les options de localité partagées : à quels domaines une adresse de réponse peut se trouver, et comment
{login}/{localpart}se développent.
85.1.32.1.9. Placement¶
Sur le chemin entrant :
après pepsi-stage-detect-language(1), afin que le défi soit dans la langue de l’expéditeur ;
après pepsi-stage-check-whitelist(1), dont le
state.spam = falseest ce qui laisse passer un expéditeur connu — cette étape n’interroge jamais elle-même la liste blanche ;avant pepsi-stage-aliases(1), le routeur de listes et la remise locale, dont aucun ne doit voir une adresse de réponse en premier (un attrape-tout
@domainou un RECIPIENT_DELIMITER-la réécrirait).
Le chemin sortant devrait exécuter pepsi-stage-auto-whitelist(1) vers le même WHITELIST_NAME, afin que les personnes auxquelles vos utilisateurs écrivent ne reçoivent jamais de défi lorsqu’elles répondent. Les milters anti-spam restent par défaut en amont de check-whitelist ; la section « Filtres anti-spam et secrétaire » du manuel décrit comment les placer derrière cette étape.
85.1.32.1.10. Base de données¶
Deux tables. pepsi.secretary_challenge contient un défi ouvert par paire (liste blanche, expéditeur) : le cookie, l’expiration et le fait qu’un message retenu ait ou non réussi DKIM. pepsi.secretary_sent note qu’un défi a été envoyé, sans son cookie, pour le plafond sur 24 heures — tenue à part afin qu’un défi qui reçoit une réponse, rebondit ou expire ne rende pas son quota à l’expéditeur. Quatre fonctions font le travail, en une instruction chacune : secretary_challenge_claim() (sûre face aux concurrences : deux workers revendiquant une même paire ouvrent un seul défi), secretary_confirm(), secretary_abandon() et secretary_expire(). Les lignes expirées sont balayées à mesure que de nouveaux défis sont revendiqués ; il n’y a aucune tâche cron à exécuter.
85.1.32.1.11. Sous-commandes¶
- worker
Exécuté comme un worker persistant de pepsi-dispatch(1), lisant les identifiants de message sur l’entrée standard.
85.1.32.1.12. Options globales¶
- -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 (par défaut
info).- -v, –verbose
Affiche les messages de journal de toutes les sources.
- -h, –help; -V, –version
Affiche un résumé d’utilisation / la version et quitte.
85.1.32.1.13. Code de sortie¶
- 0
Le message a été traité (transmis, retenu, réacheminé ou consommé).
- 1
Une erreur s’est produite (message introuvable ou non
running, ou un réglage par adresse qui rend la section de l’étape invalide). La raison est écrite dans le journal.Une défaillance de l’hôte (la base de données, un modèle ou un helper inutilisable) n’est pas signalée comme un échec : le message est mis en pause et réessayé, comme le décrit Erreurs d’étape dans pepsi-dispatch(1). Une section qui ne s’analyse pas fait refuser au worker de démarrer (statut 78) au lieu de mettre chaque message en échec à tour de rôle.
Un défi qui ne peut être mis en file est une telle défaillance. Il est retiré — le défi supprimé, à moins qu’un autre message retenu ne l’ait rejoint entre-temps, et l’emplacement MAX_CHALLENGES_PER_SENDER de l’expéditeur rendu — et le message est réessayé, plutôt que retenu dans l’attente d’une réponse que personne n’a été invité à donner.
85.1.32.1.14. Exemples¶
Une section de pipeline sur le chemin entrant
[stage-check-whitelist]
PROGRAM = pepsi-stage-check-whitelist
NEXT_STAGE = secretary
WHITELIST_NAME = correspondents
[stage-secretary]
PROGRAM = pepsi-stage-secretary
NEXT_STAGE = local
RESPONSE_STAGE = dkim-sign
WHITELIST_NAME = correspondents
PENALTY = EUR:50
Le texte de défi propre à un utilisateur, saisi par l’opérateur
pepsi-settings -c /etc/pepsi/pepsi.conf set alice@example.org secretary \
MESSAGE_EN "Hi {{SENDER_NAME}}, please reply once to reach me."
85.1.32.1.15. Voir aussi¶
pepsi-stage-check-whitelist(1), pepsi-stage-auto-whitelist(1), pepsi-stage-anti-spam(1), pepsi-stage-vacation(1), pepsi-whitelist(1), pepsi-settings(1), pepsi-dispatch(1), pepsi.conf(5), pepsi.state(7), pepsi-setup(1)
RFC 3834 (réponses automatiques).
85.1.32.1.16. Bogues¶
Signalez les bogues au gestionnaire de tickets de Pepsi.