85.2.1. pepsi.conf

configuration file for the Pepsi pipeline

Section du manuel:

5

85.2.1.1.1. Nom

pepsi.conf - fichier de configuration partagé par tous les composants Pepsi.

85.2.1.1.2. Description

Chaque composant Pepsi — pepsi-ingress(1), pepsi-dispatch(1), chaque programme pepsi-stage-*, pepsi-httpd(1), pepsi-queue(1), pepsi-tlsrpt(1), pepsi-setup(1) et le reste — lit le même fichier de configuration de style INI, conventionnellement pepsi.conf. Le format est partagé avec les composants GNU Taler sur lesquels Pepsi est bâti.

Comme il y a un seul fichier, chaque paramètre est documenté une fois, sous la section qui le possède. Un composant ne lit que les sections qui le concernent : les sections partagées [pepsi] et [pepsi-postgres] sont lues par tout le monde ; les sections de pipeline [stage-<name>] sont lues par le dispatcher et les programmes d’étape ; les sections spécifiques à un composant ([pepsi-ingress], [pepsi-httpd], [pepsi-dispatch], [pepsi-payments], [pepsi-tlsrpt] …) par le composant nommé.

Une option que rien ne lit est ignorée, de sorte qu’une option mal orthographiée prend silencieusement sa valeur par défaut ; pepsi-setup(1) avertit de chacune de ces options dans une section qu’il connaît, en nommant l’option réelle la plus proche.

Options renommées. Lorsqu’une version renomme une option, l’ancien nom continue de fonctionner pendant au moins une version de plus : chaque programme la lit sous le nouveau nom et journalise un avertissement qui le signale, et pepsi-setup(1) avertit également. Lorsque les deux noms sont définis, le nouveau l’emporte. NEWS liste chaque renommage.

85.2.1.1.3. Format de fichier

Un fichier de configuration est une suite d’en-têtes [SECTION], chacun suivi d’affectations OPTION = VALUE

[pepsi-ingress]
HOSTNAME = mail.example.org
ACCEPTED_DOMAINS = example.org example.com

Les noms de section et d’option sont insensibles à la casse et sont conventionnellement écrits en majuscules. Les lignes vides sont ignorées. Un # ou % en début de ligne introduit un commentaire. Une valeur peut être entourée de guillemets doubles pour préserver les espaces de début ou de fin.

85.2.1.1.3.1. Directives

@inline@ FILE

Inclure un autre fichier de configuration, résolu relativement au fichier courant.

@inline-matching@ GLOB

Inclure chaque fichier correspondant au glob shell GLOB.

@inline-secret@ SECTION FILE

Fusionner la section SECTION de FILE (typiquement un fichier à mode restreint contenant des identifiants) dans la configuration. Un fichier qui ne peut pas être lu est ignoré avec un avertissement. Cela garde les secrets hors du fichier principal lisible par tous.

Une directive est une ligne de premier niveau : comme @inline@, elle termine la section dans laquelle elle apparaît. Écrivez-la après la dernière option de la section qu’elle alimente — une option placée en dessous d’elle n’appartient à aucune section, et le fichier entier échoue alors au chargement avec Expected section header or directive. C’est pour cette raison que pepsi-setup(1) émet toujours ses directives en dernier au sein d’une section

[pepsi-srs]
SRS_DOMAIN = srs.example.org
MAX_AGE_DAYS = 21
@inline-secret@ pepsi-srs secrets.d/pepsi-ingress.secret

Comme un fragment illisible ne produit qu’un avertissement, une option qu’il aurait dû fournir a simplement l’air non réglée — un problème de permissions est signalé par ce qui a besoin de la valeur, typiquement sous la forme « … is not configured ». Pepsi détecte ce cas et le dit explicitement, en nommant le fragment, son propriétaire et son mode ; exécutez pepsi-setup run en tant que root pour donner chaque fragment au compte qui doit le lire.

85.2.1.1.3.2. Substitution de valeurs

Les options lues comme des chemins subissent une expansion $ : $VAR et ${VAR} sont remplacés par la valeur de VAR de la section [PATHS] ou, à défaut, de l’environnement. La forme ${VAR:-default} fournit un repli. La section [PATHS] est pré-remplie avec les répertoires d’installation habituels (PREFIX, BINDIR, DATADIR et ainsi de suite).

85.2.1.1.3.3. Types de valeur

booléen

YES ou NO (insensible à la casse).

nombre

Un entier décimal. Quelques options documentées comme telles prennent à la place une valeur fractionnaire, et chacune le signale là où elle est décrite (les options de débit de connexion de l’ingress et le RETRY_FACTOR des étapes de relais).

durée

Une durée telle que 5 s ou 2 h. Voir la mise en garde ci-dessous.

chemin

Un chemin de système de fichiers soumis à l’expansion $ comme décrit ci-dessus.

mode unix

Une permission de fichier écrite en octal, par exemple 660.

Avertissement

Les valeurs duration sont analysées par jiff::SignedDuration, qui n’accepte que les heures/minutes/secondes et en dessous. Une unité calendaire telle que 5 d ou 2 weeks ne s’analyse pas. Pour des fenêtres d’un jour ou plus, écrivez l’équivalent en heures (120 h) ou utilisez une option entière lorsqu’il en existe une (par exemple [pepsi-srs] MAX_AGE_DAYS).

85.2.1.1.4. La surcouche en base de données

Ce fichier est la couche de base. Par-dessus, chaque composant lit un ensemble de redéfinitions gérées par l’administrateur dans la table pepsi.config_override du schéma partagé, de sorte qu’un déploiement puisse être reconfiguré sans éditer de fichier et, pour les sections d’étape, sans redémarrage. Sans aucune ligne dans cette table, un déploiement se comporte exactement comme ce fichier le dit ; supprimer toutes les redéfinitions le ramène à cet état.

La chaîne de portées, précédence la plus faible d’abord :

  1. ce fichier ;

  2. la portée de base de données global ;

  3. la portée de base de données domain:DOMAIN ;

  4. la portée de base de données address:ADDRESS ;

  5. la table pepsi.settings par adresse (pepsi-settings(1)).

Les couches supérieures redéfinissent les inférieures option par option, jamais section par section : une option qu’aucune couche ne mentionne conserve la valeur écrite ici. L’adresse à laquelle une portée domain:/address: est comparée est l’expéditeur d’enveloppe pour un message d’origine locale, sinon chaque destinataire d’enveloppe.

La dernière couche est une table différente, avec une autorité d’écriture différente. pepsi.settings est écrite par les titulaires de comptes eux-mêmes, par e-mail, dans les limites de la liste d’autorisation EDITABLE_STAGES ; config_override définit le pipeline et n’est inscriptible qu’à travers le rôle PostgreSQL pepsi-config. pepsi-setup(1) accorde à ce rôle INSERT/UPDATE/DELETE sur la table, les révoque à chaque compte de service, et vérifie les deux face à la base en service après chaque installation : un worker d’étape analyse du courrier hostile pour vivre et ne doit pas pouvoir réécrire la configuration qui définit l’étape dans laquelle il s’exécute.

85.2.1.1.4.1. Sections qui ne sont jamais lues depuis la base

Une redéfinition qui en nomme une est ignorée à l’exécution et refusée à l’écriture :

[pepsi], [pepsi-postgres], [PATHS]

Lues avant qu’une connexion à la base ne puisse exister — et [pepsi] détient en outre la politique cryptographique réservée à l’administrateur.

[pepsi-httpd], [pepsi-httpd-listener-*], [pepsi-httpd-cert-*]

Le serveur qui sert l’interface de configuration doit toujours pouvoir démarrer.

[pepsi-ingress-listener-*]

Les sockets d’écoute sont liées au démarrage, souvent sous activation par socket et avant l’abandon des privilèges.

[pepsi-secure-link]

Son PEPPER est le secret côté serveur qui rend inutile une base de données volée ; une base capable de le remplacer pourrait donc faire en sorte que le prochain message stocké soit un message qu’un attaquant peut ouvrir. Le reste de la section suit.

[pepsi-admin]

Décide qui peut administrer le serveur et comment la surface d’administration atteint la base de données ; un avis de la base sur ce point serait un moyen de s’octroyer soi-même la console.

[pepsi-crypto], [pepsi-srs], [pepsi-origin]

Chacune détient une clé côté serveur qui existe pour que la base de données seule ne suffise pas : les clés de chiffrement de clés (et laquelle d’entre elles enveloppe les nouvelles clés privées), la clé SRS qui autorise le relais vers n’importe quelle adresse, et la clé de preuve d’origine contre laquelle un rebond ou une demande de paiement de retour est vérifié. Une base capable d’en remplacer une pourrait faire en sorte que la prochaine clé enveloppée soit une clé qu’un attaquant peut ouvrir, ou qu’un rebond falsifié soit relayé ou payé. Le reste de chaque section suit.

[pepsi-wizard]

Pas du tout de la configuration, mais le relevé par pepsi-setup(1) des réponses qui lui ont été données, que la console du navigateur dépose en brouillon dans cette même table. Rien ne le lit à l’exécution, la base de données ne le fournit donc pas non plus.

Deux règles supplémentaires s’appliquent dans toutes les autres sections :

  • Aucun identifiant n’est jamais stocké dans la base de données. Une option dont le nom la désigne comme telle – contenant PASS (PASSWORD, PASSPHRASE, API_PASS), SECRET, TOKEN, CREDENTIAL, CLIENT_ID ou PEPPER, la même règle qui masque une valeur partout où une configuration est affichée – est refusée à l’écriture et ignorée à l’exécution, dans chaque section. Cela inclut le fichier d’où un identifiant est lu et le point de terminaison auquel il est envoyé (SECRET_FILE, TOKEN_FILE, TOKEN_ENDPOINT) : une base capable de les définir peut détourner l’identifiant. Les identifiants résident dans ce fichier ou dans ses fragments secrets.d, chacun lisible uniquement par le compte qui en a besoin.

  • Les portées domain: et address: n’acceptent que des sections [stage-*] et nulle autre. Ces couches sont consultées par une étape, message par message, pour la section qu’elle exécute ; rien ne lit une autre section par domaine ou par adresse, de sorte qu’une telle redéfinition est refusée plutôt que stockée et jamais lue.

Par conséquent, ajouter un port de soumission, changer le matériel TLS d’un listener, la connexion à la base ou la politique cryptographique est une opération d’éditeur de texte et de redémarrage, et aucune interface d’administration ne peut le faire. [pepsi-ingress] DB_POOL_SIZE et [pepsi-dispatch] DB_POOL_SIZE sont réservés au fichier pour la même raison d’amorçage : le pool doit exister avant que la surcouche ne puisse être lue.

85.2.1.1.4.2. Rechargement à chaud

Chaque écriture dans la table déclenche une notification config_changed.

Tout changement [stage-*] est appliqué sans redémarrage, et ce pour les deux moitiés du pipeline. À la notification, pepsi-dispatch(1) reconstruit sa propre table d’étapes à partir de la surcouche – une étape peut donc être ajoutée, modifiée ou supprimée pendant que le pipeline tourne, et un PROGRAM/PARALLELISM/ MAX_MESSAGES/QUEUE_LIMIT modifié prend effet – et il met ses workers d’étape hors service, de sorte que les remplaçants relisent la surcouche. Aucun message n’est interrompu : un worker ne reçoit plus de travail et son créneau est abandonné une fois que ses messages en vol ont rendu compte.

La seule chose qu’un rechargement ne fera pas, c’est router selon un pipeline que les workers ne partagent plus. Un graphe d’étapes rechargé qui ne s’analyse pas met fin au dispatcher (sortie EX_CONFIG, par l’arrêt ordinaire, de sorte que rien n’est laissé en plan) plutôt que de laisser la table précédente en place.

Toute autre section est lue une fois au démarrage par le composant qui la possède et exige donc le redémarrage de ce composant – y compris les options propres à [pepsi-dispatch], qui ne sont délibérément pas rechargées. pepsi-config set imprime quel cas s’applique.

Un composant qui manque une notification relit la surcouche lorsque son écouteur de base se reconnecte : une notification perdue coûte donc de la latence, non de la correction.

Les secrets ne sont jamais stockés dans la base : la surcouche refuse un identifiant (voir ci-dessus), et la référence @inline-secret@ réside dans ce fichier. Chaque fragment reste la propriété de l’unique lecteur qui en a besoin.

Une valeur défectueuse dans la base ne peut empêcher aucun programme de démarrer : une surcouche illisible ou ne produisant pas une configuration utilisable est journalisée bruyamment et ce fichier est employé tel quel.

Voir pepsi-config(1) pour set/unset/list, pour dump --origin (qui annote chaque valeur effective avec la couche dont elle vient), et pour l”export/import chiffré de ce fichier et de ses fragments secrets.d.

85.2.1.1.5. La section [pepsi]

Paramètres d’identité et de politique transversaux partagés entre les outils Pepsi. Cette section n’est jamais lue depuis la surcouche en base.

KEY_DIR = PATH

Répertoire sous lequel les clés de signature par domaine sont stockées. Chaque domaine obtient un sous-répertoire (mode 0700) contenant dkim.rsa.key et dkim.ed25519.key (mode 0600). Facultatif ; par défaut /var/pepsi/keys.

DKIM_SELECTOR = NAME

Sélecteur DKIM de base. La clé RSA est publiée comme un enregistrement TXT à <NAME>._domainkey.<domain> et la clé Ed25519 à <NAME>-ed25519._domainkey.<domain>. Facultatif ; par défaut pepsi.

DKIM_ALGORITHMS = LIST

Les signatures DKIM qu’ajoute pepsi-stage-dkim-sign(1) : une liste de rsa et ed25519 séparés par des espaces ou des virgules. Facultatif ; par défaut les deux. Gmail, Microsoft 365 et Yahoo ne vérifient pas les signatures Ed25519 (RFC 8463) ; ils les ignorent, et les rapports agrégés DMARC de Google indiquent le sélecteur Ed25519 comme fail. C’est sans conséquence — DMARC a besoin d’une réussite alignée et la signature RSA la fournit — mais rsa seul supprime ce bruit. Omettre rsa est permis et fait l’objet d’un avertissement de pepsi-setup(1) : ces destinataires ne verraient alors plus aucune signature vérifiable. pepsi-setup ne publie et ne vérifie que les sélecteurs utilisés (plus celui dont le sceau ARC a besoin lorsque ce domaine est l”ARC_DOMAIN) ; les deux fichiers de clé sont générés dans tous les cas.

ARC_DOMAIN = DOMAIN

Domaine dont pepsi-stage-arc(1) utilise l’identité pour sceller en ARC le courrier entrant (RFC 8617). Le sceau réutilise la clé DKIM de ce domaine, de sorte que pepsi-setup(1) l’ajoute à l’ensemble des domaines pour lesquels il génère des clés et des enregistrements DNS DKIM ; ARC n’a besoin d’aucun enregistrement séparé. Facultatif ; s’il n’est pas réglé, les résultats d’authentification sont enregistrés mais pas scellés.

ARC_ALGORITHM = rsa | ed25519

Algorithme qui signe l’unique sceau ARC (ARC n’en permet qu’un par saut, contrairement à DKIM qui est par défaut signé avec les deux — voir DKIM_ALGORITHMS). Facultatif ; par défaut rsa pour la plus large interopérabilité.

ORIGINATE_SUCCESS_DSN = yes | no

Si Pepsi peut générer une notification d’état de remise positive (Action: delivered) lorsqu’une remise réussit et que l’expéditeur a demandé NOTIFY=SUCCESS. Facultatif ; par défaut no — Pepsi n’émet normalement que des rebonds d’échec. Lorsque yes, les étapes de remise (pepsi-stage-relay-to-internet(1), pepsi-stage-relay-to-smarthost(1), pepsi-stage-relay-to-maildir(1), pepsi-stage-relay-to-lmtp(1)) et pepsi-stage-discard(1) acheminent une remise réussie vers leur BOUNCE_STAGE (pour LMTP, son NOTIFY_STAGE) afin d’émettre le rapport.

Elle ne régit que les rapports SUCCESS. Les rapports DELAY ont leur propre interrupteur, par étape (le DELAY_DSN_AFTER d’une étape de remise, non réglé par défaut), et les rebonds FAILURE n’ont besoin d’aucun interrupteur – ils sont la valeur par défaut lorsque le NOTIFY d’un destinataire ne dit rien. SUCCESS comme DELAY ne sont émis que lorsque le NOTIFY de l’expéditeur les a demandés nommément ; ni l’un ni l’autre n’a de valeur par défaut implicite.

MAILBOX_QUOTA = SIZE

Limite par défaut de la quantité de courrier qu’un compte local peut détenir, appliquée par pepsi-stage-relay-to-maildir(1). Un simple nombre d’octets ou un suffixe K/M/G/T en puissances de 1024 (2G, 500M, 1048576), ou none. Facultatif ; vaut none par défaut — aucun quota. La limite d’un compte particulier se règle avec pepsi-quota(1) set, qui redéfinit ceci ; la limite propre au noyau resserre celle qui s’applique.

Le quota couvre tout l’arbre Maildir++ — la boîte de réception plus chaque dossier (.Sent, .Trash, …) — car c’est ce que l’utilisateur appelle sa boîte aux lettres, et ne compter que la boîte de réception permettrait à quiconque de garer une quantité illimitée de courrier à un glisser-déposer de là.

MAILBOX_QUOTA_COUNT = N

Limite par défaut du nombre de messages qu’un compte peut détenir ; 0 ou absent pour aucune. Un très grand nombre de très petits messages est un déni de service à part entière contre une boîte aux lettres, qu’une limite en octets seule n’empêche pas.

MAILBOX_OVER_QUOTA = defer | bounce

Ce qui arrive à un destinataire dont la boîte aux lettres est pleine. Facultatif ; vaut defer par défaut.

defer garde le message en file et le réessaie jusqu’au MAX_LIFETIME de l’étape de remise, puis rebondit — le même traitement que reçoit un EDQUOT du noyau, et cela laisse au compte le temps de faire de la place. bounce refuse aussitôt avec un 5.2.2 de la RFC 3463, acheminant le destinataire vers le QUOTA_LIMIT_STAGE de l’étape de remise, de sorte que l’expéditeur ne reste pas à attendre des jours.

Le même choix détermine la réponse que donne pepsi-ingress(1) lorsqu’il refuse un destinataire hors quota au RCPT : 452 4.2.2 pour defer, 552 5.2.2 pour bounce.

MAILBOX_QUOTA_MAX_AGE = DURATION

Combien de temps une mesure de boîte aux lettres peut être crue pour un refus au moment du RCPT. Facultatif ; vaut 15 m par défaut. Les unités sont h/m/s.

pepsi-ingress(1) ne refuse un destinataire hors quota que sur une mesure plus jeune que cela, et jamais sur l’estimation d’usage courante. C’est une borne de correction, non de performance : l’estimation ne fait que croître (rien n’indique à Pepsi qu’un utilisateur supprime du courrier en IMAP), de sorte que refuser sur elle fermerait une boîte aux lettres que son propriétaire a depuis vidée — définitivement, car chaque message étant refusé, aucune remise ne s’exécuterait pour remesurer. Cette borne, et pepsi-quota(1) reconcile, sont ce qui l’empêche.

MAILBOX_QUOTA_RCPT_CHECK = yes | no

Si pepsi-ingress(1) consulte la table des quotas au moment du RCPT. Facultatif ; vaut yes par défaut. Refuser là coûte une consultation indexée et épargne un rebond : le MTA émetteur est encore en ligne, c’est donc lui qui prévient son utilisateur, et Pepsi ne produit aucun backscatter vers un expéditeur d’enveloppe qui peut fort bien être falsifié. Le désactiver déplace toute l’application au moment de la remise.

MAILBOX_HELPER = PATH

Le helper privilégié que pepsi-quota(1) exécute pour mesurer une boîte aux lettres — pour sa sous-commande measure et son balayage reconcile. Facultatif ; vaut pepsi-helper-maildir-writer par défaut, résolu sur le PATH du processus appelant.

C’est le même binaire que celui qu’emploie l’étape de remise locale, invoqué dans son mode measure : un Maildir est en 0700, c’est donc l’unique processus qui peut devenir l’utilisateur et le lire. Ne réglez ceci que lorsque le helper n’est pas sur le PATH de pepsi-quota sous son nom — principalement une installation depuis les sources avec --prefix. Gardez-le en accord avec la propre option HELPER de l’étape de remise dans sa section [stage-<name>] (voir pepsi-stage-relay-to-maildir(1)) : les deux nomment le même programme pour deux appelants, et seule celle de l’étape est par étape.

MAILBOX_FS_QUOTA = yes | no

Si le système de fichiers hébergeant les répertoires personnels applique des quotas disque du noyau, auquel cas Pepsi consulte aussi quotactl(2) et laisse la limite du noyau resserrer la limite effective. Facultatif ; vaut no par défaut.

Normalement réglé pour vous. C’est un fait sur les montages de l’hôte, non une préférence : pepsi-setup(1) le sonde donc et consigne la réponse sans poser de question. Une valeur explicite n’est jamais écrasée. Activez-le là où cela s’applique : la comptabilité du noyau est la seule des trois couches que le titulaire du compte ne peut pas altérer (le fichier Maildir++ maildirsize réside dans son propre répertoire), et elle compte tout ce qu’il possède sur ce système de fichiers plutôt que son seul courrier.

RECIPIENT_DELIMITER = CHARACTER | none

Le séparateur de sous-adresse valant pour tout le site (alice+lists est le compte alice). Facultatif ; vaut + par défaut. Une section [stage-<name>] peut le redéfinir pour ses propres décisions de remise, mais préférez le régler ici : pepsi-ingress(1) emploie cette valeur pour déterminer à quel quota de boîte un destinataire appartient et n’a aucune section d’étape à lire, de sorte qu’une étape en désaccord fasse échapper le courrier sous-adressé au refus au moment du RCPT. pepsi-setup(1) avertit lorsque c’est le cas.

Les listes de diffusion utilisent cette valeur, et elle seule, pour chaque sous-adresse qu’elles écrivent et lisent : l’expéditeur d’enveloppe VERP de chaque copie (announce-bounces+alice=example.net@…), l’expéditeur d’une sonde de rebond, l’adresse -confirm+jeton, et le routeur de pepsi-stage-list(1) qui les reconnaît à leur retour. none laisse les listes sur +, puisqu’un expéditeur VERP ne peut pas s’écrire sans délimiteur.

MAX_QUEUE_ROWS = N | none

Contrôle d’admission de la file d’attente : le nombre maximal de messages (lignes de pepsi.workqueue) que la file peut contenir avant que pepsi-ingress(1) cesse d’accepter du courrier. Facultatif ; vaut par défaut 1000000 ; none (ou 0) pour aucune limite. Une ligne correspond à un groupe de destinataires, c’est donc ce chiffre que multiplie la diffusion d’une liste de diffusion ou la scission d’une étape de relais en une ligne par destinataire.

À la limite, pepsi-ingress(1) répond 452 4.3.1 à RCPT, à DATA/au premier segment BDAT, et après la fin des données. C’est un refus temporaire : le MTA expéditeur garde le message et réessaie, pendant que la file déjà présente se vide. pepsi-stage-list-post(1) retient une diffusion pendant QUEUE_THROTTLE_DELAY au lieu d’émettre son lot suivant. Rien de ce qui est déjà en file n’est affecté : les bounces, DSN et réponses automatiques que le pipeline émet lui-même ne sont jamais refusés.

MAX_QUEUE_BYTES = SIZE | none

Le nombre maximal d’octets que la file d’attente peut contenir : chaque bloc d’en-têtes en file plus chaque corps en file, chaque corps étant compté une seule fois quel que soit le nombre de lignes de destinataires qui le partagent (il est stocké une seule fois — voir DONNÉES STOCKÉES ci-dessous). Un nombre d’octets brut ou un suffixe K/M/G/T comme pour MAILBOX_QUOTA. Facultatif ; vaut par défaut none. Après la fin des données, la vérification inclut la taille du message proposé, de sorte qu’un message trop volumineux est refusé pour ce qu’il est. Les refus sont les mêmes que pour MAX_QUEUE_ROWS.

MIN_FREE_SPACE = SIZE | none

L’espace libre qui doit rester sur le système de fichiers contenant FREE_SPACE_PATH pour que le courrier soit accepté ; un message est refusé lorsque l’accepter en laisserait moins. Facultatif ; vaut par défaut 1G ; none désactive la sonde. C’est la limite qui voit ce qui n’est pas la file d’attente – journal d’écriture anticipée, autres bases de données, journaux – et PostgreSQL ne se dégrade pas lorsque son système de fichiers se remplit : il s’arrête, et avec lui chaque étape, la console et la socket de submission. Les refus sont les mêmes que pour MAX_QUEUE_ROWS.

FREE_SPACE_PATH = PATH

L’endroit où MIN_FREE_SPACE est mesuré (statvfs(3), l’espace disponible pour un écrivain non privilégié). Facultatif ; vaut par défaut /var/lib/postgresql, le parent des répertoires de données des clusters Debian – un répertoire de données lui-même est 0700 postgres, mais statvfs n’a besoin que d”atteindre un chemin, et son parent se trouve sur le même système de fichiers dans une disposition par défaut. Réglez-le sur le répertoire de données (ou son point de montage) lorsque PostgreSQL conserve ses données ailleurs. Lorsque la base de données est sur un autre hôte, le chemin par défaut n’existe généralement pas et la sonde est silencieusement désactivée ; un chemin défini ici qui ne peut pas être sondé est journalisé une fois, et la limite n’est alors pas appliquée.

QUEUE_CHECK_INTERVAL = DURATION

Durée pendant laquelle une mesure de la file d’attente est réutilisée. Facultatif ; vaut par défaut 10 s. Une mesure consiste en deux parcours séquentiels (la fonction pepsi.queue_usage()), de sorte que chaque processus en effectue au plus une par intervalle et que chaque RCPT entre-temps reçoit sa réponse à partir du chiffre en cache ; les limites sont donc approximatives, à hauteur des admissions d’un intervalle au plus. Une mesure qui échoue admet le courrier (et est journalisée) – un hoquet de la base de données ne doit pas devenir une panne à part entière, et une insertion qui ne peut réellement pas être stockée répond toujours 451.

QUEUE_THROTTLE_DELAY = DURATION

Durée pendant laquelle pepsi-stage-list-post(1) retient une diffusion pour laquelle il a trouvé la file d’attente pleine, avant de regarder à nouveau. Facultatif ; vaut par défaut 60 s.

MAIL_LOG = off | summary | full

Faut-il conserver une trace par message. Facultatif ; vaut off par défaut.

Pepsi supprime la ligne d’un message lorsque le pipeline en a fini avec lui : il n’y a donc normalement aucun journal de succès par message. Un déploiement ordinaire n’accumule pas de trace de la correspondance de ses utilisateurs, et ne peut être contraint d’en produire une qu’il n’a pas.

Régler cette option change cela. summary écrit une ligne pepsi.mail_log au moment où un message quitte le pipeline, portant l’expéditeur et les destinataires d’enveloppe, la direction (outbound pour le courrier soumis localement, inbound sinon), l’étape où il s’est arrêté, l’issue (completed/failed) et ce que le pipeline a décidé à son sujet (une liste fermée de clés de state : le verdict d’authentification, les décisions de spam et de paiement, tout détail d’échec au saut suivant, et les constats de cryptographie et de langue). full consigne en outre la ligne Subject:. Le contenu des messages n’est jamais enregistré, quel que soit le réglage.

Avertissement

Activer ceci signifie que le déploiement conserve la trace de qui correspond avec qui. Certains déploiements ont réellement besoin de cette preuve ; assurez-vous que le vôtre en fait partie, et que la conserver est licite là où vous opérez.

Les lignes sont lisibles par GET /api/v1/mail-log pour un principal détenant logs:read, sont en ajout seul pour chaque composant traitant du courrier, et sont élaguées après [pepsi-admin] MAIL_LOG_RETENTION_DAYS jours. L’écriture voyage sur la même instruction que le terminal qui retire ou fait échouer le message, de sorte qu’activer le journal ne coûte aucun aller-retour supplémentaire à la base. Voir le chapitre « L’API d’administration » du manuel.

ALLOW_FUSION = yes | no

Si la fusion d’étapes est permise. Lorsqu’une étape avance vers un successeur marqué FUSION = yes (voir l’option par étape ci-dessous), dont le PROGRAM est plié dans le même binaire pepsi unifié, et qui n’a besoin d’aucune colonne de message que le prédécesseur n’a pas déjà chargée, le prédécesseur exécute le corps du successeur dans son propre processus worker — sautant à la fois l”UPDATE d’avancement et le SELECT de chargement du successeur, et rapportant une seule complétion au dispatcher pour toute la chaîne fusionnée. Facultatif ; par défaut yes. Réglez-le sur no pour forcer chaque transition d’étape à repasser par la base de données et le dispatcher (le benchmark de coût par étape fait cela afin que chaque étape soit mesurée comme son propre worker dispatché). La fusion est de toute façon inerte dans un build par programme (multibin), où un successeur est toujours un processus séparé. Voir pepsi-dispatch(1) pour le modèle complet.

MTA_STS_MODE = enforce | testing | none

Mode de la politique MTA-STS publiée pour nos domaines. enforce et testing amènent pepsi-setup(1) à émettre un enregistrement TXT _mta-sts.<domain> (et pepsi-httpd(1) à servir le fichier de politique correspondant) ; none désactive la publication MTA-STS. Facultatif ; vaut enforce par défaut. Les hôtes que la politique autorise sont MTA_STS_MX.

MTA_STS_MX = ENTRÉE[, ENTRÉE…]

Les hôtes publiés comme lignes mx: de la politique MTA-STS – chaque MX auquel un expéditeur peut remettre, RFC 8461 §3.2 (mx « must appear at least once and may appear more than once »). Chaque ENTRÉE est soit

HOST

un motif d’hôte s’appliquant à tous les domaines servis, soit

DOMAIN:HOST

un motif d’hôte s’appliquant à ce seul domaine servi.

L’ensemble mx d’un domaine est constitué des entrées non qualifiées plus les entrées qualifiées par son propre nom ; les entrées qualifiées s’ajoutent à l’ensemble commun au lieu de le remplacer, si bien qu’un site dont les domaines partagent un MX principal l’écrit une fois et ne peut pas le perdre en qualifiant le MX de secours d’un domaine. Un motif d’hôte peut employer un joker sur le premier label seulement (*.example.net), et : est un séparateur sans ambiguïté puisqu’un nom d’hôte n’en contient pas.

La politique est donc par domaine, ce dont un hôte servant plusieurs domaines a besoin : les enregistrements MX de chaque domaine nomment ses propres hôtes, et rien n’exige qu’ils concordent. La politique de chaque domaine reçoit son propre id dans son propre enregistrement TXT _mta-sts.<domain>, les expéditeurs les mettent donc en cache indépendamment

MTA_STS_MX = example.org:mx.example.org, example.net:mail.example.net

Facultatif. Lorsque l’option est entièrement absente, la politique de chaque domaine nomme le [pepsi-ingress] HOSTNAME. Ce repli est un dernier recours et non une bonne valeur par défaut : HOSTNAME est le nom de salutation EHLO, qui n’a pas à être un nom vers lequel un enregistrement MX pointe – et lorsqu’il ne l’est pas, une politique enforce dit à chaque expéditeur conforme de ne pas remettre au domaine du tout. Posez donc cette option sur les hôtes que vos enregistrements MX nomment réellement. L’assistant de pepsi-setup(1) les lit dans le DNS et écrit l’option pour vous, et chaque pepsi-setup run recoupe l’ensemble résolu avec les enregistrements MX réels et affiche l’option à poser lorsqu’ils divergent (voir pepsi-setup(1), Recoupements MTA-STS).

Sous le mode enforce par défaut, une politique qui omet un hôte dit à chaque expéditeur conforme qu’il ne doit pas y remettre : un MX de secours absent de cette liste ne reçoit donc aucun courrier pendant que le principal est en panne.

Chaque hôte nommé doit en outre présenter un certificat TLS valide pour son propre nom (RFC 8461 §4.1), et pepsi-setup(1) le provisionne : les hôtes listés ici deviennent des Subject Alternative Names sur le certificat des listeners d’ingress, lequel est élargi via certbot à la prochaine exécution de pepsi-setup run s’il ne les couvre pas encore. Un seul certificat plutôt qu’un par hôte, parce que pepsi-ingress(1) sert un unique certificat par listener et ne sélectionne pas sur SNI. Une entrée à joker est l’exception : HTTP-01 ne peut pas en obtenir, ce certificat doit donc être fourni par TLS_CERT/TLS_KEY.

MTA_STS_MAX_AGE = SECONDS

Le max_age publié dans la politique MTA-STS (combien de temps les expéditeurs peuvent la mettre en cache). Facultatif ; par défaut 604800 (une semaine). Le §3.2 de la RFC 8461 le borne à 1..``31557600``, et une valeur hors de cet intervalle est refusée – en particulier 0, qui publierait une politique expirant immédiatement et désactiverait donc MTA-STS tout en donnant l’impression d’être configurée.

TEMPLATE_DIR = PATH

Répertoire contenant les modèles de message (<name>.<lang>.body) développés à l’exécution — par exemple la réponse de demande de paiement de pepsi-stage-anti-spam(1) et le corps BOUNCE_MESSAGE de pepsi-stage-bounce(1). Facultatif ; vaut par défaut ${DATADIR}/templates, où make install place les modèles fournis. ${DATADIR} est résolu depuis le préfixe d’installation du binaire en cours d’exécution : le défaut est donc /usr/share/pepsi/templates pour une installation --prefix=/usr et suit le préfixe pour tout autre ; ne réglez cette option que si les modèles résident là où le préfixe ne l’implique pas.

LOG_JSON = yes | no

Émettre les journaux sous forme de lignes JSON structurées (un objet JSON par enregistrement) sur l’erreur standard au lieu du format texte lisible par un humain par défaut, de sorte qu’un agrégateur de journaux tel que Loki puisse les ingérer sans analyse supplémentaire. S’applique à chaque binaire Pepsi. Facultatif ; par défaut no (texte). L’option de niveau de log -L/--log et -v/--verbose s’appliquent dans les deux formats.

LOG = error | warn | info | debug | trace

Niveau de log maximal par défaut pour chaque binaire Pepsi. Comme tous les composants — y compris les workers d’étape que le dispatcher lance (qui ne reçoivent pas d’indicateur de journal en ligne de commande propre) — chargent cette même configuration, c’est l’unique réglage qui abaisse ou relève la journalisation à travers tout le pipeline d’un coup ; c’est, par exemple, ce que les scripts de benchmark règlent à warn afin que la journalisation par message ne fausse pas leurs mesures. Facultatif ; par défaut info. L’indicateur -L/--log, lorsqu’il est donné, le redéfinit pour ce seul processus.

PUBLIC_RESOLVERS = IP … | none

Les résolveurs récursifs publics par lesquels pepsi-setup(1) revérifie, tels qu’Internet les voit, les enregistrements DNS dont dépend cet hôte : le DNS inverse de chaque PUBLIC_IP, les enregistrements MX et TXT de chaque domaine servi, et les adresses du HOSTNAME d’ingress (voir Le DNS tel que l’Internet le voit dans pepsi-setup(1)). Une liste d’adresses IP séparées par des espaces ou des virgules. Facultatif ; par défaut Google (8.8.8.8, 2001:4860:4860::8888), Cloudflare (1.1.1.1, 2606:4700:4700::1111) et Quad9 (9.9.9.9, 2620:fe::fe). none désactive la vérification.

Une recherche depuis cet hôte ne peut voir une zone que seul le réseau de cet hôte peut atteindre — un serveur de noms derrière un NAT dont le port 53 n’est pas redirigé semble sain vu de l’intérieur — et c’est pourquoi la vérification existe. Les noms qu’elle envoie à ces résolveurs sont des noms que cet hôte publie pour que n’importe qui les interroge ; réglez tout de même none si vous préférez qu’aucun résolveur tiers ne soit interrogé, et vérifiez plutôt depuis une machine extérieure à votre réseau. Lu uniquement par pepsi-setup.

SHARE_TELEMETRY = yes | no

Si ce déploiement partage une télémétrie anonyme d’usage des fonctionnalités avec le projet Pepsi. Sur consentement explicite : facultatif, et vaut no par défaut, de sorte qu’une installation qui ne le règle jamais ne partage rien. Réglé sur yes, pepsi-setup(1) engendre un SYSTEM_ID aléatoire (ci-dessous) et le daemon pepsi-telemetry-client(1) agrège les événements d’usage venus des workers d’étape et de pepsi-ingress(1) et soumet des comptes par fonctionnalité à TELEMETRY_SERVER sous cet identifiant anonyme (aucune adresse, donnée de message, nom d’hôte ou adresse IP). Laissé à no, un daemon en cours d’exécution reste en sommeil (aucune socket, rien de soumis), aucun SYSTEM_ID n’est engendré, et les appels de télémétrie en processus sont sans effet et n’ouvrent aucune socket. Une valeur inanalysable est lue comme no. Quiconque modifie cette option dans le fichier notifie le daemon (telemetry_changed) ; celui-ci relit aussi le fichier chaque minute. La console de configuration du navigateur ne peut l’activer que tant que le daemon tourne avec un SYSTEM_ID.

SYSTEM_ID = 64-HEX

Identifiant anonyme de 256 bits (64 caractères hexadécimaux) soumis avec chaque rapport de télémétrie. Engendré et écrit ici par pepsi-setup(1) seulement une fois SHARE_TELEMETRY activé — un déploiement qui n’a pas donné son consentement n’en voit jamais frapper un ; requis par pepsi-telemetry-client(1). Un opérateur peut en ajouter un à la main tant que la télémétrie est désactivée, ce qui permet à la console du navigateur de proposer d’activer la télémétrie ; un enregistrement dans la console le conserve. Ne le réutilisez pas d’un déploiement à l’autre.

TELEMETRY_SERVER = HOST | URL

Le collecteur de télémétrie central. Facultatif ; par défaut telemetry.pepsi.taler.net. pepsi-telemetry-client(1) soumet à https://<server>/telemetry/{usage,features} ; une valeur contenant un scheme:// explicite est honorée verbatim (par exemple http://localhost:18080 pour des tests locaux).

Les options CRYPTO_* suivantes régissent la cryptographie de bout en bout des messages (OpenPGP et S/MIME) — non les clés DKIM/ARC ci-dessus. Ce sont délibérément des paramètres d”administrateur système et elles vivent dans [pepsi] plutôt que dans une section [stage-*], ce qui les place structurellement hors de portée de la couche de redéfinition par adresse (pepsi.settings ne redéfinit que les sections d’étape) et donc de pepsi-stage-edit-settings(1) : le choix des algorithmes, la permission de rétrograder, l’acceptation des condensats faibles et les tailles de clé minimales sont des décisions de sécurité à valeur par défaut sûre, non des préférences par utilisateur. Chacune est facultative ; un déploiement qui ne fait pas de cryptographie de bout en bout peut toutes les ignorer. Le magasin où vivent ces clés se configure dans [pepsi-crypto] (ci-dessous) et se gère avec pepsi-keys(1).

CRYPTO_ALLOW_DOWNGRADE = no | negotiate | yes

Si Pepsi peut émettre un conteneur rétrogradé (EnvelopedData AES-256-CBC en S/MIME, SEIPDv1-avec-MDC en OpenPGP) et accepter le 3DES au déchiffrement. Facultatif ; la valeur compilée est negotiate, qui ne rétrograde que lorsque la clé même du destinataire prouve qu’il ne peut faire mieux — ce qui compte, car une grande part du parc installé ne sait pas lire du tout un message AEAD de la RFC 9580. La lecture du SEIPDv1 et de l’AES-CBC est toujours permise et n’est pas conditionnée par cette option.

Un Pepsi installé livre yes, depuis ${DATADIR}/config.d/thunderbird.conf : le défaut effectif sur un système empaqueté est donc l”EnvelopedData AES-256-CBC en S/MIME. Thunderbird 140.12.0esr ne sait pas lire nos AuthEnvelopedData AES-256-GCM et échoue silencieusement — aucune erreur, un texte clair vide — de sorte qu’un déploiement laissé sur le défaut compilé enverrait du courrier vide à la plus grande population de clients S/MIME qui soit. Supprimer ce fichier rétablit l’AEAD en une étape, et CRYPTO_ALLOW_DOWNGRADE = negotiate dans pepsi.conf fait de même sans le supprimer (pepsi.conf est analysé après config.d). La mesure est pepsi-crypto/tests/thunderbird.rs ; la matrice des clients est dans le chapitre d’interopérabilité du manuel.

yes ne dégrossit pas OpenPGP : l’étape de chiffrement demande le conteneur auto, que negotiate comme yes résolvent par destinataire — AEAD pour un certificat qui annonce SEIPDv2, SEIPDv1+MDC seulement pour un qui ne l’annonce pas. La différence entre les deux valeurs est le conteneur S/MIME et l’acceptation d’un message S/MIME 3DES entrant, qui n’est jamais émis sous aucun réglage. Le 3DES OpenPGP entrant est accepté sous negotiate comme sous yes, et refusé seulement sous no : un certificat OpenPGP énonce ses propres capacités de chiffrement, si bien que negotiate a de quoi négocier, tandis que X.509 n’en annonce aucune et reçoit donc la règle la plus stricte.

pepsi-setup n’écrit pas cette option. L’assistant la laisse délibérément hors de la pepsi.conf engendrée — tout ce qu’il y écrirait écraserait le fichier empaqueté — de sorte qu’une redéfinition délibérée se fasse en éditant pepsi.conf à la main ou avec pepsi-setup --wizard --expert=CRYPTO_ALLOW_DOWNGRADE.

CRYPTO_ALLOW_WEAK_DIGESTS = yes | no

Accepter les signatures SHA-1 et MD5 à la vérification. Facultatif ; vaut no par défaut. Une signature sous un condensat faible est rapportée comme telle, jamais comptée silencieusement comme valide.

CRYPTO_MIN_RSA_BITS = BITS

Plus petit module RSA accepté à la vérification entrante et au chiffrement sortant. Facultatif ; vaut 2048 par défaut. Les valeurs inférieures à 1024 sont refusées d’emblée.

CRYPTO_GENERATE_RSA_BITS = BITS

Taille de module employée lorsque ce déploiement engendre une clé RSA. Facultatif ; vaut 2048 par défaut. Elle ne peut être inférieure à CRYPTO_MIN_RSA_BITS — un déploiement ne doit pas engendrer des clés qu’il refuse ensuite d’accepter — et la génération de clés OpenPGP n’accepte que 2048, 3072 ou 4096.

CRYPTO_INLINE_PGP = accept | reject

Comment traiter le PGP en ligne (non MIME). Facultatif ; vaut accept par défaut, car de vrais expéditeurs en émettent encore. Pepsi n’en engendre jamais.

CRYPTO_OPENPGP_ALGORITHM = ed25519 | rsa

Algorithme employé lors de la génération d’une nouvelle identité OpenPGP. Facultatif ; vaut ed25519 par défaut — la génération est instantanée, ce qui compte car une identité peut devoir être créée pendant qu’un message attend. rsa emploie CRYPTO_GENERATE_RSA_BITS.

CRYPTO_SMIME_ALGORITHM = rsa | p256 | p384

Algorithme employé lors de la génération d’une nouvelle identité S/MIME. Facultatif ; vaut rsa par défaut (à CRYPTO_GENERATE_RSA_BITS) ; p256 et p384 sont ECDSA/ECDH sur la courbe NIST correspondante.

CRYPTO_SMIME_SHARED_KEY = yes | no

Délivrer un seul certificat S/MIME portant à la fois digitalSignature et keyEncipherment au lieu d’un certificat de signature et d’un certificat de chiffrement distincts. Facultatif ; vaut no par défaut.

Le défaut les sépare parce qu’un certificat de signature séparé peut être détruit à l’expiration ou à la révocation — rien de légitime ne resigne jamais du vieux courrier, une clé de signature retirée n’est donc qu’un risque de falsification — tandis que la moitié de déchiffrement est conservée afin que le texte chiffré archivé et en vol reste lisible. Activer ceci divise par deux les certificats qu’un opérateur achète par identité et abandonne cela : une clé partagée suit la règle du déchiffrement, de sorte que révoquer une clé de signature compromise mette aussi fin à la capacité de recevoir du nouveau courrier chiffré sur ce certificat.

L’option ne décide que de l’allure des identités nouvellement créées. Les deux formes sont prises en charge de façon permanente et peuvent coexister pour une même adresse, de sorte que chaque consultation se résolve par capacité plutôt que par forme. Combinée à un CRYPTO_SMIME_ALGORITHM à courbes elliptiques, elle est refusée par pepsi-setup(1) : une seule clé EC faisant à la fois ECDSA et ECDH est une réutilisation de clé entre algorithmes que plusieurs clients S/MIME rejettent.

85.2.1.1.6. La section [pepsi-postgres]

Paramètres de connexion à la base de données partagés. Chaque composant Pepsi se connecte à la même base de données et au schéma pepsi partagé, de sorte que ces paramètres résident dans une seule section plutôt que d’être répétés par composant.

Note

Budget de connexions. Chaque processus Pepsi ouvre son propre pool de connexions. Les workers d’étape et les CLI d’opérateur font leur travail de base de données strictement en série, ils utilisent donc une seule connexion chacun — et comme le dispatcher exécute jusqu’à un processus worker par créneau d’étape (la somme des PARALLELISM des étapes), cette règle d’une connexion par worker est ce qui garde l’essentiel du nombre de connexions prévisible et minimal. Les composants concurrents gardent un petit pool borné dimensionné par leur propre option DB_POOL_SIZE : le coordinateur pepsi-dispatch(1) (par défaut 8, pour le traitement de résultats concurrent des nombreux workers) et les serveurs pepsi-ingress(1) et pepsi-httpd(1) (par défaut 1 chacun). Lors du réglage, assurez-vous que Σ PARALLELISM (une connexion par worker en vie) + le pool du dispatcher + les pools des deux serveurs reste en dessous du max_connections du serveur. Le QUEUE_LIMIT d’une étape n’entre pas dans ce budget : pipeliner plus de messages sur un worker augmente son nombre en vol, pas le nombre de processus workers (ou de connexions), c’est donc le réglage sûr pour le débit lorsque max_connections est la contrainte liante.

CONFIG

(chaîne, obligatoire) Chaîne de connexion ou URI PostgreSQL, par exemple postgres:///pepsi. Le serveur règle le chemin de recherche de schéma sur pepsi et utilise des transactions READ COMMITTED (au plus un écrivain touche jamais une ligne de file donnée, de sorte que l’isolation sérialisable est inutile).

Ce fichier est lisible par tous, la chaîne ne doit donc porter aucun mot de passe ; chaque composant refuse de démarrer s’il en trouve un.

Base de données locale (la configuration canonique). Chaque composant se connecte par la socket UNIX sous le rôle qui porte le nom de son propre compte système (pepsi, pepsi-ingress, pepsi-httpd, pepsi-crypto, …) et l’authentification peer de PostgreSQL vérifie l’uid. Aucun mot de passe n’existe nulle part, et les droits de chaque rôle dans la base de données constituent la frontière de privilèges entre les composants.

Base de données distante (configuration recommandée). Gardez le même modèle : un rôle par compte, chacun avec ses propres identifiants qu’aucun autre compte ne peut lire. Le paramètre fictif {role} de la chaîne de connexion est remplacé, lorsqu’un composant se connecte, par le rôle sous lequel il se connecte, de sorte qu’une seule chaîne désigne un fichier différent pour chaque rôle. Avec des certificats clients (le pg_hba.conf de la base de données utilisant cert)

CONFIG = postgres://db.example.org/pepsi?sslmode=verify-full&sslcert=/etc/pepsi/postgres/{role}.crt&sslkey=/etc/pepsi/postgres/{role}.key

ou avec des mots de passe, un fichier de mots de passe libpq (format .pgpass, par exemple l’unique ligne *:*:*:*:<password>) par rôle

CONFIG = postgres://db.example.org/pepsi?sslmode=verify-full&passfile=/etc/pepsi/postgres/{role}.pgpass

Chaque fichier de clé ou de mot de passe appartient au compte de son rôle et a le mode 0600 ou 0400 ; un fichier de mots de passe que quelqu’un d’autre peut lire est refusé, comme libpq le refuse, et pepsi-setup run signale chaque rôle dont le compte existe sur l’hôte mais dont le fichier est absent, appartient à un autre compte ou est ouvert à d’autres. Omettez le nom d’utilisateur de la chaîne (ou écrivez-y {role}) : chaque composant fournit le sien. Comme le fichier est lu à l’ouverture de la connexion, par le compte qui l’ouvre, une étape setuid telle que pepsi-stage-encrypt lit le fichier de pepsi-crypto et le dispatcher qui l’a lancée ne le peut pas. La chaîne elle-même ne contient alors aucun secret et reste dans ce fichier.

Surcharge par l’environnement. La variable d’environnement PEPSI_POSTGRES_CONFIG, lorsqu’elle est définie et non vide, remplace cette option et peut porter un mot de passe. Chaque unité systemd livrée la lit depuis EnvironmentFile=-/etc/pepsi/postgres.env (le - initial rend le fichier facultatif ; gardez-le propriété de root en 0600, puisque systemd le lit en tant que root avant de démarrer le service). Les programmes setuid et setgid ne conservent la variable que lorsque root ou le compte dispatcher pepsi les a lancés, de sorte que les étapes atteignent la base de données du dispatcher tandis qu’un utilisateur ordinaire ne peut pas diriger un programme privilégié vers une autre. Un mot de passe qui s’y trouve est un seul mot de passe pour tous les rôles, ce qui abandonne la séparation entre les composants ; préférez les fichiers par rôle ci-dessus et utilisez la variable pour ce qui diffère d’un hôte à l’autre. Lorsqu’elle est définie, CONFIG peut être omis ; un mot de passe dans CONFIG est refusé même dans ce cas. Un outil lancé depuis un shell (pepsi-setup run, pepsi-queue, …) a besoin de la variable exportée de la même manière, par exemple set -a; . /etc/pepsi/postgres.env; set +a.

SQL_DIR

(chemin, facultatif) Répertoire contenant les fichiers de migration SQL. Seul pepsi-setup(1) le lit, lors de l’installation du schéma ; les composants de service l’ignorent. Par défaut ${DATADIR}/sql (c.-à-d. <install-prefix>/share/pepsi/sql, où make install place les fichiers). Redéfinissez-le lors d’une exécution depuis un checkout des sources.

WORKER_SYNCHRONOUS_COMMIT

(booléen, facultatif) Si la connexion de base de données d’un worker d’étape garde le synchronous_commit de PostgreSQL activé. Vaut no par défaut.

Désactivé, le COMMIT d’un worker revient avant que l’enregistrement du journal d’écriture anticipée n’ait atteint un stockage stable, ce qui permet aux écritures du pipeline de valider en groupe au lieu que chacune paie sa propre purge. Rien d’autre ne change : l’isolation, l’atomicité et la visibilité sont intactes, et un plantage ne peut jamais exposer une transaction partielle. Ce qui peut être perdu, ce sont les dernières centaines de millisecondes de durabilité — et uniquement pour les transitions d’étape, jamais pour l’admission des messages, car pepsi-ingress(1) valide toujours de façon synchrone. Un 250 signifie toujours que le message est sur disque.

Perdre un avancement d’étape à cause d’un plantage machine signifie que le message est retrouvé encore à l’étape précédente et la traverse une seconde fois — exactement ce qui arrive déjà lorsqu’un worker est tué après avoir fait son travail mais avant d’avoir validé. Réglez ceci sur yes si une étape de votre pipeline a des effets de bord qui ne doivent pas être répétés même à travers une coupure de courant, et acceptez le coût en débit.

85.2.1.1.7. La section [pepsi-srs]

Les paramètres du Sender Rewriting Scheme, partagés par pepsi-stage-srs(1) (la réécriture directe) et pepsi-ingress(1) (le décodage inverse au moment du RCPT), de sorte que le secret et le domaine correspondent dans les deux sens. Omettre la section désactive SRS : l’étape refuse de s’exécuter et l’ingress traite les destinataires d’apparence SRS comme des adresses ordinaires.

SRS_DOMAIN

(chaîne, requise pour activer SRS) Domaine sous lequel vivent les expéditeurs d’enveloppe réécrits. Ce doit être un domaine que vous contrôlez : son MX doit pointer vers l’ingress Pepsi (pour que les rejets reviennent) et son SPF doit autoriser les IP d’envoi de Pepsi. pepsi-setup(1) provisionne les clés et le DNS pour lui. Le MX est la moitié qu’il ne peut pas provisionner – où le courrier d’un domaine est routé est votre décision –, il vérifie donc à la place : avec une étape exécutant pepsi-stage-srs(1), un SRS_DOMAIN sans MX et sans enregistrement d’adresse est signalé à chaque exécution, car une adresse SRS est un chemin de retour et un domaine qui ne peut pas recevoir abandonne chaque rejet du courrier que cette machine transfère. Il n’a pas besoin d’être un sous-domaine dédié ; un domaine dont vous acceptez déjà le courrier fonctionne et n’exige aucun nouvel enregistrement (pepsi-ingress(1) décode une partie locale SRS avant de chercher une boîte : les adresses ordinaires de ce domaine ne sont donc pas affectées).

SECRET_FILE / SECRET

(requis lorsque SRS_DOMAIN est réglé) Le secret clé du HMAC qui signe les adresses SRS, donné comme un chemin de fichier (préféré ; stockez-le en mode 0600) ou en ligne. Il doit rester stable dans le temps — un rebond renvoyé des jours plus tard doit encore se vérifier — et être identique sur toutes les instances.

MAX_AGE_DAYS

(entier, facultatif) Combien de jours une adresse réécrite reste valide pour les rebonds de retour (les horodatages SRS sont à granularité journalière). Par défaut 21. Borné à 1..``1021`` : le compteur de jours boucle après 1024 jours, si bien qu’une fenêtre égale ou supérieure ferait vérifier tous les horodatages et désactiverait complètement l’expiration.

La signature d’une adresse réécrite fait 8 caractères base32 — 40 bits — et aucune plus courte n’est jamais acceptée. Une signature valide n’est pas une petite chose à falsifier : pepsi-ingress(1) traite un destinataire SRS vérifié comme une autorisation de relayer vers l’adresse décodée même lorsque son domaine n’est pas servi par ce déploiement, de sorte qu’un jeton falsifié est un relais ouvert et du backscatter arbitraire attribué à cet hôte. Il n’y a pas d’option pour accepter une signature plus étroite : elle laisserait le déploiement aussi solide que le seul MAC le plus étroit tant qu’elle serait réglée. Le plafond par connexion sur les destinataires SRS en échec (pepsi-ingress(1) coupe une connexion avec un 421 après trois) borne séparément la recherche en ligne ; aucune des deux bornes ne remplace l’autre.

85.2.1.1.8. La section [pepsi-origin]

Matériel de clé de preuve d’origine, partagé par les deux étapes de relais (pepsi-stage-relay-to-internet(1) et pepsi-stage-relay-to-smarthost(1), qui estampillent l’en-tête Pepsi-Origin sur le courrier sortant et enregistrent son nonce) et pepsi-stage-anti-spam(1) (qui vérifie l’en-tête sur un rebond de retour). La fonctionnalité est activée par défaut : lorsqu’aucun secret n’est configuré, pepsi-setup(1) en génère un aléatoire au premier lancement (à condition que [pepsi-ingress] HOSTNAME soit réglé). Le secret n’est pas stocké en ligne dans ce fichier lisible par tous ; il est écrit dans un fragment secrets.d/pepsi-origin.secret à côté de la configuration (possédé par le compte dispatcher pepsi, mode 0640) et tiré dans cette section avec une directive @inline-secret@. Réexécuter la configuration initiale réutilise le fragment existant plutôt que de faire tourner la clé. ENABLED = no désactive la fonctionnalité — le courrier sortant n’est pas estampillé et chaque rebond devient alors invérifiable (acheminé selon le BOUNCE_TARGET_STAGE de l’étape, sinon transféré). Supprimer la section ne la désactive pas : la prochaine exécution de pepsi-setup(1) provisionnerait un nouveau secret.

ENABLED

(booléen, facultatif) YES par défaut. NO désactive la preuve d’origine pour chaque composant qui lit cette section, quel que soit le secret configuré, et empêche pepsi-setup(1) d’en générer un. Un fragment de secret existant est laissé en place, de sorte que la réactiver reprend avec la même clé.

L’en-tête porte la version, notre HOSTNAME (l’option [pepsi-ingress]), le compte expéditeur d’origine, un nonce de 128 bits et un horodatage, plus un HMAC-SHA256 sur l’ensemble. Chaque nonce estampillé est enregistré dans pepsi.origin_nonce pendant deux semaines ; un rebond n’est approuvé que si le MAC de son en-tête intégré se vérifie et que son nonce est encore suivi. Voir pepsi-stage-anti-spam(1).

SECRET_FILE / SECRET

Le secret clé du HMAC, donné comme un chemin de fichier (préféré ; stockez-le en mode 0600) ou en ligne. Comme le secret SRS, il doit rester stable dans le temps — un rebond renvoyé des jours plus tard doit encore se vérifier — et être identique sur toutes les instances. Lorsqu’aucun n’est réglé, pepsi-setup(1) provisionne un SECRET aléatoire dans un fragment secrets.d/pepsi-origin.secret référencé par @inline-secret@ (voir ci-dessus), le gardant hors de la configuration principale lisible par tous. La fonctionnalité nécessite [pepsi-ingress] HOSTNAME (intégré au MAC).

85.2.1.1.9. La section [pepsi-crypto]

Garde et cycle de vie du magasin de clés de bout en bout — les tables pepsi.crypto_identity, pepsi.peer_key et pepsi.ca_trust gérées par pepsi-keys(1). Comme les options CRYPTO_* de [pepsi] ci-dessus, ceci est réservé à l’administrateur, mais il s’agit de stockage plutôt que de force cryptographique. Omettez la section entière si le déploiement ne fait pas de cryptographie de bout en bout ; dès qu’elle dit quoi que ce soit, pepsi-setup(1) insiste sur un KEY_WRAP_SECRET utilisable, car un magasin de clés incapable de stocker des clés est une erreur de configuration plutôt qu’un choix.

Le matériel de clé privée est conservé dans la base, scellé en AES-256-GCM sous une clé de chiffrement de clés (KEK) dérivée de KEY_WRAP_SECRET. La base seule ne livre donc jamais de clé privée : un vidage, un réplicat ou une bande de sauvegarde produit du texte chiffré, et la clé qui l’ouvre est un artefact distinct gardé par les permissions de fichier. L’autre moitié de la frontière est un droit de base — crypto_identity.private_wrapped n’est accordé qu’au seul rôle pepsi-crypto ; voir pepsi-setup(1).

KEY_WRAP_SECRET

(chaîne, requise dès que la section existe) La clé de chiffrement de clés qui enveloppe le matériel de clé privée au repos. Gardez-la hors de ce fichier lisible par tous : placez-la dans un fragment secrets.d/pepsi-crypto.secret et référencez-la par une directive @inline-secret@, exactement comme sont traités les secrets SRS et de preuve d’origine. Chaque run de pepsi-setup(1) réaffirme le mode 0640 sur ce fragment et le remet au compte pepsi-crypto. Moins de 16 caractères est refusé.

Sauvegardez-la séparément de la base. Si elle est perdue, chaque clé privée stockée est perdue : les boîtes aux lettres contiennent du texte clair, si bien que le courrier de personne ne devient illisible, mais le texte chiffré en vol et archivé est perdu, chaque identité publiée est invalidée et l’organisation doit changer de clés.

KEY_WRAP_KEY_ID

(chaîne, facultative) Identifiant de la clé de chiffrement de clés sous laquelle le nouveau matériel est enveloppé. k1 par défaut. Doit être une suite non vide de lettres ASCII, de chiffres et de tirets bas, car il est inséré dans le nom d’option KEY_WRAP_SECRET_<ID> d’où est lue une clé retirée. Chaque ligne consigne l’identifiant qui l’a scellée, ce qui rend le renouvellement incrémental plutôt qu’un jour J.

KEY_WRAP_SECRET_<ID>

(chaîne, facultative) Une clé de chiffrement de clés retirée, conservée jusqu’à ce que chaque ligne enveloppée sous elle ait été renouvelée. <ID> est le wrap_key_id qu’elle nomme, en majuscules (donc KEY_WRAP_SECRET_K0 pour la clé k0). Entre l’introduction d’une nouvelle clé et l’exécution de pepsi-keys wrap rotate, le déploiement continue de fonctionner : le nouveau matériel est scellé sous la nouvelle clé tandis que l’ancien s’ouvre toujours sous celle-ci. Retirez-la une fois que le renouvellement rapporte que tout a été réenveloppé.

AUTO_CREATE_IDENTITY

(booléen, facultatif) Si une identité peut être générée automatiquement pour une adresse servie. YES par défaut. C’est pepsi-stage-encrypt(1) qui agit en conséquence, et uniquement pour une adresse d’un domaine de [pepsi-ingress] ACCEPTED_DOMAINS qui n’a encore aucune ligne crypto_identity d’aucune sorte (une clé révoquée ou la propre clé enregistrée de l’utilisateur compte), selon CRYPTO_OPENPGP_ALGORITHM / CRYPTO_SMIME_ALGORITHM et IDENTITY_VALIDITY_DAYS. Le moment où elle se déclenche dépend de l’option ENABLE_PEP de cette étape :

  • ENABLE_PEP = yes (par défaut) : de manière anticipée, au premier message soumis localement par l’expéditeur, qu’il ait ou non demandé une protection. Chaque expéditeur d’un domaine servi finit donc par avoir une clé privée enveloppée sur ce serveur, et le WKD du déploiement en sert la moitié publique.

  • ENABLE_PEP = no : de manière paresseuse, la première fois qu’un expéditeur local demande explicitement une protection (signer ou seulement chiffrer), ou à chaque message sous SIGN = always de cette étape ; jamais du seul fait qu’une adresse est apparue dans une enveloppe, de sorte qu’un utilisateur qui n’utilise jamais la fonctionnalité n’a jamais de matériel de clé.

Cette option est le veto de l’opérateur sur les deux : elle réside dans une section réservée à l’administrateur, de sorte qu’aucune redéfinition pepsi.settings par adresse ne peut réactiver la création automatique. Lorsqu’elle est désactivée, chaque identité est créée sur demande – par pepsi-keys(1), la console web ou la commande generate par e-mail.

Comme le déclencheur est sur le chemin sortant, une adresse qui ne fait que recevoir reste sans clé et n’est jamais publiée — les tiers n’ont donc rien pour chiffrer vers elle. Provisionnez ces adresses à l’avance avec pepsi-keys identity generate.

IDENTITY_VALIDITY_DAYS

(nombre, facultatif) Durée de vie d’une identité engendrée, en jours. 730 par défaut (deux ans) ; doit être positive. Un nombre entier de jours plutôt qu’une duration, car l’analyseur rejette les unités calendaires (voir l’avertissement en tête de cette page). pepsi-keys identity generate --days la redéfinit pour une identité.

LOCAL_DOMAINS, TARGETS, RECIPIENT_DELIMITER

(chaîne, facultative) À quels domaines et comptes une adresse est attribuée pour décider à qui appartient une identité, que ce soit pepsi-keys(1), l’applicateur de configuration ou pepsi-stage-encrypt(1) qui la crée — les mêmes noms d’options, avec les mêmes significations et valeurs par défaut, que les options des étapes de remise locale (pepsi-stage-relay-to-maildir(1)). LOCAL_DOMAINS vaut par défaut [pepsi-ingress] ACCEPTED_DOMAINS, TARGETS la plage UID_MIN..``UID_MAX`` de /etc/login.defs et RECIPIENT_DELIMITER +. Une adresse qui se résout vers un compte local voit ce login consigné avec son identité et peut être gérée par cet utilisateur ; une adresse qui ne s’y résout pas (une adresse de rôle, un domaine hébergé) est réservée à l’opérateur.

85.2.1.1.10. La section [pepsi-keydiscovery]

Comment Pepsi trouve la clé publique ou le certificat d’un correspondant — l’entrée de pepsi.peer_key, à la différence de [pepsi-crypto] ci-dessus, qui concerne la garde de notre propre matériel de clé. Lue par les services de découverte pepsi-keydisc(1), par pepsi-keys(1) (dont peer refresh --address exécute le même éventail dans un seul processus), et par toute étape qui doit garer un message sur une clé qu’elle n’a pas encore.

La section entière est facultative : sans elle, la découverte s’exécute avec l’ensemble de sources par défaut.

La découverte est asynchrone. Une étape qui a besoin d’une clé absente de son cache n’effectue aucune entrée-sortie réseau propre — elle valide son travail, met le message en pause et met une demande en file dans pepsi.key_request, et un service de découverte répond à la demande et libère chaque message garé sur cette adresse. Voir pepsi-keydisc(1) pour le côté service et pepsi.state(7) pour la clé keydisc que porte un message garé.

SOURCES

(chaîne, facultative) Quelles méthodes de découverte ce déploiement exécute, sous forme de liste séparée par virgules ou espaces parmi dane, wkd-advanced, wkd-direct, ldap et vks (wkd est accepté pour wkd-advanced, hkp pour vks ; les doublons sont ignorés). Par défaut dane wkd-advanced wkd-direct vks — ldap en est délibérément absent, étant conditionné à une fonctionnalité de compilation et inutile tant qu’il n’est pas configuré.

Cette liste est aussi le registre que la règle d’arrêt attend, ce qui a deux conséquences. Une instance pepsi-keydisc@<method> dont la méthode n’y figure pas refuse de démarrer ; et une méthode listée sans instance en cours coûte simplement à chaque demande le TIMEOUT complet avant qu’elle ne se règle. Gardez la liste et les unités en cours d’exécution en accord : pepsi.target démarre exactement les quatre méthodes par défaut, laissez donc l’option non définie à moins de masquer ou de démarrer aussi des instances. inbound et gossip (ainsi que leurs alias harvested/autocrypt et autocrypt-gossip) sont rejetés : apprendre une clé dans un message n’est pas un service – cela s’exécute en ligne dans pepsi-stage-autocrypt-learn(1) à partir de matériel déjà présent dans le message – si bien que rien n’y répondrait jamais. Une liste vide est refusée elle aussi ; retirez l’option pour prendre la valeur par défaut.

MIN_TRUST

(chaîne, facultative) Le plancher de confiance — une clé venue d’une source moins bien classée n’est pas employée. Nommé par sa source : manual (aussi api ou operator), dane, wkd-advanced (aussi wkd), wkd-direct, ldap, vks (aussi hkp), harvested (aussi inbound ou autocrypt), ou gossip (aussi autocrypt-gossip, any, none). Par défaut any — tout accepter.

Une orthographe supplémentaire, owner-confirmed (owner_confirmed), nomme un échelon par ce que la preuve est plutôt que par la méthode qui l’a produite : elle se résout en vks, le plus faible échelon auquel quelqu’un qui pouvait prouver le contrôle de la boîte aux lettres ou du domaine a publié la clé volontairement. Elle existe afin que l’insertion d’un échelon entre vks et harvested ne puisse pas déplacer silencieusement cette ligne. C’est aussi la valeur par défaut de [stage-encrypt] GOSSIP_MIN_TRUST.

L’alternative au chiffrement vers une clé en confiance au premier usage n’est pas une meilleure clé, c’est le texte clair. Le relever est la façon dont un déploiement dit qu’il préférerait ne rien envoyer plutôt que d’envoyer vers une clé non authentifiée. Le classement travaille encore au réglage par défaut : il tranche les conflits et il est consigné par clé.

any/none nomment l’échelon du bas, quel qu’il soit à l’instant présent, tandis que toute autre graphie nomme un rang exact. La distinction compte pour les deux qui se ressemblent : harvested est le rang 7 — ce qu’un correspondant a dit de sa propre adresse, dans un en-tête Autocrypt: ou une clé jointe — et gossip est le rang 8, la présentation d’un autre par un correspondant (Autocrypt Level 1 §5.3). MIN_TRUST = harvested est donc le réglage intermédiaire utile : conserver le chiffrement opportuniste, refuser les présentations par des tiers. Les clés gossipées sont stockées dans les deux cas ; le plancher décide seulement si elles peuvent être employées.

Le plancher ne s’applique pas à une adresse pour laquelle ce déploiement détient une identité. Notre propre clé n’est pas une clé découverte : elle préempte la consultation, de sorte qu’aucune ligne peer_key pour cette adresse ne soit consultée quel que soit son rang, et qu’aucun plancher ne puisse l’exclure. own (aussi local) est accepté comme graphie par souci de complétude — chaque rang a un nom et state.crypto rend celui-ci — mais comme plancher il signifie « ne chiffrer que vers des adresses dont nous détenons notre propre clé », c’est-à-dire qu’aucun correspondant externe ne reçoit jamais de texte chiffré. Voir pepsi-stage-encrypt(1) et pepsi-stage-decrypt(1).

TIMEOUT

(durée, facultative) Échéance de la demande entière : combien de temps une demande peut rester en cours avant de se régler avec ce qui a été trouvé. 60 s par défaut. N’emploie que les unités h/m/s (voir la note sur les durées ci-dessus).

INBOUND_TIMEOUT

(durée, facultative) La même échéance pour un message garé sur le chemin entrant — en attente de la clé qui vérifie une signature — valant TIMEOUT par défaut. Elle est distincte précisément pour pouvoir être abaissée seule : un garage entrant retarde exactement le courrier que quelqu’un attend, de sorte qu’un opérateur qui le ressent puisse la réduire à quelques secondes sans raccourcir l’échéance sortante. pepsi-setup(1) avertit au-delà de cinq minutes.

RANK_GRACE

(durée, facultative) Le curseur entre vitesse et exhaustivité. Lorsqu’une consultation réussit, chaque méthode encore en cours qui se classe mieux se voit accorder RANK_GRACE × (de combien de rangs elle est meilleure) de temps supplémentaire ; à son expiration, la meilleure réponse en main l’emporte. 5 s par défaut, donc un rang au-dessus reçoit 5 s et trois rangs au-dessus 15 s.

Un seul réglage couvrant tout l’éventail : 0 signifie que la première réponse utilisable l’emporte d’emblée ; le défaut se situe là où un serveur WKD lent ne peut pas retenir un message derrière une réponse de serveur de clés déjà arrivée, tandis qu’une meilleure source presque aussi rapide peut encore l’emporter ; une valeur égale ou supérieure à TIMEOUT signifie qu’on attend chaque méthode et que le classement s’applique intégralement (pepsi-setup(1) signale ce cas plutôt que de le traiter comme une erreur — c’est un choix légitime).

METHOD_TIMEOUT

(durée, facultative) L’échéance réseau propre à une méthode, couvrant la connexion, la poignée de main et chaque lecture. 15 s par défaut. La régler au-delà de TIMEOUT rend une méthode lente incapable de finir dans l’échéance de la demande entière, ce dont pepsi-setup(1) avertit.

CACHE_TTL

(durée, facultative) Combien de temps une clé stockée est employée avant que pepsi-keys peer refresh ne la revérifie (cela devient le refresh_after de la ligne). 24 h par défaut.

NEGATIVE_TTL

(durée, facultative) Combien de temps un « cette adresse n’a pas de clé » faisant autorité est retenu. 24 h par défaut. Tant que l’entrée est fraîche, un message pour cette adresse prend immédiatement le chemin « pas de clé » et ne se gare jamais : s’arrêter 60 s pour réapprendre une réponse connue ne fait que retarder chaque message vers ce correspondant. Le coût accepté est qu’une clé publiée il y a cinq minutes reste invisible jusqu’à ce que l’entrée vieillisse — abaissez ceci si cela compte plus que le délai.

ERROR_TTL

(durée, facultative) La même chose, après qu’une méthode a échoué plutôt que répondu « il n’y a rien ici ». 1 h par défaut : « le serveur était en panne » mérite d’être retenté plus tôt que « il n’y a pas de clé ».

MAX_RESPONSE_BYTES

(nombre, facultatif) Plafond sur un corps de réponse WKD ou VKS récupéré, appliqué pendant la diffusion plutôt qu’après, de sorte qu’un corps de 10 Mo coûte le plafond et non 10 Mo. 262144 par défaut (256 Kio). Doit être supérieur à zéro.

VKS_SERVERS

(chaîne, facultative) Serveurs de clés vérifiants à interroger, dans l’ordre, sous forme de liste séparée par virgules ou espaces. https://keys.openpgp.org par défaut. Chaque entrée doit être une URL https:// — une clé récupérée sur un canal non authentifié n’est pas une clé qu’on ait raison de croire — et un / final est retiré.

ALLOW_DOMAINS, DENY_DOMAINS

(chaîne, facultative) Politique de consultation par domaine de destinataire, séparée par virgules ou espaces et comparée sans distinction de casse sur la partie domaine. Un ALLOW_DOMAINS non vide est exclusif (seuls ces domaines sont jamais consultés) ; DENY_DOMAINS l’emporte toujours sur lui. Les deux sont vides par défaut, de sorte que tout domaine puisse être consulté. Une adresse sans @ n’est jamais consultée.

C’est le contrôle de confidentialité côté destinataire, et il est celui de l’opérateur. L’interrupteur par utilisateur ci-dessous est le côté expéditeur ; les deux ne sont pas interchangeables.

LDAP_URL, LDAP_BASE, LDAP_FILTER, LDAP_ATTRIBUTE, LDAP_BIND_DN, LDAP_BIND_PASSWORD

(chaîne, facultative) L’annuaire qu’interroge pepsi-keydisc@ldap. LDAP_URL doit être une URL ldap:// ou ldaps:// et, avec LDAP_BASE, est requise dès que ldap figure dans SOURCES. LDAP_FILTER vaut (mail={address}) par défaut et doit contenir le marqueur {address} (l’adresse est échappée selon la RFC 4515 avant substitution, de sorte qu’une partie locale contenant * ou ( ne puisse devenir de la syntaxe de filtre) ; LDAP_ATTRIBUTE vaut userCertificate;binary par défaut. Un LDAP_BIND_DN absent signifie un bind anonyme ; un LDAP_BIND_DN présent exige une URL ldaps://, car un bind simple envoie le mot de passe verbatim et la consultation est refusée plutôt qu’effectuée en clair (la même règle que les clients LMTP et SMTP appliquent à AUTH).

La prise en charge de LDAP est une fonctionnalité cargo de compilation. Sur une compilation qui en est dépourvue, ldap dans SOURCES est rejeté par pepsi-setup(1) et l’instance pepsi-keydisc@ldap refuse de démarrer.

85.2.1.1.10.1. L’interrupteur par expéditeur : [stage-encrypt] DISCOVERY

Une étape qui consomme le magasin de clés lit une option qui lui est propre, dans sa section [stage-<name>], de sorte qu’elle puisse être redéfinie par adresse via la couche pepsi.settings (pepsi-settings(1)) :

DISCOVERY

(booléen, facultatif) Si un défaut de cache peut déclencher une consultation réseau. YES par défaut. Avec NO, les clés en cache sont toujours employées, mais un défaut va droit au chemin « pas de clé » de l’étape au lieu de garer le message — il n’y aurait rien à attendre.

Important

Ce que signifie réellement la redéfinition par adresse. La couche de paramètres résout un message sortant sur son expéditeur d’enveloppe, de sorte qu’une redéfinition de DISCOVERY pour une adresse signifie « le courrier de cet utilisateur ne déclenche jamais de consultation » — et non « ne jamais consulter ce correspondant ». La suppression côté destinataire est celle de l’opérateur, ALLOW_DOMAINS/DENY_DOMAINS ci-dessus ; il n’existe délibérément pas de liste noire de destinataires par adresse, qui exigerait sa propre colonne et une seconde liste pour rester cohérente avec celle-ci.

DISCOVERY est lue par pepsi-stage-encrypt(1) et pepsi-stage-decrypt(1) depuis la section effective de cette étape, de sorte qu’une redéfinition pepsi.settings s’applique. Leurs autres options sont documentées sous Options de pepsi-stage-encrypt et Options de pepsi-stage-decrypt.

85.2.1.1.11. La section [pepsi-keys]

L’image en miroir de la section ci-dessus : comment les autres trouvent les clés de nos utilisateurs. Lue par pepsi-keys(1) et par pepsi-stage-vks-confirm(1). La section entière est facultative, et une configuration qui l’omet ne publie rien sur aucun serveur de clés.

La publication par Web Key Directory n’a besoin d’aucune option. Elle suit l’indicateur published de chaque identité (activé par défaut, effacé avec pepsi-keys identity unpublish) et est servie par pepsi-httpd(1) depuis notre propre domaine : elle prend donc effet à la requête suivante et se défait en effaçant l’indicateur. Ce que cette section configure est l’autre canal, qui ne se comporte pas du tout de même : un serveur de clés accepte une clé définitivement — on peut plus tard lui dire que la clé est révoquée, jamais lui dire de l’oublier.

VKS_PUBLISH

(booléen, facultatif) Si une identité créée ou importée à la main (pepsi-keys identity generate/import, le generate de la console web ou de l’API, la commande generate par e-mail) commence avec son téléversement vers le serveur de clés demandé (crypto_identity.vks_wanted). NO par défaut.

Chaque identité enregistre si son téléversement a été demandé, et la tâche de relance (pepsi-keys identity publish --retry) téléverse exactement les identités OpenPGP publiées et actives qui ont vks_wanted positionné, en réessayant jusqu’à vérification. Elle n’est pas conditionnée par cette option. Deux conséquences :

  • les clés générées automatiquement ([stage-encrypt] ENABLE_PEP) et les clés MUA enregistrées à partir du propre courrier d’un utilisateur ne sont jamais téléversées sans demande, quoi que dise cette option – Autocrypt et le WKD propre au déploiement sont la manière dont on les trouve ;

  • la demande explicite de téléversement d’un utilisateur (pepsi-keys identity publish <ID> --vks, Upload to the key server dans la console web, PATCH /api/v1/identities/{id} avec vks_wanted, ou la commande publish par e-mail) est honorée quoi que dise cette option.

« Non téléversé » est donc un état enregistré plutôt qu’une absence, et pepsi-keys identity show l’affiche. Un téléversement ne peut pas être retiré, c’est pourquoi la valeur par défaut pour les clés faites à la main reste une décision de l’opérateur.

VKS_SERVER

(chaîne, facultative) Le serveur de clés vers lequel vont les téléversements ; https:// uniquement, et une URL en clair est refusée plutôt que rétrogradée. Vaut par défaut la première entrée de [pepsi-keydiscovery] VKS_SERVERS, afin qu’un déploiement ayant déjà choisi un serveur de clés à lire ne le nomme pas deux fois.

Un serveur, non une liste : publier la même clé auprès de plusieurs multiplie un acte irréversible, et chacun d’eux doit ensuite être tenu à jour des révocations.

Son hôte est aussi le VKS_HOST par défaut de pepsi-stage-vks-confirm(1) — l’unique hôte dont cette étape accepte un courrier de vérification et vers lequel elle suit un lien.

VKS_MAX_ATTEMPTS

(entier, facultatif) Combien de tentatives une identité obtient avant que pepsi-keys identity publish --retry ne la laisse tranquille. 5 par défaut. La ligne conserve sa dernière erreur, de sorte qu’une identité abandonnée dise pourquoi.

VKS_RETRY_INTERVAL

(durée, facultative) Espacement minimal entre les tentatives pour une identité. 6 h par défaut. Les unités calendaires sont rejetées : 6 h s’analyse, 1 d non.

VKS_BATCH

(entier, facultatif) Sur combien d’identités une exécution --retry travaille, afin qu’une première exécution sur un grand déploiement ne soit pas une seule énorme rafale chez un tiers. 50 par défaut.

85.2.1.1.12. La section [pepsi-ingress]

Options globales régissant l’acceptation des messages, lues par pepsi-ingress(1).

HOSTNAME

(chaîne, obligatoire) Nom d’hôte annoncé dans la salutation SMTP et la réponse EHLO, par exemple mail.example.org.

ACCEPTED_DOMAINS

(chaîne, obligatoire) Liste séparée par espaces ou virgules de domaines pour lesquels le courrier est accepté. Les destinataires dans tout autre domaine sont rejetés comme relayage avec une réponse 550. La correspondance est insensible à la casse. Au moins un domaine doit être donné.

USERNAME_MAP

(chemin, facultatif) Fichier mappant chaque id d’authentification SASL aux adresses e-mail qu’il peut utiliser comme expéditeur d’enveloppe et identité From: (RFC 6409 §6/§8.1). Chaque ligne non vide et non-commentaire est username: addr… — un # commence un commentaire, la clé est le nom d’utilisateur SASL, et la valeur est la liste séparée par espaces/virgules des adresses autorisées (qui peut être vide). Un nom d’utilisateur listé avec des adresses est autorisé exactement celles-ci (la première concrète étant l’identité canonique utilisée pour la correction Sender:) ; une adresse peut être un joker * tel que *@example.org (n’importe quelle adresse au domaine) ou un * nu (n’importe quelle adresse). Un nom d’utilisateur listé sans adresses se voit refuser toute adresse (son AUTH est refusé même si les identifiants sont valides) ; un nom d’utilisateur non listé retombe sur le défaut username@HOSTNAME. Le fichier est relu chaque fois que son heure de modification change (vérifiée à chaque authentification) ; un fichier manquant/illisible est traité comme vide. Lorsqu’il n’est pas réglé, chaque utilisateur authentifié est mappé à son défaut username@HOSTNAME. Voir pepsi-ingress(1).

POSTMASTER

(chaîne, facultative) Adresse routable en laquelle la boîte aux lettres réservée sans domaine <Postmaster> est réécrite. La RFC 5321 §4.5.1 exige que <Postmaster> (sans domaine) soit accepté quels que soient ACCEPTED_DOMAINS ; à l’acceptation, Pepsi le réécrit en cette adresse afin que le pipeline normal (alias, remise locale, relais) puisse l’acheminer. Lorsqu’il n’est pas réglé, il est réécrit en postmaster@HOSTNAME — ajoutez un alias pour cette adresse dans une carte ALIASES de pepsi-stage-aliases pour remettre le courrier postmaster à une vraie personne, ou réglez POSTMASTER directement sur cette personne. Voir pepsi-ingress(1).

MAX_MESSAGE_SIZE

(nombre, facultatif) Taille maximale acceptée du corps de message en octets — la taille de la charge utile DATA. La valeur est annoncée via l’extension ESMTP SIZE ; les messages la dépassant sont rejetés avec 552. Par défaut 26214400 (25 Mio).

MAX_CONNECTIONS

(nombre, facultatif) Nombre maximal de connexions SMTP servies en concurrence sur tous les listeners. Le plafond d’admission effectif est le plus petit de celui-ci et de MAX_OPEN_SOCKETS. Par défaut 1024.

DB_POOL_SIZE

(nombre, facultatif) Nombre maximal de connexions PostgreSQL dans le pool de base de données de l’ingress. L’ingress sert de nombreuses sessions SMTP en concurrence, chacune appelant brièvement workqueue_add, de sorte que contrairement aux workers d’étape à connexion unique, il peut en utiliser plus d’une. Par défaut 1 ; ne le relevez que si l’acceptation entrante est limitée par la connexion unique, et gardez la somme du pool de chaque composant en dessous du max_connections de PostgreSQL.

MAX_OPEN_SOCKETS

(nombre, facultatif) Plafond dur sur les connexions client ouvertes en concurrence, protégeant contre l’épuisement des descripteurs de fichiers. Lorsqu’il n’est pas réglé, il est dérivé du RLIMIT_NOFILE souple du processus moins RESERVED_SOCKETS. Lorsque le plafond est atteint et qu’une nouvelle connexion arrive, le serveur fait de la place en fermant la connexion la plus longtemps inactive dans la plage source (une adresse IPv4, ou un /32 IPv6) dont le temps d’inactivité total est le plus grand (un 421, puis fermeture).

RESERVED_SOCKETS

(nombre, facultatif) Descripteurs de fichiers retenus du budget dérivé de RLIMIT_NOFILE (pour le pool de base de données, les listeners, stdio et les sockets DNS). Par défaut 64. Ignoré lorsque MAX_OPEN_SOCKETS est réglé.

CONN_RATE_PER_SECOND

(nombre, facultatif) Taux de recharge de seau à jetons limitant les nouvelles connexions acceptées par plage source, en connexions par seconde. Une connexion dépassant le débit est refusée avec 421 et fermée sans prendre de créneau. Par défaut 1. Une valeur fractionnaire est acceptée (0.2 vaut une connexion toutes les cinq secondes). Les connexions locales (socket UNIX) ne sont jamais limitées en débit.

CONN_RATE_BURST

(nombre, facultatif) Allocation de rafale de seau à jetons par plage source, également fractionnaire. Par défaut 1.

MAX_CONNECTIONS_PER_IP

(nombre, facultatif) Connexions simultanées qu’une plage source (une adresse IPv4, ou un /32 IPv6) peut détenir. Une connexion au-delà est refusée comme une connexion limitée en débit. Par défaut 16 ; 0 désactive le plafond.

MAX_LOCAL_CONNECTIONS

(nombre, facultatif) Connexions simultanées que l’ensemble des pairs de socket UNIX peuvent détenir. Les connexions locales sont exemptées de la limite de débit et jamais évincées, c’est donc ce qui empêche les émetteurs locaux d’occuper tous les créneaux. Par défaut 32 ; 0 ne les borne que par MAX_CONNECTIONS.

MAX_MESSAGES_PER_SESSION

(nombre, facultatif) Transactions de courrier qu’une session peut commencer ; le MAIL suivant reçoit la réponse 421 et la session est fermée. Par défaut 100 ; 0 signifie illimité.

VERIFY_RECIPIENTS

(``auto`` ou ``off``, facultatif) Si une adresse d’un domaine servi que rien sur cet hôte n’accepterait est refusée au moment du RCPT avec 550 5.1.1. Par défaut auto. Le MTA émetteur prévient alors immédiatement son propre utilisateur. Accepté, le message rebondirait plus tard vers son expéditeur d’enveloppe — que le spam falsifie, de sorte que le rebond frappe un tiers innocent (backscatter) et vaut à cet hôte de finir sur une liste noire.

Rien n’a besoin d’être listé à la main. Pour chaque domaine servi, les sources qui peuvent se porter garantes d’une adresse sont déduites des sections [stage-*] :

  • les comptes locaux que résout une pepsi-stage-relay-to-maildir(1) ou une pepsi-stage-dot-forward(1) pour ses LOCAL_DOMAINS, TARGETS et RECIPIENT_DELIMITER compris ;

  • le MDA derrière une pepsi-stage-relay-to-lmtp(1), interrogé pour ses LOCAL_DOMAINS avec RCPT TO et sans message ;

  • le backend derrière une pepsi-stage-route(1), selon ce qu’indique son RECIPIENT_CHECK ;

  • chaque table de pepsi-stage-aliases(1), avec la correspondance propre à l’étape ;

  • les listes de diffusion, lorsqu’un routeur pepsi-stage-list(1) est configuré ;

  • postmaster@ et abuse@, ainsi que les adresses de contrôle des étapes qui en traitent une (pepsi@, pepsi-keys@, pepsi-wallet@, secretary@).

Une adresse dont l’une d’elles se porte garante est acceptée. Il en va de même de toute adresse d’un domaine qui ne peut pas être vérifié :

  • un alias fourre-tout couvre le domaine ;

  • une étape exécute un programme que Pepsi ne connaît pas ;

  • le domaine est acheminé vers un backend avec RECIPIENT_CHECK = none ;

  • le domaine est relayé plus loin par une étape smarthost sans que rien ici ne détienne ses boîtes aux lettres.

Toute incertitude accepte aussi : un fichier illisible, une erreur de base de données, une sonde qui échoue ou expire. pepsi-setup run affiche le résultat pour chaque domaine. off accepte toute adresse d’un domaine servi, comme auparavant. Lu au démarrage : un graphe d’étapes modifié exige un redémarrage de l’ingress, tandis que les modifications d’une table d’alias, d’une liste de destinataires ou des listes de diffusion s’appliquent immédiatement.

MAX_INVALID_RECIPIENTS

(nombre, facultatif) Nombre de destinataires inconnus qu’une session peut nommer. À la limite, la session est fermée avec 421, ce qui transforme une attaque par dictionnaire (collecte d’adresses valides, ou obliger le MDA à répondre essai après essai) en un flux de connexions que mesurent les limites de connexion. Par défaut 10 ; 0 signifie illimité.

MAX_SELF_HOPS

(nombre, facultatif) Combien de fois un message peut déjà être passé par l’ingress de cet hôte avant d’être refusé comme boucle de routage, avec 554 5.4.6. Compté à partir des champs Received: que l’ingress écrit lui-même (by HOSTNAME (pepsi-ingress)). Le courrier légitime revient tout au plus quelques fois : un alias vers un autre domaine servi, un ~/.forward, ou un rapport destiné à l’un de nos propres utilisateurs repartent chacun par SMTP puis reviennent. Une boucle, en revanche, tournerait sinon jusqu’à la limite de sauts générique des étapes de relais, soit des dizaines de passages. Par défaut 5 ; 0 désactive la vérification.

AUTH_FAILURES_PER_HOUR

(nombre, facultatif) Tentatives AUTH échouées qu’une plage source peut faire par heure sur l’ensemble de ses sessions (un seau à jetons). Une fois épuisé, AUTH depuis la plage est refusé avec 421 sans consulter le backend SASL jusqu’à ce que le seau se remplisse. Par défaut 20 ; 0 signifie illimité.

LOCAL_MESSAGES_PER_MINUTE

(nombre, facultatif) Messages qu’un uid local, identifié par SO_PEERCRED sur une session par socket UNIX, peut soumettre par minute sur l’ensemble de ses sessions ; un MAIL au-delà du débit reçoit 451 4.7.1. Par défaut 60 ; 0 signifie illimité.

LOCAL_MESSAGE_BURST

(nombre, facultatif) La rafale autorisée en plus de LOCAL_MESSAGES_PER_MINUTE. Par défaut 120.

COMMAND_TIMEOUT

(durée, facultative) Durée maximale qu’une session attend pour la commande suivante (ou la continuation AUTH, le début d’un corps DATA/BDAT, ou l’achèvement d’une poignée de main STARTTLS/TLS implicite) avant que la connexion ne soit fermée avec 421 (RFC 5321 §4.5.3.2). Par défaut 300 s.

DATA_TIMEOUT

(durée, facultative) Durée maximale qu’une session attend pour le bloc d’octets de charge utile suivant lors de la réception d’un corps DATA/BDAT avant de fermer avec 421. Par défaut 180 s.

DMARC_ENFORCE

(booléen, facultatif) Lorsque YES, rejeter au moment SMTP (550) un message dont l’évaluation DMARC échoue et dont la politique publiée est quarantine ou reject. Par défaut NO : pepsi-ingress(1) accepte normalement un tel courrier (et pepsi-stage-arc(1) scelle le résultat en échec) afin que le destinataire en aval décide. Les autres échecs d’authentification ne rejettent jamais un message.

DNS_SERVERS

(chaîne, facultative) Liste séparée par espaces ou virgules d’adresses IP de résolveur (IPv4 et/ou IPv6) utilisées pour les recherches SPF/DKIM/DMARC, interrogées sur le port 53. Si elle n’est pas réglée, la configuration de résolveur système (/etc/resolv.conf) est utilisée.

DNS_TIMEOUT

(durée, facultative) Timeout par requête pour ces recherches. Par défaut 5 s. Comme la vérification s’exécute de façon synchrone pendant la réception du DATA, un résolveur lent retarde l’acceptation 250.

Elle ne s’applique que lorsque DNS_SERVERS nomme les résolveurs. Avec DNS_SERVERS non réglé, la configuration de résolveur système est employée en entier, timeout compris : cette option n’a donc aucun effet et ce sont les lignes options timeout:/attempts: de /etc/resolv.conf qui bornent une requête.

MAX_DKIM_SIGNATURES

(nombre, facultatif) Nombre de champs DKIM-Signature d’un message entrant qui sont vérifiés ; ceux dont le d= est le domaine du From: ou un parent ou un enfant de celui-ci passent en premier. Par défaut 10.

VERIFY_TIMEOUT

(durée, facultative) Échéance de la vérification entrante : SPF et les signatures DKIM sélectionnées sont vérifiés en concurrence sous cette échéance, puis DMARC sous une seconde. Une vérification qui la dépasse est consignée comme temperror pour cette seule vérification. Par défaut 20 s.

DISPATCH_WAKE_INTERVAL

(durée, facultative) Écart minimal entre deux NOTIFYs annonçant à pepsi-dispatch(1) que du nouveau courrier est arrivé. Vaut 5 ms par défaut ; 0 désactive le regroupement et notifie une fois par message accepté.

L’ingress ne notifie pas depuis la transaction qui stocke le message. PostgreSQL détient un verrou à l’échelle de la base depuis l’instant où une transaction met une notification en file jusqu’à sa validation : les transactions notifiantes ne peuvent donc pas valider en groupe — sous charge concurrente elles se sérialisent, chacune payant sa propre purge disque. Les admissions sont donc notifiées hors bande, une fois par intervalle, après que les lignes ont été validées ; comme le dispatcher répond à tout réveil par un balayage complet de la file, une seule notification sert un nombre arbitraire de messages nouvellement acceptés.

La limite est traînante : le premier réveil après une période d’inactivité est envoyé immédiatement, de sorte qu’un message isolé n’est pas retardé du tout, et seules les notifications derrière lui sont fusionnées. L’augmenter échange un peu de latence de file dans le pire cas contre moins de notifications sous charge soutenue ; il y a rarement une raison de le faire.

L’identité et l’algorithme de scellement ARC sont configurés dans la section partagée [pepsi] (ARC_DOMAIN et ARC_ALGORITHM) ci-dessus et utilisés par pepsi-stage-arc(1), pas par l’ingress.

85.2.1.1.13. Les sections [pepsi-ingress-listener-*]

Chaque section dont le nom commence par pepsi-ingress-listener- définit une socket d’écoute. Le suffixe est un nom de forme libre utilisé dans les messages de journal, par exemple [pepsi-ingress-listener-mx]. Déclarez autant de listeners que nécessaire.

SERVE

(obligatoire) Le type de socket à lier. L’un de :

tcp

Lier une socket TCP. Nécessite BIND_TO et PORT.

unix

Lier une socket de domaine UNIX. Nécessite UNIXPATH ; honore UNIXPATH_MODE et UNIXPATH_GROUP.

systemd

Adopter une socket passée par un parent systemd via l’activation par socket ; voir FD_INDEX.

BIND_TO

(chaîne) Adresse IP sur laquelle écouter lorsque SERVE = tcp, par exemple 0.0.0.0 ou ::. Requis pour tcp.

PORT

(nombre) Port TCP sur lequel écouter lorsque SERVE = tcp. Requis pour tcp.

UNIXPATH

(chemin) Chemin de système de fichiers de la socket lorsque SERVE = unix. Requis pour unix.

UNIXPATH_MODE

(mode unix, facultatif) Bits de permission de la socket de domaine UNIX, en octal. Par défaut 660.

UNIXPATH_GROUP

(chaîne, facultative) Nom de groupe vers lequel la socket de domaine UNIX est chgrp-ée après la liaison (le propriétaire est inchangé). Combiné avec le mode 0660 par défaut, cela permet à un pair spécifique d’atteindre la socket tout en restant non accessible à tous — utilisé lorsque pepsi-httpd s’exécute derrière un serveur web frontal (par exemple www-data) qui lui fait un reverse-proxy. Le groupe doit exister ; un groupe inconnu est une erreur de démarrage.

FD_INDEX

(nombre, facultatif) Index basé sur zéro du descripteur de fichier passé par systemd à adopter lorsque SERVE = systemd. L’index 0 est le premier descripteur (SD_LISTEN_FDS_START). Par défaut 0.

C’est une position, non un nom : elle compte les entrées ListenStream= de l’unité .socket propriétaire, de sorte qu’en insérer une renumérote chaque listener suivant tandis qu’en ajouter une à la fin n’en renumérote aucun. L’unité et ces sections sont deux moitiés d’une même affirmation et rien ne vérifie leur accord au moment de la configuration : une discordance est donc signalée là où les descripteurs se trouvent réellement — le serveur journalise un avertissement au démarrage nommant chaque index qu’aucun listener n’a revendiqué. Prenez-le au sérieux : une socket sur laquelle le serveur n’accepte jamais est pire qu’une socket absente, car systemd met tout de même la connexion en file et le client bloque jusqu’à l’expiration de son propre délai de lecture au lieu d’être refusé aussitôt.

Un descripteur peut être une socket de domaine UNIX aussi bien qu’une socket TCP ; lequel des deux réside dans l’unité, non ici. Les options qui dépendent de la famille de la socket sont donc résolues une fois le descripteur en main plutôt que pendant l’analyse : AUTH_PEERCRED doit être énoncé explicitement (il ne peut être déduit comme il l’est pour SERVE = unix), et un listener SUBMISSION en clair qui se révèle avoir hérité d’une socket réseau fait refuser le démarrage à pepsi-ingress(1) plutôt que de porter des identifiants en clair.

MODE

(facultatif) Sécurité du transport du listener. L’une de :

plain

En clair uniquement ; STARTTLS n’est pas annoncé. C’est le défaut.

tls

TLS implicite : la connexion est enveloppée dans TLS dès le premier octet (par exemple le port submissions 465). Nécessite TLS_CERT et TLS_KEY.

starttls

En clair pouvant être élevé avec la commande STARTTLS. Nécessite TLS_CERT et TLS_KEY.

TLS_CERT

(chemin) Fichier PEM contenant la chaîne de certificats serveur. Requis lorsque MODE est tls ou starttls — mais peut être omis, auquel cas pepsi-setup(1) remplit automatiquement le chemin certbot /etc/letsencrypt/live/<HOSTNAME>/fullchain.pem et peut obtenir le certificat (voir pepsi-setup(1) et son option –no-certbot).

TLS_KEY

(chemin) Fichier PEM contenant la clé privée pour TLS_CERT. Requis lorsque MODE est tls ou starttls ; comme TLS_CERT, il peut être omis pour que pepsi-setup(1) le remplisse automatiquement (…/privkey.pem).

MYNETWORKS

(facultatif) Liste séparée par espaces/virgules de réseaux CIDR IPv4/IPv6 de confiance (une adresse nue est un hôte /32 ou /128). Une connexion depuis l’un de ceux-ci est authentifiée sans preuve supplémentaire. Vide par défaut.

AUTH_PEERCRED

(facultatif, par défaut ``yes`` sur un listener ``SERVE = unix``, ``no`` ailleurs) Authentifier le client par les identifiants du pair de la socket UNIX rapportées par le noyau (SO_PEERCRED) : l’identifiant d’utilisateur du processus qui se connecte est résolu en un login via la base passwd, et ce login est recherché dans USERNAME_MAP exactement comme le serait un nom d’utilisateur SASL. La session est alors authentifiée et porte une identité de soumission, de sorte que les règles de la RFC 6409 §6/§8.1 s’appliquent — un programme local ne peut utiliser qu’un expéditeur d’enveloppe et un From: auxquels son propre compte est associé, et un compte associé à aucune adresse est refusé.

C’est le mécanisme qui sous-tend pepsi-sendmail(1) et la raison pour laquelle la socket peut sans risque être inscriptible par tous : pouvoir l’ouvrir ne décide en rien de l’identité sous laquelle vous pouvez envoyer. Contrairement à MYNETWORKS, qui fait confiance à une position réseau et laisse donc n’importe quel processus local envoyer au nom de n’importe qui, l’identité est ici fournie par le noyau et ne peut pas être falsifiée par le client.

Rejeté sur un listener SERVE = tcp, où il n’y a pas d’identifiants de pair à lire. Réglez-le sur no pour une socket locale non authentifiée (par exemple derrière un proxy) — mais un tel listener ne peut alors pas être en plus un listener SUBMISSION, puisque rien n’authentifierait.

Avec SERVE = systemd, elle est acceptée mais non déduite et doit donc être écrite explicitement : que le descripteur hérité soit une socket UNIX ou une socket TCP est une propriété de l’unité .socket et non de ce fichier, et la pepsi-ingress.socket livrée passe les deux sortes. Si le descripteur se révèle être une socket TCP, l’option n’authentifie personne — SO_PEERCRED n’y a aucun sens, chaque session reste donc anonyme — ce qui est le sens sûr mais silencieux : pepsi-ingress(1) avertit donc au démarrage en nommant le listener.

SASL_TYPE

(facultatif) Backend SASL pour la commande AUTH : none (par défaut) ou dovecot. AUTH (mécanismes PLAIN et LOGIN) n’est annoncé et accepté que sur une session protégée par TLS ; un AUTH en clair est refusé avec 504 5.5.4 (RFC 4954 §4 – le 538 de la RFC 2554 est obsolète), et un AUTH sur un listener sans backend avec 503 5.5.1. Toute valeur autre que none nécessite MODE tls ou starttls.

SASL_PATH

(chemin) Chemin de la socket auth-client de Dovecot. Requis lorsque SASL_TYPE est dovecot — il n’y a aucune valeur par défaut, et un listener qui demande dovecot sans elle échoue à l’analyse. Le chemin que pepsi-setup propose, /run/dovecot/auth-client-pepsi, est un listener privé à Pepsi plutôt que la socket auth-client partagée de Dovecot : cette dernière est en 0600 dovecot et inaccessible à l’utilisateur non privilégié pepsi-ingress, de sorte que la pointer vers elle donne un listener de soumission dont l”AUTH échoue toujours avec une erreur de permission. pepsi-setup run sonde cette socket en tant qu’utilisateur du service et, si elle est absente ou illisible, propose d’installer un /etc/dovecot/conf.d/10-pepsi.conf qui ajoute un listener dédié possédé par pepsi-ingress (ou l’affiche pour que vous le déployiez).

TLS_AUTH_CLIENT

(facultatif) Liste séparée par espaces/virgules de hashes SHA-256 (64 caractères hex) du SubjectPublicKeyInfo DER des clés publiques de clients ou de CA autorisés. Lorsqu’elle est réglée, le listener demande un certificat client : une session est authentifiée si le hash de clé de la feuille présentée est listé, ou si sa chaîne se valide par signature jusqu’à une clé de CA listée. Un certificat non reconnu n’interrompt pas la poignée de main. Nécessite MODE tls ou starttls. Calculez un hash avec openssl x509 -in cert.pem -noout -pubkey | openssl pkey -pubin -outform DER | openssl dgst -sha256.

SUBMISSION

(facultatif, par défaut ``no``) Lorsque yes, le listener est un agent de soumission de messages RFC 6409 : l’authentification devient obligatoire (un MAIL FROM non authentifié est refusé avec 530 5.7.0), et chaque message accepté reçoit les corrections de soumission — un Date: et un Message-ID: manquants sont ajoutés. Nécessite au moins un mécanisme d’authentification (SASL_TYPE, TLS_AUTH_CLIENT, MYNETWORKS ou AUTH_PEERCRED) ; un listener de soumission qui n’en a aucun est rejeté. Laissez-le désactivé pour un listener MX (port 25).

Un MODE TLS est également requis, sauf sur un listener SERVE = unix : une socket de système de fichiers n’a aucun transport qu’un attaquant pourrait observer ou sur lequel il pourrait s’interposer, et son authentification vient du noyau plutôt que du réseau, de sorte qu’y exiger un certificat ne protégerait rien.

Une session acceptée par l’un de MYNETWORKS, AUTH_PEERCRED, SASL AUTH ou TLS_AUTH_CLIENT est enregistrée avec state.local_origin = true (sinon false) et peut relayer vers n’importe quel domaine, pas seulement les domaines servis.

85.2.1.1.14. Le pipeline d’étapes et les sections [stage-*]

Après l’ingress, un message est avancé par une chaîne de programmes d’étape. pepsi-dispatch(1) revendique une ligne pending, la met running et remet l’identifiant du message à un processus worker persistant de cette étape — démarré comme PROGRAM [-c FILE] worker et alimenté en identifiants sur son entrée standard, un par ligne, répondant par une ligne de statut chacun — et le programme fait son travail et fait avancer la ligne (ou la termine). Il n’y a pas d’invocation par identifiant positionnel : un PROGRAM qui est un script enveloppe doit donc transmettre ses arguments et son entrée standard. Les nouveaux messages entrent à l’étape initiale, [stage-init], qui doit exister.

Chaque section dont le nom commence par stage- décrit une étape. Le suffixe est le nom de l’étape, par exemple [stage-init]. Le nom de l’étape est un label choisi par l’opérateur, indépendant du binaire qu’elle exécute.

PROGRAM

(chaîne, obligatoire) Le binaire d’étape à exécuter, par exemple pepsi-stage-relay-to-smarthost. Il est localisé sur le PATH sauf s’il est donné comme un chemin absolu. Le même binaire peut servir plusieurs étapes (il lit ses options depuis la section où le message se trouve actuellement).

NEXT_STAGE

(chaîne, facultative) L’étape vers laquelle un message avance en cas de succès. En son absence, une étape terminale réussie supprime le message.

BOUNCE_STAGE

(chaîne, facultative) L’étape vers laquelle un message est acheminé pour qu’une notification d’état de remise soit générée. Pour les étapes de remise (pepsi-stage-relay-to-smarthost(1), pepsi-stage-relay-to-internet(1)) et pepsi-stage-discard(1), elle reçoit un message ayant échoué de façon permanente (non-rebond) pour un rebond, et — lorsque [pepsi] ORIGINATE_SUCCESS_DSN est activé — un message remis avec succès pour un rapport positif. En son absence, un message ayant échoué de façon permanente est marqué failed (étapes de remise) ou simplement abandonné (pepsi-stage-discard(1)).

PARALLELISM

(nombre, facultatif) Borne supérieure du nombre de processus workers concurrents que pepsi-dispatch(1) exécute pour cette étape. Les workers sont démarrés à la demande et arrêtés à l’inactivité, c’est donc un plafond, pas une taille de pool fixe. Chaque worker détient une connexion de base de données, de sorte que cela borne aussi la part de l’étape dans le budget de connexions (voir la note [pepsi-postgres] ci-dessus). Par défaut 4. Le dispatcher abaisse temporairement une étape en dessous de cette valeur lorsque la base de données rapporte que sa limite de connexions est épuisée (voir pepsi-dispatch(1)).

MAX_MESSAGES

(nombre, facultatif) Nombre de messages qu’un worker de cette étape traite avant que le dispatcher ne le retire et démarre un nouveau processus (bornant la croissance de la mémoire). Par défaut 1000.

QUEUE_LIMIT

(nombre, facultatif) Borne supérieure du nombre de messages que pepsi-dispatch(1) pipeline vers un seul processus worker de cette étape à la fois. Le worker les traite tout de même strictement un à la fois, mais avoir les identifiants suivants déjà en file sur son entrée standard supprime un aller-retour de coordinateur par message, de sorte que la capacité totale en vol de l’étape est QUEUE_LIMIT × PARALLELISM. Comme le nombre de workers (et donc le budget de connexions) est inchangé, relever cela échange un peu de latence de tête de file (un message peut attendre derrière un frère pipeliné plus lent sur le même worker) contre du débit, sans dépenser plus de connexions de base de données ; abaissez-le (par exemple à 1) pour une étape dont le travail par message est long et inégal, comme un relais réseau. Par défaut 4.

MAX_LIFETIME

(durée, facultatif) Combien de temps un message peut continuer à échouer à cette étape — avec toute erreur que l’étape ne marque pas comme permanente, c’est-à-dire une défaillance de l’hôte plutôt que du message, comme une configuration de résolveur illisible, un helper qui ne peut être démarré ou un modèle qui ne peut être lu — avant que le worker n’abandonne, compté à partir de sa mise en file (pour un DSN, à partir du moment où pepsi-stage-bounce(1) l’a construit). Jusque-là, le message est mis en pause et réessayé, après une minute puis deux fois plus longtemps à chaque fois, jusqu’à une heure, avec l’erreur dans state.last_error. Il est ensuite réacheminé vers le BOUNCE_STAGE de cette étape, ou mis en échec s’il n’y en a pas (voir pepsi-dispatch(1)). Les étapes de remise et pepsi-stage-milter(1) lisent la même option pour leurs propres réessais. Par défaut 120 h.

FUSION = yes | no

(facultatif) Si une étape prédécesseur peut exécuter cette étape dans son propre processus worker au lieu d’écrire la ligne pending et d’attendre que le dispatcher la revendique (fusion d’étapes ; voir [pepsi] ALLOW_FUSION ci-dessus et pepsi-dispatch(1)). La fusion n’a lieu que lorsqu’elle est aussi activée globalement, que le PROGRAM de cette étape est plié dans le binaire pepsi unifié, et que cette étape n’a besoin d’aucune colonne de message que le prédécesseur n’a pas déjà chargée — elle est donc refusée (et l’avancement retombe sur un saut dispatché normal) chaque fois que l’une de ces conditions ne tient pas, ce qui est toujours sûr. Par défaut yes pour les étapes rapides de routage/classification sans corps — pepsi-stage-if(1), pepsi-stage-discard(1), pepsi-stage-srs(1), pepsi-stage-check-whitelist(1), pepsi-stage-auto-whitelist(1), pepsi-stage-block-language(1), pepsi-stage-list(1) et pepsi-stage-edit-settings(1) (qui est sans corps pour tout message qui n’est pas un message de contrôle, c’est-à-dire pratiquement tous) — et no pour tout autre programme. Deux d’entre elles ont besoin du bloc d’en-têtes plutôt que de la seule enveloppe — pepsi-stage-block-language(1), dont le chemin ENFORCEMENT = soft réécrit le Subject:, et pepsi-stage-check-whitelist(1), qui lit List-Id: — chacune ne fusionne donc que dans un prédécesseur qui l’avait déjà chargé. Lister un programme ici ne fixe que la valeur par défaut de son option FUSION ; qu’une paire donnée puisse effectivement fusionner se décide par paire, à l’exécution.

Les options restantes dans une section [stage-<name>] dépendent de son PROGRAM. Les sous-sections ci-dessous documentent les options que chaque programme d’étape lit depuis sa propre section ; une section ne lit que les clés listées pour son PROGRAM plus les clés générales ci-dessus.

Certains programmes font exception et sont documentés uniquement dans leurs propres pages de manuel, car leurs ensembles d’options sont vastes et changent avec le mécanisme de remise qu’ils pilotent : pepsi-stage-relay-to-maildir(1) (dont SERVER_NAME est obligatoire — l’étape refuse de démarrer sans lui — plus HELPER, UNKNOWN_MAILBOX_STAGE, QUOTA_LIMIT_STAGE, la famille RETRY_*, MAX_LIFETIME et les options de localité LOCAL_DOMAINS, TARGETS et RECIPIENT_DELIMITER), pepsi-stage-relay-to-lmtp(1) (SOCKET ou HOST/PORT, TLS, TLS_VERIFY, TLS_CA, TLS_CLIENT_CERT/TLS_CLIENT_KEY, AUTH, USERNAME, PASSWORD, SERVER_NAME, QUOTA_LIMIT_STAGE, SIEVE_REJECT_STAGE, NOTIFY_STAGE et les timeouts), pepsi-stage-dot-forward(1) (HELPER, RESTART_STAGE, ALLOW_PIPE, ALLOW_FILE et les options de localité) et les étapes de listes de diffusion pepsi-stage-list(1) (POST_STAGE, COMMAND_STAGE), pepsi-stage-list-post(1) (DELIVERY_STAGE, RESPONSE_STAGE, REMOVE_DKIM_HEADERS, SITE_HEADER_MATCH_CHAIN, SENDER_POSTS_PER_HOUR, MAX_HELD_MESSAGES), pepsi-stage-list-deliver(1), pepsi-stage-list-command(1) (RESPONSE_STAGE, MAX_COMMAND_LINES) et pepsi-stage-list-bounce(1) (RESPONSE_STAGE), dont les options valables pour tout le site se trouvent dans [pepsi-list] ci-dessous. Tout ce que cette page dit de [stage-<name>] en général leur reste applicable. Les sections partagées sur lesquelles ces programmes s’appuient aussi sont documentées ailleurs sur cette page : [pepsi] (identité de signature), [pepsi-srs] (le moteur SRS), [pepsi-payments] (le backend marchand) et les sections smarthost [pepsi-stage-relay-to-smarthost-mta-*].

85.2.1.1.14.1. Options de pepsi-stage-arc

Une étape avec PROGRAM = pepsi-stage-arc lit, outre un NEXT_STAGE obligatoire, ses paramètres DNS et les paramètres de signature de l’ensemble ARC qu’elle ajoute (ceux-ci s’appliquent à l’ARC-Message-Signature ; l’ARC-Seal est toujours canonicalisé en relaxed sur un ensemble d’en-têtes fixe, conformément à la RFC 8617) :

DNS_SERVERS

(chaîne, facultative) Résolveurs explicites séparés par espaces/virgules (port 53) pour les recherches SPF/DKIM/DMARC/ARC. Lorsqu’il n’est pas réglé, le resolv.conf système est utilisé.

DNS_TIMEOUT

(durée, facultative) Timeout DNS par requête. Par défaut 5 s.

HEADER_CANONICALIZATION

(``relaxed`` | ``simple``, facultatif) Canonicalisation des en-têtes de l’AMS (la moitié gauche de c=). Par défaut relaxed.

BODY_CANONICALIZATION

(``relaxed`` | ``simple``, facultatif) Canonicalisation du corps de l’AMS (la moitié droite de c=). Par défaut relaxed. ARC prend en charge toute combinaison des deux.

SIGNATURE_EXPIRATION_DAYS

(entier, facultatif) Lorsqu’il est réglé sur un nombre positif de jours, l’AMS porte une expiration (x=) ce nombre de jours après la signature. Non réglé (le défaut) n’émet aucune expiration. L’ARC-Seal n’a pas de balise x= dans la RFC 8617 et n’en porte jamais, quoi que dise cette option.

SIGNED_HEADERS

(chaîne, facultative) Liste séparée par espaces/virgules des en-têtes que l’AMS couvre (h=). Doit inclure From. Par défaut l’ensemble d’en-têtes originateur/MIME intégré.

L’identité de signature ARC, le répertoire de clés, le sélecteur et l’algorithme proviennent de la section partagée [pepsi] (ARC_DOMAIN, ARC_ALGORITHM, KEY_DIR, DKIM_SELECTOR). Le hachage est toujours SHA-256 ; l’algorithme de signature (a=) est l’unique choix [pepsi] ARC_ALGORITHM, puisque ARC permet une signature par saut.

85.2.1.1.14.2. Options de pepsi-stage-srs

Une étape avec PROGRAM = pepsi-stage-srs n’a besoin que d’un NEXT_STAGE dans sa propre section [stage-<name>] ; tous ses paramètres (SRS_DOMAIN, SECRET/SECRET_FILE, MAX_AGE_DAYS) résident dans la section partagée [pepsi-srs] documentée ci-dessus, de sorte qu’ils sont identiques au décodage inverse de l’ingress.

85.2.1.1.14.3. Options de pepsi-stage-encrypt

Une étape avec PROGRAM = pepsi-stage-encrypt signe le courrier soumis localement au nom de l’auteur de son From: et le chiffre pour chaque destinataire. Elle lit, outre un NEXT_STAGE obligatoire et un BOUNCE_STAGE facultatif :

Avertissement

Placez cette étape avant l’étape de signature DKIM, non après : … → encrypt → srs → dkim-sign → relay. DKIM doit signer les octets réellement transmis, et cette étape réécrit le corps. Signer d’abord produit du courrier qui a l’air valide et dont la signature ne se vérifie pas — pire qu’aucune signature, car une signature cassée est un signal négatif plus fort pour un destinataire qu’une signature absente. pepsi-setup(1) avertit lorsqu’il trouve une étape de signature DKIM qui mène à celle-ci.

Le péage à l’envoi et la détection de langue lisent tous deux le corps du message et veulent toutes deux du texte clair ; sur le chemin sortant elles s’exécutent avant cette étape, ce qui explique que le chiffrement vienne en dernier.

Chaque option ci-dessous est comportementale et redéfinissable par adresse via la table pepsi.settings (pepsi-settings(1)), indexée pour le courrier sortant sur l”expéditeur d’enveloppe. La politique cryptographique — algorithmes, permission de rétrograder, tailles de clé minimales — se trouve dans les options CRYPTO_* de [pepsi] et dans [pepsi-crypto], est réservée à l’administrateur système, et n’est délibérément pas atteignable d’ici.

ENABLE_PEP

(booléen, facultatif) Se comporter comme le projet pretty Easy privacy (pEp) : chaque expéditeur local d’un domaine servi reçoit une clé à son premier message, le courrier est chiffré chaque fois que la clé d’un destinataire est connue ou découvrable, et la clé de l’expéditeur part avec chaque message. YES par défaut.

Un préréglage de valeurs par défaut, et non un mode contraignant : il change la valeur par défaut de SIGN en encrypted-only et active la création anticipée des clés. Toute option écrite explicitement l’emporte toujours. Avec ENABLE_PEP = no, SIGN vaut par défaut opportunistic et les clés ne sont créées que sur demande explicite (signer ou chiffrer) ou sous SIGN = always. La création anticipée requiert en outre [pepsi-crypto] AUTO_CREATE_IDENTITY (le veto de l’opérateur, qu’aucune redéfinition par adresse n’atteint) et un KEY_WRAP_SECRET, et n’a lieu que pour une adresse d’un domaine de [pepsi-ingress] ACCEPTED_DOMAINS qui n’a aucune ligne crypto_identity d’aucune sorte. Un utilisateur peut s’en retirer avec ENABLE_PEP = no dans sa propre redéfinition pepsi.settings, là où EDITABLE_STAGES le permet. Aucun format de transmission pEp n’est produit : pas d’en-tête X-pEp-Version, pas d’enveloppement pEp 2.x, pas de trustwords et pas de synchronisation de clés. Voir pepsi-stage-encrypt(1).

SIGN

(``no`` | ``encrypted-only`` | ``opportunistic`` | ``always``, facultatif) S’il faut signer avec la clé de l’auteur du From:. encrypted-only par défaut sous ENABLE_PEP, sinon opportunistic.

encrypted-only ne signe qu’un message que cette étape chiffre, à l’intérieur du texte chiffré ; le courrier en clair porte la clé de l’expéditeur mais aucune signature, de sorte qu’un destinataire qui n’utilise pas la cryptographie ne voit jamais de signature.asc. Une demande explicite (X-Pepsi-Sign: yes, un mot-clé [sign] dans le sujet) signe tout de même le texte en clair. opportunistic signe lorsque l’auteur dispose de matériel utilisable, et envoie non signé sinon. always signe de la même façon et fait en outre créer une identité pour un auteur qui n’en a pas, aux mêmes conditions que la création anticipée d”ENABLE_PEP (AUTO_CREATE_IDENTITY, un KEY_WRAP_SECRET, un domaine servi, aucune identité d’aucune sorte), sauf si X-Pepsi-Sign: no a refusé la signature. Aucun n’est une garantie — un auteur que ce déploiement ne sert pas voit son courrier envoyé non signé plutôt que rebondi. Un message que le client soumetteur a déjà signé ne reçoit pas de seconde signature de Pepsi, et un message que le client a déjà chiffré est laissé entièrement tel quel.

ENCRYPT

(``no`` | ``opportunistic`` | ``required``, facultatif) opportunistic par défaut : chiffrer vers un destinataire dont nous avons une clé utilisable, envoyer du courrier ordinaire à celui dont nous n’en avons pas. required signifie qu’un destinataire sans clé utilisable reçoit le lien sécurisé ou un rebond, jamais du texte clair.

PREFER

(``openpgp`` | ``smime``, facultatif) Vers quel protocole se tourner lorsqu’un correspondant dispose de matériel utilisable pour les deux. openpgp par défaut ; pgp est accepté comme synonyme.

ON_NO_KEY

(``cleartext`` | ``secure-link`` | ``bounce``, facultatif) Ce qui arrive à un destinataire sans clé utilisable. Valeur par défaut dérivée d’ENCRYPT : cleartext pour no/opportunistic, et pour required soit secure-link (lorsque SECURE_LINK_STAGE est réglé) soit bounce. Le régler explicitement redéfinit cela — sauf qu’un message dont la propre demande a élevé la politique à required ne retombe jamais sur cleartext.

Prudence

ON_NO_KEY = cleartext conjugué à [pepsi] CRYPTO_ALLOW_DOWNGRADE = no envoie du texte clair à un correspondant dont la clé ne sait pas lire l’AES-GCM — strictement pire que le SEIPDv1+MDC que l’option visait à éviter, et l’essentiel du parc OpenPGP installé (GnuPG 2.4 et antérieurs) est dans ce cas. pepsi-setup(1) avertit sur cette paire. Laissez l’option tranquille : negotiate (compilé) comme yes (ce que livre config.d) rétrogradent plutôt que de refuser, et sous negotiate seulement lorsque la clé même du destinataire prouve qu’il le faut.

ON_OVERSIZE

(``cleartext`` | ``secure-link`` | ``bounce``, facultatif) Ce qui arrive à un message plus grand que MAX_SIZE. Valeurs par défaut exactement comme pour ON_NO_KEY, de sorte que required ne devienne pas du texte clair parce qu’une pièce jointe était volumineuse.

MAX_SIZE

(nombre, facultatif) Plus grand message, en octets, que cette étape chiffrera. 25000000 par défaut (25 Mo). Ni le constructeur CMS ni les chemins OpenPGP ne diffusent en flux, de sorte que tout le message est résident pendant son chiffrement, une fois par destinataire ; un plafond visible est ce qui garde le plafond mémoire par worker prévisible au lieu de laisser PARALLELISM workers détenir chacun un message de plusieurs centaines de mégaoctets.

MIN_TRUST

(``own`` | ``manual`` | ``dane`` | ``wkd-advanced`` | ``wkd-direct`` | ``ldap`` | ``vks`` | ``owner-confirmed`` | ``harvested`` | ``gossip`` | ``any``, facultatif) La source de clé la moins bien classée vers laquelle cette étape chiffrera. Vaut par défaut [pepsi-keydiscovery] MIN_TRUST, de sorte qu’un déploiement n’ait qu’un plancher à moins d’en vouloir délibérément deux. Voir La section [pepsi-keydiscovery] pour le classement, pour la raison pour laquelle le plancher par défaut accepte tout, et pour la différence entre harvested et gossip.

SUBJECT_KEYWORDS_SIGN, SUBJECT_KEYWORDS_ENCRYPT, SUBJECT_KEYWORDS_BOTH

(liste séparée par virgules, facultative) Mots-clés qu’un expéditeur peut placer n’importe où dans le Subject pour demander une protection. Par défaut [sign], [encrypt] et [secure]. Comparés sans distinction de casse ; le mot-clé trouvé est retiré du Subject sortant. Un mot-clé de chiffrement élève la politique à required pour ce message — lire une demande humaine délibérée comme « essayer, et renoncer en silence » ferait de la fonctionnalité un mensonge. Ce sont des virgules, non des espaces, qui séparent la liste, car un mot-clé peut légitimement contenir une espace.

STRIP_REQUEST_HEADERS

(booléen, facultatif) Retirer chaque champ X-Pepsi-* du message sortant. YES par défaut. Les deux en-têtes sur lesquels cette étape agit (X-Pepsi-Sign, X-Pepsi-Encrypt) sont retirés inconditionnellement, quoi que dise ceci : un canal de commande qui survit jusque sur le fil est un canal auquel on peut ordonner au saut suivant d’obéir. Cette option ne décide que du sort des autres champs X-Pepsi-* qu’un module d’extension aurait pu ajouter. Pepsi-Origin n’appartient pas à cet espace de noms et n’est jamais touché.

PROTECT_HEADERS

(booléen, facultatif) Copier les champs d’en-tête de la RFC 5322 dans la partie protégée et remplacer le Subject extérieur par ... — ce que Thunderbird implémente pour PGP/MIME. NO par défaut : la prise en charge par les clients est inégale, et le mode de défaillance est un message dont le sujet se lit ... dans un client incapable de regarder à l’intérieur.

AUTOCRYPT

(booléen, facultatif) Annoncer la clé OpenPGP propre à l’auteur du From: dans un en-tête Autocrypt:. YES par défaut, et sur chaque message soumis localement — signé, chiffré ou en clair — car un correspondant doit apprendre la clé depuis du courrier ordinaire avant qu’il n’y ait quoi que ce soit à chiffrer.

La clé est réduite à la forme minimale à cinq paquets d’Autocrypt Level 1 §2.1.1. Seul OpenPGP est annoncé (Autocrypt n’a pas de forme S/MIME), seulement pour une identité qui détient encore son matériel privé, et jamais sur un message portant déjà un champ Autocrypt: — l’en-tête propre à un vrai client nomme la clé avec laquelle il peut déchiffrer, et un second champ fait écarter les deux par les analyseurs Level 1. prefer-encrypt=mutual n’est revendiqué que lorsque l”ENCRYPT effectif vaut required ; voir pepsi-stage-encrypt(1).

Rien n’est annoncé lorsque la face publique de l’adresse est la propre clé MUA de l’utilisateur (custody = client), ni sur un message que le client a déjà chiffré : le client de messagerie annonce sa propre clé.

Désactivez-le pour limiter la publication des clés au Web Key Directory et au DNS, ce qui est un choix défendable pour un déploiement qui ne veut pas que les clés de ses utilisateurs voyagent sur chaque message qu’ils envoient.

ATTACH_KEYS_AS_FILES

(booléen, facultatif) Joindre aussi la clé publique de l’expéditeur sous forme d’un fichier application/pgp-keys nommé OpenPGP_0x<long key ID>.asc, la manière classique d’OpenPGP, en plus de l’en-tête Autocrypt:. NO par défaut, indépendamment d”ENABLE_PEP ; un opérateur qui ne veut que le fichier positionne aussi AUTOCRYPT = no.

Sur un message chiffré, le fichier va à l’intérieur du texte chiffré ; en clair, le message est enveloppé dans un multipart/mixed (ou la clé est ajoutée à un existant). Il est joint jusqu’à ce que chaque destinataire détienne la clé de façon prouvée – il a renvoyé un message chiffré pour elle et signé par lui, consigné dans pepsi.peer_has_own_key – et recommence pour une nouvelle clé. Jamais lorsque la face publique est la propre clé MUA de l’utilisateur, jamais sur du courrier que le client a chiffré, et pas sur du texte en clair que le client a signé.

KEYS_CONTROL_LOCAL_PART

(chaîne, facultative) Partie locale de l’adresse à laquelle un utilisateur gère ses propres clés par e-mail : un message soumis localement dont l’unique destinataire est <KEYS_CONTROL_LOCAL_PART>@<served domain> est une commande (status, generate, register, publish [FPR], retire FPR dans le Subject:), consommée et traitée par une réponse injectée à RESPONSE_STAGE. pepsi-keys par défaut ; none désactive cette surface. Requiert RESPONSE_STAGE.

RESPONSE_STAGE

(nom d’étape, facultatif) Où sont injectés, comme nouveaux messages à expéditeur nul, les réponses aux commandes de clés par e-mail et les avis « une nouvelle clé a été enregistrée pour votre adresse ». Normalement l’étape sortante de signature DKIM, ce qu’écrit pepsi-setup –wizard (dkim-sign). Non défini signifie ni avis ni commandes par e-mail (le courrier de contrôle est alors transmis comme tout autre message) ; pepsi-setup(1) en avertit, refuse un nom qui n’est pas une étape, et exige les modèles de repli key-registered.en.body et keys.en.body lorsqu’elle est définie.

AUTOCRYPT_GOSSIP

(booléen, facultatif) Annoncer les clés OpenPGP des autres destinataires dans des champs Autocrypt-Gossip: (Autocrypt Level 1 §5.3), afin que deux correspondants qui ne se sont jamais écrit puissent néanmoins se répondre en chiffré après un seul message. NO par défaut.

Désactivé par défaut parce que ce n’est pas le même genre d’acte qu”AUTOCRYPT : celui-ci publie une clé dont le propriétaire a demandé à ce déploiement de la détenir, tandis que celui-là redistribue les clés de tiers — du matériel simplement mis en cache ici — à des correspondants qui ne les ont pas demandées.

Cela ne s’applique qu’à un message que cette étape chiffre réellement, et les champs vont à l’intérieur du texte chiffré, jamais sur le bloc d’en-tête extérieur : leur objet même est de présenter les destinataires les uns aux autres sans divulguer l’ensemble des destinataires au réseau. Il n’y a donc pas de gossip sur le passage en clair, sur un message signé mais non chiffré, ni sur un conteneur S/MIME (Autocrypt est défini au-dessus d’OpenPGP et n’a pas de forme S/MIME). Un champ est émis par destinataire présenté — contrairement à Autocrypt:, où un second champ fait écarter le message par un analyseur Level 1 — et prefer-encrypt n’apparaît jamais, puisqu’il énonce la politique propre à l’expéditeur alors que ce champ parle pour quelqu’un d’autre.

Avertissement

Les copies cachées ne sont jamais gossipées. Les adresses annoncées sont lues dans les champs To: et Cc: analysés du message et nulle part ailleurs ; la liste des destinataires d’enveloppe n’est consultée que pour retirer une adresse de l’ensemble. Un destinataire en Bcc figure sur l’enveloppe et dans aucun des deux champs, de sorte qu’aucune copie du message ne puisse porter un en-tête le nommant — et c’est la propriété sur laquelle compter, car un en-tête de gossip pour un destinataire caché indiquerait à chaque autre destinataire qu’un destinataire caché existe et qui il est. Cela tient même si un champ Bcc: a été laissé sur le message par un client de soumission défectueux, puisque le champ n’est pas lu.

La réciproque est délibérée : la copie propre d’un destinataire caché porte bel et bien du gossip sur les destinataires To:/Cc:. Il a reçu ces champs d’en-tête comme tout le monde : cela ne divulgue donc rien qu’il ne puisse déjà lire, et c’est ce qui lui permet de répondre en chiffré.

Un destinataire pour lequel ce déploiement ne détient aucune clé en cache est simplement laissé de côté — l’étape n’effectue aucune découverte de clé en son nom et ne retarde jamais un message pour aller chercher la clé d’un tiers. Un message comptant plus de 50 destinataires visibles ne reçoit aucun gossip : à cette taille c’est une diffusion plutôt qu’une conversation, chaque clé présentée est répétée dans le texte chiffré de chaque destinataire, et présenter un sous-ensemble arbitraire serait pire que n’en présenter aucun.

GOSSIP_MIN_TRUST

(``own`` | ``manual`` | ``dane`` | ``wkd-advanced`` | ``wkd-direct`` | ``ldap`` | ``vks`` | ``owner-confirmed`` | ``harvested`` | ``gossip`` | ``any``, facultatif) La source de clé de plus bas rang dont la clé peut être republiée dans un champ Autocrypt-Gossip:. Par défaut owner-confirmed — le plus faible échelon auquel quelqu’un ayant droit sur l’adresse a fait une démarche délibérée pour publier la clé.

C’est un vrai resserrement par rapport à MIN_TRUST, et délibérément : chiffrer vers une clé en confiance au premier usage est un bon échange, car l’alternative est le texte clair, mais remettre cette clé à des tiers est un autre acte. Une clé transmise par gossip est stockée par chacun de ses destinataires à un échelon qu’ils jugent sur notre parole et non sur la façon dont nous y sommes venus : transmettre une supposition la blanchit donc en quelque chose qui a l’air d’une connaissance.

Le plancher réellement appliqué est le plus strict de celui-ci et de MIN_TRUST : présenter à un correspondant une clé vers laquelle cette étape ne chiffrerait pas elle-même reviendrait à recommander ce qu’elle a refusé. Relever l’une ou l’autre option resserre donc le gossip, abaisser l’une ou l’autre ne peut pas le desserrer au-delà de la seconde, et un opérateur qui durcit MIN_TRUST n’a pas à se souvenir qu’une seconde option existe. GOSSIP_MIN_TRUST = any transmet par gossip tout ce vers quoi il est permis de chiffrer. Sans effet si AUTOCRYPT_GOSSIP n’est pas activé.

SECURE_LINK_STAGE

(nom d’étape, facultatif) Où est envoyé un destinataire empruntant la voie secure-link. Requis si ON_NO_KEY/ON_OVERSIZE se résout en secure-link.

DISCOVERY

(booléen, facultatif) Si un défaut de cache peut déclencher une consultation réseau ; documenté sous L’interrupteur par expéditeur : [stage-encrypt] DISCOVERY.

DISCOVERY_TIMEOUT

(temporel, facultatif) Redéfinit [pepsi-keydiscovery] TIMEOUT pour les garages que crée cette étape. Notez que Section::duration() rejette les unités calendaires : 90 s et 2 h s’analysent, 1 d non.

Une identité d’auteur que cette étape crée ou enregistre est attribuée à un login passwd via les options LOCAL_DOMAINS, TARGETS et RECIPIENT_DELIMITER de [pepsi-crypto], comme pepsi-keys(1) en attribue une, de sorte que la règle de propriété de La section [pepsi-crypto] ne dépend pas du programme qui a fait la clé. Une adresse qui ne se résout vers aucun compte local est un état légitime (une adresse de rôle ou un domaine hébergé), non un échec. Qu’une identité puisse être créée du tout est réglé par [pepsi-crypto] AUTO_CREATE_IDENTITY, et cela n’est proposé que pour un auteur dans un domaine de [pepsi-ingress] ACCEPTED_DOMAINS.

Le binaire est installé setuid pepsi-crypto, mode 4750 pepsi-crypto:pepsi, parce qu’il doit être l’unique rôle de base à qui crypto_identity.private_wrapped est accordé — l’authentification par pair se fonde sur l’uid effectif — et doit lire le fragment de clé de chiffrement de clés en 0640 appartenant au même compte. Voir pepsi-stage-encrypt(1).

85.2.1.1.14.4. Options de pepsi-stage-decrypt

Une étape avec PROGRAM = pepsi-stage-decrypt déchiffre le courrier adressé aux destinataires que cet hôte sert et vérifie la signature qu’il porte. Elle lit, outre un NEXT_STAGE obligatoire et un BOUNCE_STAGE facultatif :

ENABLED

(booléen, facultatif) S’il faut faire de la cryptographie du tout. YES par défaut. NO retire tout de même l’espace de noms d’en-têtes X-Pepsi-* du courrier entrant : une étape désactivée ne doit pas devenir un canal pour un indicateur falsifié.

LOCAL_DOMAINS, TARGETS, RECIPIENT_DELIMITER

(facultatif) Quels destinataires cet hôte sert — les mêmes options, avec les mêmes valeurs par défaut, que pepsi-stage-relay-to-maildir(1) et pepsi-stage-dot-forward(1). LOCAL_DOMAINS vaut par défaut [pepsi-ingress] ACCEPTED_DOMAINS.

REQUIRE_ACCOUNT

(booléen, facultatif) Si un destinataire local doit en outre se résoudre vers un compte passwd autorisé par TARGETS. NO par défaut, ce qui est la différence avec les étapes de remise : elles doivent savoir quelle boîte écrire, tandis que cette étape n’a qu’à savoir si le message est le nôtre. Un domaine hébergé dont les utilisateurs détiennent des identités cryptographiques mais aucun compte shell est un déploiement ordinaire.

ON_DECRYPT_FAILURE

(``passthrough`` | ``quarantine`` | ``bounce``, facultatif) Que faire d’un message que cet hôte n’a pas pu ouvrir. passthrough par défaut : l’utilisateur détient peut-être la clé dans son propre client, et faire rebondir du courrier que nous n’avons simplement pas su ouvrir n’aide personne. quarantine exige QUARANTINE_STAGE ; bounce exige BOUNCE_STAGE.

ON_BAD_SIGNATURE

(``record`` | ``quarantine`` | ``bounce``, facultatif) Que faire d’un message dont la signature ne s’est pas vérifiée. record par défaut : les listes de diffusion qui réécrivent les corps, les redirections et les clients à la canonicalisation défectueuse produisent tous de mauvaises signatures sur du courrier parfaitement légitime. Seul le verdict invalid compte ici comme mauvais — valid-untrusted et unverifiable sont l’état normal du courrier d’un correspondant inconnu et ne sont jamais acheminés.

QUARANTINE_STAGE

(nom d’étape, facultatif) Où mène une voie quarantine. Requis si l’une des politiques ci-dessus est réglée sur quarantine.

SUBJECT_TAGS

(booléen, facultatif) Préfixer au Subject les étiquettes acquises dans l’ordre d’imbrication — encrypted(signed(body)) donne [decrypted][verified] … et signed(encrypted(body)) donnerait [verified][decrypted] …. YES par défaut : pour la plupart des utilisateurs c’est le seul signal qu’ils verront jamais. Le coût est un champ visible par l’utilisateur qui se trouve muté, ce qui affecte la recherche, le fil de discussion et les sujets cités dans les réponses. (Les deux formes s’ouvrent. La seconde n’acquiert [verified] que d’une signature à l’intérieur du texte chiffré : une signature extérieure couvre du texte chiffré et n’atteint jamais le verdict valid pour lequel l’étiquette est écrite — voir pepsi-stage-decrypt(1).)

TAG_DECRYPTED, TAG_VERIFIED

(chaîne, facultative) La formulation des étiquettes. Par défaut [decrypted] et [verified]. TAG_VERIFIED n’est écrite que pour le verdict valid.

TAG_BAD_SIGNATURE

(chaîne, facultative) L’étiquette du verdict invalid. Vide par défaut : une mauvaise signature est une propriété courante du courrier légitime, si bien qu’une étiquette activée par défaut décorerait une grande partie de la boîte de réception d’un utilisateur d’une accusation.

STRIP_SUBJECT_TAGS

(booléen, facultatif) Retirer le vocabulaire d’étiquettes propre à cette étape du début d’un Subject entrant avant d’y préfixer le nôtre. YES par défaut, et de fait obligatoire : sans cela, un expéditeur externe écrit simplement [verified] lui-même. Le vocabulaire est dérivé des trois options TAG_* plus les [decrypted] et [verified] intégrés, de sorte que renommer une étiquette ne puisse rouvrir la brèche.

STRIP_SUBJECT_KEYWORDS

(liste séparée par virgules, facultative) Étiquettes de sujet entrantes supplémentaires à retirer. Des virgules plutôt que des espaces, car un mot-clé peut contenir une espace.

ADD_RESULT_HEADER

(booléen, facultatif) Ajouter l’en-tête de résultat X-Pepsi-Crypto à un message qui portait une protection. YES par défaut. Sa grammaire est documentée dans pepsi-stage-decrypt(1). Chaque champ X-Pepsi-* est d’abord retiré du courrier entrant, inconditionnellement et quoi que dise cette option — c’est ce retrait qui rend l’en-tête crédible.

MAX_LAYERS

(entier, facultatif) Combien de couches chiffrées imbriquées sont déballées. 4 par défaut. Un message qui en compte davantage est remis avec le reste non ouvert.

TRUST_ANCHOR_TTL

(temporel, facultatif) Combien de temps un processus worker réutilise les ancres ca_trust qu’il a lues en dernier. 5 m par défaut. Une ancre ajoutée ou désactivée prend effet dans cette fenêtre ; redémarrez les workers pour l’appliquer aussitôt. Les unités calendaires sont rejetées (5 m et 2 h s’analysent, 1 d non).

DISCOVERY

(booléen, facultatif) Si un défaut de cache peut déclencher une consultation réseau ; documenté sous L’interrupteur par expéditeur : [stage-encrypt] DISCOVERY. Lue depuis cette section par le même lecteur, de sorte que les deux étapes cryptographiques ne puissent pas être en désaccord sur son nom ou sur sa valeur par défaut.

DISCOVERY_TIMEOUT

(temporel, facultatif) Redéfinit [pepsi-keydiscovery] INBOUND_TIMEOUT pour les garages que crée cette étape.

[pepsi] CRYPTO_ALLOW_DOWNGRADE ne conditionne pas ce sens. Le SEIPDv1+MDC OpenPGP et l”EnvelopedData CMS AES-CBC sont toujours lisibles, quoi que dise la politique d’émission : les refuser en entrée rendrait cet hôte incapable de recevoir du courrier de la majeure partie du monde sans protéger personne. Seuls le 3DES et les condensats de signature faibles sont conditionnés en entrée, et chaque refus produit son propre verdict.

Le binaire est installé setuid pepsi-crypto, mode 4750 pepsi-crypto:pepsi, exactement pour les raisons données plus haut pour pepsi-stage-encrypt(1). Voir pepsi-stage-decrypt(1).

85.2.1.1.14.5. Options de pepsi-stage-reencrypt

Une étape avec PROGRAM = pepsi-stage-reencrypt scelle un message que l’étape de déchiffrement a ouvert, à destination de la clé du propre client de messagerie (MUA) du destinataire, avant la remise locale. Elle n’agit que sur les lignes dont state.crypto.in indique que le message est arrivé chiffré et a été déchiffré. NEXT_STAGE est obligatoire.

ON_NO_CLIENT_KEY

(chaîne, facultative) Ce qui arrive à un destinataire local sans clé MUA utilisable : plaintext (par défaut) classe le texte en clair ; bounce refuse le message via BOUNCE_STAGE avec un DSN 5.7.5 qui ne porte que les champs d’en-tête d’adressage et aucun corps (RET=HDRS est forcé). pepsi-setup refuse bounce sans BOUNCE_STAGE. Les surcharges par destinataire via pepsi.settings s’appliquent.

PROTECT_HEADERS

(booléen, facultatif) Copie les champs RFC 5322 à l’intérieur du texte chiffré et remplace le Subject extérieur par .... Par défaut NO.

ENABLED

(booléen, facultatif) Désactivé, laisse passer tous les messages. Par défaut YES.

LOCAL_DOMAINS, TARGETS, RECIPIENT_DELIMITER, REQUIRE_ACCOUNT

Quels destinataires sont servis ici, comme pour Options de pepsi-stage-decrypt. Les autres destinataires ne sont ni scellés ni refusés.

Le conteneur suit [pepsi] CRYPTO_ALLOW_DOWNGRADE comme pour le chiffrement sortant. Le binaire est non privilégié et intégré au binaire multi-appel pepsi : il scelle vers des clés publiques et ne lit que les colonnes publiques de pepsi.crypto_identity. Voir pepsi-stage-reencrypt(1).

85.2.1.1.14.8. Options de pepsi-stage-dkim-sign

Une étape avec PROGRAM = pepsi-stage-dkim-sign lit, outre un NEXT_STAGE obligatoire :

HEADER_CANONICALIZATION, BODY_CANONICALIZATION

(``relaxed`` | ``simple``, facultatif) Les deux moitiés de la canonicalisation c=. Les deux valent relaxed par défaut et peuvent être réglées indépendamment ; les quatre combinaisons sont valides à la fois pour la signature DKIM et le scellement ARC.

SIGNATURE_EXPIRATION_DAYS

(entier, facultatif) Lorsqu’il est réglé sur un nombre positif de jours, les signatures portent une expiration (x=) ce nombre de jours après la signature. Non réglé (le défaut) n’émet aucune expiration.

SIGNED_HEADERS

(chaîne, facultative) Liste séparée par espaces/virgules des en-têtes que les signatures couvrent (h=). Doit inclure From. Par défaut l’ensemble d’en-têtes originateur/MIME intégré.

SIGNING_DOMAIN

(chaîne, facultative) Forcer le domaine de signature (d=). Lorsqu’il n’est pas réglé, le domaine est pris dans l’en-tête From: de chaque message. Un SIGNING_DOMAIN fixe est une identité d’envoi, de sorte que pepsi-setup(1) provisionne ses clés et son DNS.

Le matériel de clé DKIM et les sélecteurs proviennent de la section partagée [pepsi] (KEY_DIR, DKIM_SELECTOR). Le hachage est toujours SHA-256 ; une signature RSA (rsa-sha256) et une Ed25519 (ed25519-sha256) sont toutes deux émises.

85.2.1.1.14.9. Options de pepsi-stage-relay-to-internet

Une étape avec PROGRAM = pepsi-stage-relay-to-internet lit (un NEXT_STAGE et un BOUNCE_STAGE sont les clés générales ci-dessus) :

SERVER_NAME

(chaîne, obligatoire) Notre propre nom d’hôte, annoncé dans EHLO et écrit dans l’en-tête de trace Received:, par exemple mail.example.org.

POSTMASTER

(chaîne, facultative) Adresse qui reçoit un double rebond — un rebond (expéditeur nul) qui est lui-même non remettable. En son absence, de tels doubles rebonds sont abandonnés.

PUBLIC_IP

(chaîne, facultative) Les adresses publiques depuis lesquelles ce relais émet, lues par pepsi-setup(1) pour construire l’enregistrement SPF (et, pour cette étape, pour vérifier le DNS inverse) — une option d’étape de relais documentée sous L’option d’identité de sortie : PUBLIC_IP ci-dessous.

CONNECT_TIMEOUT / COMMAND_TIMEOUT / DATA_TIMEOUT

(durée, facultative) Timeouts par connexion pour, respectivement, l’établissement de la connexion TCP, une commande/réponse SMTP, et le transfert DATA. Par défaut 300 s / 300 s / 600 s.

RETRY_INITIAL / RETRY_MAX_INTERVAL / RETRY_FACTOR

(durée / durée / nombre, facultatif) Calendrier de backoff exponentiel entre les tentatives de remise d’un message échouant transitoirement : la première attente, le plafond de l’attente, et le multiplicateur appliqué à chaque tentative. Par défaut 300 s / 2 h / 2.

MAX_LIFETIME

(durée, facultative) Combien de temps un message peut rester dans le pipeline avant qu’un échec transitoire ne devienne permanent (il est alors rebondi ou marqué en échec). Par défaut 5 d de temps réel, mais la valeur doit être écrite avec les unités h/m/s — l’analyseur de durée rejette l’unité calendaire d (écrivez donc 120 h, pas 5 d).

DELAY_DSN_AFTER

(durée, facultative) Lorsqu’il est réglé, un DSN Action: delayed à usage unique est envoyé à l’expéditeur une fois qu’un message encore non remis a été en file au moins aussi longtemps et que l’expéditeur a demandé NOTIFY=DELAY. Doit utiliser les unités h/m/s. Non réglé (le défaut) désactive les avertissements de délai.

MAX_HOP_COUNT

(nombre, facultatif) Nombre maximal d’en-têtes Received: tolérés avant que le message ne soit traité comme une boucle de courrier et marqué en échec permanent. Par défaut 30.

DNS_SERVERS

(chaîne, facultative) Résolveurs explicites séparés par espaces/virgules (port 53) pour les recherches MX et d’adresse. Lorsqu’il n’est pas réglé, le resolv.conf système est utilisé.

DNS_TIMEOUT

(durée, facultative) Timeout DNS par requête. Par défaut 5 s.

MTA_STS

(booléen, facultatif) S’il faut découvrir et appliquer les politiques MTA-STS du domaine destinataire (RFC 8461). Par défaut yes.

MTA_STS_TIMEOUT

(durée, facultative) Timeout pour récupérer un fichier de politique MTA-STS via HTTPS. Par défaut 10 s.

ADDRESS_FAMILY

(facultatif) Quelles familles d’adresses IP employer pour se connecter aux serveurs de courrier : any (défaut), ipv4 (aussi orthographié v4/v4only) ou ipv6 (v6/v6only). La valeur configurée est intersectée avec ce que l’hôte local sait réellement router, de sorte qu’épingler une famille pour laquelle l’hôte n’a aucune route ne laisse rien à joindre. pepsi-stage-relay-to-smarthost(1) a la même option, réglable en outre par entrée de MTA.

DANE

(facultatif) Application DANE/TLSA (RFC 7672) pour le MX de destination : off (pas de recherches TLSA), warn (le défaut ; valider mais, en cas de non-concordance, journaliser et remettre quand même) ou strict (un enregistrement utilisable mais non concordant, ou une recherche TLSA échouée, diffère la remise). Nécessite un résolveur validant DNSSEC (Pepsi fait confiance au bit AD de la réponse ; voir DNS_SERVERS) ; les enregistrements TLSA utilisables ont priorité sur MTA-STS.

85.2.1.1.14.10. Options de pepsi-stage-relay-to-smarthost

Une étape avec PROGRAM = pepsi-stage-relay-to-smarthost lit les options opérationnelles ci-dessous ; les smarthosts amont eux-mêmes sont définis une seule fois dans les sections partagées [pepsi-stage-relay-to-smarthost-mta-*] (voir Les sections smarthost (MTA) ci-dessous). Un NEXT_STAGE et un BOUNCE_STAGE sont les clés générales ci-dessus.

SERVER_NAME

(chaîne, obligatoire) Notre propre nom d’hôte, annoncé dans EHLO (sauf si un MTA le redéfinit avec HELO_NAME) et écrit dans l’en-tête Received:.

CONNECT_TIMEOUT / COMMAND_TIMEOUT / DATA_TIMEOUT

(durée, facultative) Timeouts par connexion pour le connect TCP, une commande/réponse SMTP et le transfert DATA. Par défaut 300 s / 300 s / 600 s.

RETRY_INITIAL / RETRY_MAX_INTERVAL / RETRY_FACTOR

(durée / durée / nombre, facultatif) Calendrier de backoff exponentiel entre les tentatives de relais. Par défaut 300 s / 2 h / 2.

MAX_LIFETIME

(durée, facultative) Combien de temps un message peut rester dans le pipeline avant qu’un échec transitoire ne devienne permanent. Par défaut 5 d de temps réel, mais écrivez-le avec les unités h/m/s — l’analyseur rejette l’unité calendaire d.

DELAY_DSN_AFTER

(durée, facultative) Lorsqu’il est réglé, un DSN Action: delayed à usage unique est envoyé une fois qu’un message encore non remis a été en file au moins aussi longtemps et que l’expéditeur a demandé NOTIFY=DELAY. Doit utiliser les unités h/m/s. Non réglé le désactive.

MAX_HOP_COUNT

(nombre, facultatif) Nombre maximal d’en-têtes Received: avant que le message ne soit traité comme une boucle et marqué en échec permanent. Par défaut 30.

ADDRESS_FAMILY

(facultatif) La famille d’adresses dont hérite chaque entrée MTA à moins que sa propre section [pepsi-stage-relay-to-smarthost-mta-*] ne la redéfinisse : any (par défaut), ipv4 (aussi v4/v4only) ou ipv6 (v6/v6only). Même option, mêmes orthographes, que celle de pepsi-stage-relay-to-internet(1) ci-dessus.

PUBLIC_IP

(chaîne, facultative) Les adresses publiques depuis lesquelles ce relais émet, lues par pepsi-setup(1) pour construire l’enregistrement SPF — une option d’étape de relais documentée sous L’option d’identité de sortie : PUBLIC_IP ci-dessous.

DNS_SERVERS

(chaîne, facultative) Résolveurs explicites séparés par espaces/virgules (port 53) pour les recherches TLSA DANE. Lorsqu’il n’est pas réglé, le resolv.conf système est utilisé.

Consultés uniquement lorsqu’un smarthost active DANE ; le résolveur doit valider DNSSEC.

DNS_TIMEOUT

(durée, facultative) Timeout par requête pour les recherches TLSA DANE. Par défaut 5 s.

85.2.1.1.14.11. Options de l’étape de rebond

Une section [stage-<name>] avec PROGRAM = pepsi-stage-bounce lit en outre, depuis sa propre section :

SERVER_NAME

(chaîne, obligatoire) Nom d’hôte utilisé dans les champs From: et Reporting-MTA du rebond généré et dans son domaine de Message-ID, par exemple mail.example.org.

POSTMASTER

(chaîne, facultative) Adresse From: des rebonds générés (Mail Delivery Subsystem <POSTMASTER>) et l’identité de signature DKIM — le rebond est signé en tant que domaine de cette adresse, dont pepsi-setup(1) provisionne les clés. Par défaut postmaster@<SERVER_NAME>.

NEXT_STAGE

(chaîne, requise pour cette étape) L’étape vers laquelle le rebond réécrit avance. Comme le rebond est laissé non signé, c’est normalement une étape pepsi-stage-dkim-sign(1) (qui le signe en tant que domaine du postmaster), qui à son tour pointe vers une étape de remise telle que pepsi-stage-relay-to-internet(1).

BOUNCE_MESSAGE

(chaîne, facultative) Nom du modèle qui rend la partie lisible par un humain (text/plain) du rebond. Le fichier de modèle est bounce-<NAME>.<lang>.body sous le TEMPLATE_DIR de [pepsi] ; c’est un modèle Mustache. <lang> suit le state.language du message (la langue détectée dans le message d’origine, dont l’expéditeur reçoit le rebond) dans son ordre q, avec repli sur bounce-<NAME>.en.body, qui doit exister. Lorsqu’il n’est pas réglé — ou lorsque le rendu échoue — un avis intégré en anglais est utilisé à la place, de sorte qu’un rebond est toujours produit. Trois familles de modèles sont installées par make install : bounce-default, bounce-language (la politique de langue de pepsi-stage-block-language(1)) et bounce-payment (la barrière impayée de pepsi-stage-anti-spam(1)).

Tout le state du message est passé au modèle comme contexte de rendu, augmenté des variables de commodité server_name, postmaster, bounce_to, failed_recipient, diagnostic, action et des booléens failed / delayed / delivered. En particulier, l’étape de remise enregistre un détail structuré du saut suivant sous state.bounce — remote_mta, smtp_code, enhanced_status, phase et reply_text — de sorte que le modèle puisse énoncer précisément pourquoi le MTA suivant a refusé le message. Lorsqu’un state.bounce.enhanced_status (RFC 3463) est présent, il est aussi utilisé pour le champ Status: lisible par machine du DSN.

RET_FULL_MAX_SIZE

(entier, facultatif) Plus grand message original, en octets, qu’un rebond RET=FULL renvoie en entier. Par défaut 262144 (256 Kio) ; 0 supprime la limite.

La RFC 3461 §6.2 dit que le message complet « DEVRAIT être renvoyé » lorsque l’expéditeur a posé RET=FULL sur le MAIL FROM, et permet explicitement de ne renvoyer que les en-têtes lorsque le message « dépasse une certaine taille définie par l’implémentation » — la limite fait donc partie du comportement conforme, elle n’y échappe pas. Sans elle, un message de 40 Mo en échec deviendrait un rebond de 40 Mo envoyé à un expéditeur qui passe déjà une mauvaise journée. Au-dessus de la limite, le DSN se rabat sur text/rfc822-headers, exactement comme le fait un rebond RET=HDRS (ou sans RET), et le repli est journalisé.

Le corps n’est extrait de la base que pour un message dont l’expéditeur l’a demandé et qui reste sous la limite ; un rebond ordinaire ne charge toujours que le bloc d’en-têtes.

BOUNCE_UNAUTHENTICATED

(``drop`` ou ``send``, facultatif) Que faire d’un rapport adressé à un expéditeur d’enveloppe que le message entrant n’a pas authentifié. Par défaut drop.

Le spam falsifie son expéditeur d’enveloppe, si bien qu’un rebond le concernant part vers un tiers innocent. C’est le backscatter : les destinataires se plaignent, et l’IP de cet hôte finit sur des listes noires. Avec drop, un rapport n’est envoyé que lorsque :

  • le message provient de l’un de nos propres utilisateurs (state.local_origin) ;

  • SPF a réussi pour le domaine de l’expéditeur d’enveloppe ; ou

  • une signature DKIM alignée a réussi pour un domaine From: qui est le domaine de l’expéditeur d’enveloppe, ou un parent ou enfant de celui-ci.

Tout le reste est supprimé et journalisé. Un message créé par une étape, plutôt qu’arrivé par SMTP, ne porte aucun enregistrement d’authentification et fait toujours l’objet d’un rapport. send rétablit l’ancien comportement consistant à envoyer un rapport à chaque expéditeur.

Le destinataire en échec et le diagnostic cités dans le rebond sont pris dans le state laissé sur la ligne par l’étape de remise qui a acheminé le message ici (voir BOUNCE_STAGE ci-dessus) ; en leur absence (par exemple un message mis en file à la main), un avis générique est produit.

85.2.1.1.14.12. Options de pepsi-stage-discard

Une étape avec PROGRAM = pepsi-stage-discard supprime le message (un puits de staging / test). Elle ignore NEXT_STAGE — un rejet est toujours terminal — et lit :

DISPOSITION

(facultatif) L’issue simulée : success (défaut) traite le message comme remis ; failure le traite comme un échec de remise permanent.

BOUNCE

(booléen, facultatif) Si le rejet peut émettre un DSN du tout. Par défaut no.

BOUNCE_STAGE

(chaîne, facultative) L’étape de génération de DSN vers laquelle un rejet rapportable est acheminé (normalement une étape pepsi-stage-bounce(1)). En son absence, rien n’est émis et la ligne est simplement supprimée.

Le chemin de succès consulte aussi l’indicateur partagé [pepsi] ORIGINATE_SUCCESS_DSN ; un message à expéditeur nul ne rebondit jamais.

85.2.1.1.14.13. Options de pepsi-stage-anti-spam

Une étape avec PROGRAM = pepsi-stage-anti-spam lit (outre un NEXT_STAGE) :

BOUNCE_STAGE

(chaîne, facultative) L’étape vers laquelle un message non payé au délai est acheminé — normalement une étape pepsi-stage-bounce(1) (un DSN de rejet, honorant le NOTIFY de l’expéditeur) ou une étape pepsi-stage-discard(1) (abandon silencieux). En son absence, un message non payé est simplement supprimé.

BOUNCE_TARGET_STAGE

(chaîne, facultative) Où est acheminé un rebond de retour ne portant aucune preuve ``Pepsi-Origin`` valide — un message à expéditeur nul se donnant pour un rapport sur du courrier à nous, dont nous ne pouvons pas montrer que nous l’avons originé (voir La section [pepsi-origin]). Sans elle, un tel message prend le chemin NEXT_STAGE ordinaire. Pointez-la vers une étape de quarantaine ou de revue si vous voulez les conserver pour inspection : ils ne sont jamais soumis au péage à l’envoi, puisqu’un rebond ne doit pas rebondir.

ORDER_CHOICES

(JSON, obligatoire) Le tableau choices d’une commande Taler v1, utilisé verbatim : un ou plusieurs objets OrderChoice décrivant les paiements acceptés (par exemple plusieurs montants dans différentes devises, ou des entrées/sorties de famille de jetons). Voir l’API marchand GNU Taler.

PAYMENT_DEADLINE

(durée, facultative) Combien de temps le message est retenu paused en attente de paiement avant d’être rejeté ; aussi le pay_deadline de la commande. Utilise les unités h/m/s uniquement (les unités calendaires telles que d sont rejetées). Par défaut 48 h.

DELAY_DSN_AFTER

(durée, facultative) Envoyer à l’expéditeur une notification d’état de remise différée (RFC 3461) à usage unique une fois qu’un message encore impayé a été retenu aussi longtemps, sans libérer le message — il reste en pause jusqu’à PAYMENT_DEADLINE. Le DSN n’est envoyé que lorsque l’expéditeur a demandé NOTIFY=DELAY et qu’un BOUNCE_STAGE est câblé (il y est acheminé avec kind = delay). Ne se déclenche que lorsqu’il tombe strictement avant PAYMENT_DEADLINE. Utilise les unités h/m/s uniquement. Non réglé (le défaut) désactive les avertissements de délai.

SUMMARY

(chaîne, facultative) Résumé de commande lisible par un humain montré au payeur. Par défaut E-mail delivery.

FULFILLMENT_MESSAGE

(chaîne, facultative) Message montré au payeur après un paiement réussi. Par défaut Your e-mail has been queued for delivery.

BLOCK_RESPONSE_STAGE

(chaîne, facultative) L’étape à laquelle la réponse automatique de demande de paiement est injectée — habituellement la tête d’une chaîne de signature/relais (par exemple une étape pepsi-stage-dkim-sign(1)). Doit référencer une étape existante. Lorsqu’il n’est pas réglé, aucune réponse n’est envoyée (le message est tout de même en pause en attente de paiement).

BLOCK_RESPONSE_FROM

(chaîne, facultative) L’en-tête From: de la réponse automatique. Lorsqu’il n’est pas réglé, par défaut le destinataire original (la boîte aux lettres protégée).

BLOCK_RESPONSE_SUBJECT

(chaîne, facultative) Le Subject: de la réponse automatique. Par défaut Payment required to deliver your e-mail.

BLOCK_RESPONSE_SUPPRESS

(durée, facultative) La fenêtre par expéditeur de la réponse automatique : un expéditeur à qui une demande de paiement a déjà été envoyée pour la même boîte protégée (le premier destinataire d’enveloppe) dans ce délai n’en reçoit aucune pour le message suivant — qui reste néanmoins retenu dans l’attente du paiement. La demande part vers un expéditeur d’enveloppe que personne n’a vérifié, de sorte que sans fenêtre, un flot de messages portant un même expéditeur falsifié devient le même flot de demandes à cette adresse. Revendiqué et consigné en une seule instruction (payment_request_should_send sur pepsi.payment_request_reply, le schéma de vacation_should_reply), de sorte que deux workers ne peuvent pas tous deux en envoyer une ; les lignes sont élaguées à mesure qu’elles vieillissent. Unités h/m/s uniquement (plafonné à un an) ; 0 s répond à chaque message. Par défaut 1 h.

PAYMENT_MESSAGE_DEFAULT_LANGUAGE

(chaîne, facultative) La langue de repli pour le corps de la réponse automatique, utilisée lorsque le message ne porte aucune state.language détectée ou qu’aucune des langues détectées n’a de modèle payment-request.<lang>.body (sous [pepsi] TEMPLATE_DIR). Ce modèle doit exister (pepsi-setup vérifie). Insensible à la casse. Par défaut en.

L’étape nécessite aussi la section partagée [pepsi-payments] (le backend marchand et le jeton d’accès, documentés ci-dessous) et, pour que le webhook de paiement libère les messages en pause, le RESUME_AUTHORIZATION_TOKEN de [pepsi-httpd] (voir pepsi-httpd(1)).

85.2.1.1.14.14. Options de pepsi-stage-auto-pay

Une étape avec PROGRAM = pepsi-stage-auto-pay lit :

MAX_TOTAL

(montant, obligatoire) Le maximum que cette étape dépensera, au total, pour remettre un message original — un montant GNU Taler CURRENCY:VALUE (par exemple EUR:5). Le plafond est cumulatif sur chaque demande de paiement revenant pour ce message (toutes partageant un nonce Pepsi-Origin, par exemple l’éclatement d’une liste de diffusion) et monodevise : une demande dans toute autre devise n’est pas payée. Un compte peut le redéfinir pour son propre courrier via pepsi-stage-edit-settings(1).

MAX_TOTAL_PER_DAY

(montant, facultatif) Le maximum qu’un wallet peut dépenser en demandes de paiement sur toute période de 24 heures (une fenêtre glissante), quel que soit le nombre de messages originaux — le plafond global que MAX_TOTAL ne fournit pas, puisqu’un correspondant qui a reçu k de nos messages peut exiger MAX_TOTAL pour chacun. Le wallet suit WALLET_MODE/WALLET_SCOPE : le propre wallet d’un utilisateur local, le wallet par expéditeur du compte partagé, ou son wallet unifié unique (la limite est alors celle du déploiement). Jamais par correspondant : les listes de diffusion et les alias rendent la partie qui exige le paiement impossible à connaître. Doit être dans la devise de MAX_TOTAL. Appliqué atomiquement avec MAX_TOTAL par auto_pay_try_spend sur le registre pepsi.auto_pay_spend ; un paiement qui échoue à se régler est recrédité. Non défini (la valeur par défaut), il n’y a aucune limite quotidienne.

NEXT_STAGE

(chaîne, obligatoire) Où un message est transféré lorsqu’il n’est pas une demande de paiement, n’est pas prouvablement nôtre, ou n’est pas payé (hors budget / échec de règlement). Une étape sans NEXT_STAGE produit une erreur à l’exécution.

WALLET_MODE

(``local-user`` | ``shared``, par défaut ``shared``) Quel compte le helper de wallet utilise pour payer. local-user abandonne ses privilèges vers le propre login local du destinataire du rebond (l’expéditeur original) et utilise le wallet par défaut de cet utilisateur — le destinataire doit se résoudre en un compte local permis (le test LOCAL_DOMAINS/TARGETS/RECIPIENT_DELIMITER, comme pour pepsi-stage-relay-to-maildir(1)). shared abandonne ses privilèges vers un unique compte dédié (WALLET_USER).

WALLET_USER

(chaîne, par défaut ``pepsi-wallets``) Le compte partagé vers lequel le helper abandonne ses privilèges en WALLET_MODE = shared ; son home contient la ou les bases de données de wallet.

WALLET_SCOPE

(``per-sender`` | ``unified``, par défaut ``per-sender``) En mode shared, comment les bases de données de wallet du compte partagé sont séparées : une par adresse d’expéditeur original (per-sender), ou un unique wallet partagé par tous (unified — par exemple une entreprise où des wallets individuels n’ont pas de sens).

WALLET_CLI

(chaîne, par défaut ``taler-wallet-cli``) L’outil en ligne de commande de wallet GNU Taler que le helper exécute (un nom résolu sur le $PATH ou un chemin absolu).

WALLET_PAY_OPTIONS

(chaîne, par défaut aucune) Arguments supplémentaires ajoutés à l’invocation de paiement du wallet, séparés par des espaces. Le littéral none ne passe aucune option supplémentaire. (--yes et --choice-index 0 sont toujours ajoutés par le helper pour confirmer le paiement et nommer le choix du contrat qui a été tarifé.) Rien n’est nécessaire ici par défaut — le handle-uri du wallet attend déjà que le paiement atteigne un état terminal.

HELPER

(chaîne, par défaut ``pepsi-helper-auto-pay``) Le binaire de helper de wallet privilégié (un nom sur le $PATH ou un chemin absolu).

Les options suivantes activent et configurent le rôle de self-service de wallet (un message soumis localement à l’adresse de contrôle opère le wallet propre à l’expéditeur par e-mail ; voir pepsi-stage-auto-pay(1)) :

RESPONSE_STAGE

(chaîne, facultative) L’étape à laquelle la réponse self-service est injectée (de sorte qu’elle soit signée en DKIM et relayée). La régler active le rôle self-service ; la laisser non réglée signifie que l’étape ne paie que les demandes entrantes.

CONTROL_LOCAL_PART

(chaîne, par défaut ``pepsi-wallet``) La partie locale de l’adresse de contrôle du wallet : un message d’origine locale vers <part>@<served-domain> est un message de contrôle de wallet.

RESPONSE_FROM

(chaîne, facultative) Le From: de la réponse self-service. Par défaut <{CONTROL_LOCAL_PART}@{domain}> pour le domaine servi adressé.

RESPONSE_SUBJECT

(chaîne, par défaut ``Pepsi wallet``) Le Subject: de la réponse self-service.

Un withdraw (rechargement) manuel nomme l’exchange GNU Taler depuis lequel retirer dans la requête (Subject: withdraw CURRENCY:VALUE EXCHANGE-URL) ; parce qu’un wallet est multi-devise et peut retirer depuis plusieurs exchanges, il n’y a pas d’option d’exchange côté serveur.

L’étape utilise aussi la section partagée [pepsi-origin] (le secret de preuve d’origine) pour vérifier qu’une demande concerne un courrier que ce déploiement a réellement envoyé ; sans elle, aucune demande ne peut être vérifiée et aucune n’est payée (le self-service n’est pas affecté). Tout le travail de wallet est effectué par le pepsi-helper-auto-pay(1) setuid-root ; le binaire de l’étape est installé SGID pepsi-wallets afin que son worker puisse l’exec.

85.2.1.1.14.15. Options de pepsi-stage-check-whitelist

Une étape avec PROGRAM = pepsi-stage-check-whitelist lit :

WHITELIST_NAME

(liste, obligatoire) Les groupes whitelist_name à consulter dans la table pepsi.whitelist — une liste séparée par des virgules, interrogée en un seul = ANY(...), et non un nom unique.

Une entrée peut être un modèle contenant {localpart} ou {login}, développé par destinataire d’enveloppe avant la requête : {localpart} est la partie locale dépouillée de sa sous-adresse et mise en minuscules, et {login} le login passwd auquel elle se résout. C’est ainsi qu’un espace de noms par utilisateur géré avec pepsi-whitelist(1) — les noms <login>/segment — est consulté sans redéfinition de paramètres par adresse. Par exemple

WHITELIST_NAME = correspondents, {localpart}/correspondents

consulte le groupe partagé et celui propre à chaque destinataire.

LOCAL_DOMAINS, TARGETS, RECIPIENT_DELIMITER

(facultatif) Les mêmes options de localité, avec les mêmes valeurs par défaut, que les étapes de remise — lues ici uniquement pour résoudre {login} (et pour dépouiller une sous-adresse pour {localpart}). Nécessaires seulement lorsqu’un modèle les emploie.

NEXT_STAGE

(chaîne, obligatoire) Où le message avance après la vérification (qu’il ait correspondu ou non). Une étape sans NEXT_STAGE produit une erreur à l’exécution.

85.2.1.1.14.16. Options de pepsi-stage-auto-whitelist

Une étape avec PROGRAM = pepsi-stage-auto-whitelist lit :

WHITELIST_NAME

(chaîne, obligatoire) Le groupe whitelist_name à peupler dans la table pepsi.whitelist. Il devrait correspondre au groupe que la pepsi-stage-check-whitelist(1) entrante consulte. Un unique nom littéral dans la grammaire des noms de liste blanche : cette étape ne développe aucun marqueur {login}/{localpart}, de sorte qu’une valeur en contenant un est refusée. L’opérateur peut nommer n’importe quelle liste blanche, y compris une liste partagée par tous les utilisateurs locaux ; une valeur qu’un titulaire de compte définit par courrier via pepsi-stage-edit-settings(1) doit en nommer une de son propre espace de noms <login>/..., ou celle que la configuration de l’opérateur nomme pour lui.

DKIM_REQUIRED

(booléen, facultatif) Valeur stockée dans la colonne dkim_required de chaque ligne que cette étape insère. Par défaut yes.

NEXT_STAGE

(chaîne, obligatoire) Où le message avance après que les destinataires sont enregistrés. Une étape sans NEXT_STAGE produit une erreur à l’exécution.

85.2.1.1.14.17. Options de pepsi-stage-autocrypt-learn

Une étape avec PROGRAM = pepsi-stage-autocrypt-learn lit :

LEARN_KEYS

(booléen, facultatif) Stocker le matériel de clé propre à l’expéditeur trouvé dans le message — certificats de signataire S/MIME, parties application/pgp-keys et en-tête Autocrypt: — au rang de confiance inbound, où il ne pourra jamais remplacer silencieusement une clé de meilleure source. YES par défaut. Seul le matériel revendiquant l’adresse propre à l’expéditeur est conservé. Le désactiver transforme toute l’étape en simple passage, LEARN_GOSSIP compris.

LEARN_GOSSIP

(booléen, facultatif) Apprendre en outre les clés des autres destinataires depuis les champs Autocrypt-Gossip: situés à l’intérieur d’un message arrivé chiffré (Autocrypt Level 1 §5.3), au rang gossip — le bas de l’échelle, sous inbound. YES par défaut ; sans effet à moins que LEARN_KEYS ne soit également activé.

C’est ce qui rend possible une réponse à tous chiffrée vers un correspondant dont on n’a jamais reçu de courrier direct. Un champ n’est employé que s’il était véritablement à l’intérieur du texte chiffré, seulement si son addr apparaît dans les To:, Cc: ou Reply-To: propres au message, jamais pour l’adresse de l’expéditeur lui-même, et jamais pour une adresse de LOCAL_DOMAINS — personne ne peut présenter à cet hôte ses propres utilisateurs. Une clé gossipée ne peut jamais déloger une clé de meilleure source et ne fait jamais compter une signature comme vérifiée.

Notez l’asymétrie avec la moitié émettrice ([stage-encrypt] AUTOCRYPT_GOSSIP, NO par défaut) : émettre du gossip redistribue les clés de tiers à des correspondants qui ne les ont pas demandées, tandis que le lire ne fait que remplir le cache propre à cet hôte. Un opérateur qui veut que les présentations soient stockées mais jamais employées règle [pepsi-keydiscovery] MIN_TRUST = harvested plutôt que de désactiver ceci.

LEARN_FROM_SPAM

(booléen, facultatif) Si un message que le pipeline a déjà noté comme spam (state.spam = true) peut tout de même enseigner une clé. NO par défaut, ce qui est le « les messages DEVRAIENT être ignorés … lorsque le MUA croit que le message est du spam » d’Autocrypt Level 1 §5.3.

C’est une option plutôt qu’une règle fixe parce que la croyance est celle de Pepsi : un opérateur dont la notation de spam est délibérément lâche peut préférer la continuité des clés à la règle. Notez qu’honorer le défaut exige que l’étape soit placée après ce qui règle state.spam — voir pepsi-stage-autocrypt-learn(1).

ACCEPT_ROTATION

(chaîne, facultative) Quand la règle « le plus récent l’emporte » du niveau Autocrypt peut remplacer la clé inbound/gossip stockée d’un correspondant par la clé que porte un message plus récent. newest (la valeur par défaut) correspond à Autocrypt Level 1 : une date effective strictement plus récente suffit. expired exige en outre que chaque clé stockée pour cette adresse et ce protocole soit révoquée ou expirée (d’après sa validité consignée ou son expires_at) ; sinon la clé stockée est conservée et l’offre est retenue — auditée comme key.peer.rotate.held et signalée aux destinataires comme une rotation. Un remplacement par une source strictement mieux classée n’est pas régi par cette option. Toute autre valeur est une erreur de configuration. Dans tous les cas, chaque rotation écrit une ligne d’audit key.peer.rotate ; voir pepsi-stage-autocrypt-learn(1).

RESPONSE_STAGE

(chaîne, facultative) L’étape à laquelle les avis de changement de clé sont injectés : lorsque la clé d’un correspondant fait l’objet d’une rotation ou est retenue, chaque destinataire d’enveloppe local du message qui en est la cause reçoit par courrier le modèle key-rotation.<lang>.body (expéditeur nul, From: postmaster@<domain>). Normalement l’étape de signature DKIM, comme le RESPONSE_STAGE de pepsi-stage-encrypt(1). Doit nommer une étape existante ; pepsi-setup(1) exige aussi key-rotation.en.body dans [pepsi] TEMPLATE_DIR. En son absence, les changements sont audités et journalisés mais personne ne reçoit de courrier.

LOCAL_DOMAINS, TARGETS, RECIPIENT_DELIMITER

(facultatif) Les options de localité partagées. Seul LOCAL_DOMAINS est consulté : pour refuser un champ de gossip nommant une adresse que cet hôte sert (une substitution de clé plutôt qu’une présentation), et pour choisir quels destinataires d’enveloppe sont les nôtres, à qui envoyer un avis de changement de clé. Vaut par défaut [pepsi-ingress] ACCEPTED_DOMAINS.

NEXT_STAGE

(chaîne, obligatoire) Où le message avance une fois que l’étape a appris ce qu’elle pouvait. L’étape ne consomme jamais un message : un NEXT_STAGE manquant est donc refusé par pepsi-setup(1) et produit une erreur à l’exécution.

85.2.1.1.14.18. Options de pepsi-stage-detect-language

Une étape avec PROGRAM = pepsi-stage-detect-language lit :

NEXT_STAGE

(chaîne, obligatoire) Où le message avance après la classification (qu’une langue ait été enregistrée ou non). Une étape sans NEXT_STAGE produit une erreur à l’exécution.

LANGUAGES

(liste, facultative) Les langues candidates, sous forme de codes ISO 639-1 séparés par espaces ou virgules (sans distinction de casse) ; au moins deux codes distincts sont requis. Le jeton * représente toute langue prise en charge et peut être combiné à des codes explicites (qui viennent alors en premier). La détection ne renvoie jamais que des langues de cet ensemble : il devrait donc couvrir les langues que vous attendez de recevoir. Par défaut un large ensemble courant (en de fr es it pt nl pl ru tr ar zh ja).

Restreignez-la. Chaque langue activée augmente la mémoire qu’emploie chaque processus worker et — plus important — chaque langue que votre trafic ne contient jamais concourt tout de même pour la probabilité. L’étape retire du corps ce qui n’est pas de la prose (URL, adresses, blocs base64, enregistrements DNS) avant de classifier, ce qui empêche qu’un seul jeton de ce genre décide la réponse d’emblée ; ce qui reste ensuite est une véritable compétition entre les candidates, et une langue que personne ne vous écrit peut encore l’emporter sur un message court. pepsi-detect-language(1) reclassifie un message enregistré contre n’importe quel ensemble de candidates, de sorte qu’une liste plus étroite puisse être essayée avant d’être configurée.

85.2.1.1.14.19. Options de pepsi-stage-block-language

Une étape avec PROGRAM = pepsi-stage-block-language lit :

NEXT_STAGE

(chaîne, obligatoire) Où avance un message notant au-dessus de THRESHOLD — et, sous ENFORCEMENT = soft, où continue aussi un message signalé. Une étape sans NEXT_STAGE produit une erreur à l’exécution.

BOUNCE_STAGE

(chaîne, requise lorsqu’un message peut être rebondi) Où est acheminé un message notant au niveau ou en dessous de THRESHOLD afin qu’un DSN d’échec puisse être engendré (typiquement pepsi-stage-bounce(1)). Consultée seulement sous ENFORCEMENT = hard ; un rebond sans BOUNCE_STAGE produit une erreur à l’exécution. Elle vaut la peine d’être réglée même sous soft, afin que passer à hard soit une modification d’un seul mot.

ENFORCEMENT

(``hard`` | ``soft``, facultatif) Ce qui arrive à un message qui échoue à la politique. hard (le défaut) l’achemine vers BOUNCE_STAGE, de sorte qu’il ne soit pas remis. soft le remet tout de même, marqué : SUBJECT_FLAG_LABEL est ajouté à son Subject:, un en-tête X-Pepsi-Detected-Languages consigne ce qui a été détecté, et le message avance vers NEXT_STAGE.

soft marque exactement les messages que hard aurait fait rebondir, ce qui en fait un mode d’entraînement : exécutez-le un moment et les marques dans la boîte aux lettres sont un aperçu fidèle de ce que l’application refuserait, sans coût pour un correspondant dont le courrier n’a pas encore servi à régler les listes. Étant une option d’étape ordinaire, elle est redéfinissable par adresse (pepsi-settings(1)), de sorte qu’un compte puisse rester à l’entraînement tandis que le reste du déploiement applique.

Notez que la réécriture du Subject: casse la signature DKIM de l’expéditeur et l”AMS ARC de ce serveur (tous deux sur-signent Subject), exactement comme le fait le VACATION_TAG de pepsi-stage-vacation(1) — gratuit sur une branche qui se termine par une remise locale, non gratuit sur une branche qui relaie plus loin.

SUBJECT_FLAG_LABEL

(chaîne, facultative) La marque ajoutée au Subject: d’un message signalé sous ENFORCEMENT = soft. [!LANG] par défaut. Ajoutée seulement lorsque le sujet ne la contient pas déjà (sans distinction de casse), de sorte qu’une réponse qui la recite à travers l’étape n’en accumule pas une seconde. Une valeur vide réapplique le défaut ; il n’y a aucun moyen de désactiver la marque, puisque ne rien signaler revient à laisser l’étape hors du pipeline.

WHITELIST

(liste, facultative) Langues dont la probabilité est ajoutée au score, sous forme de codes ISO 639-1 séparés par espaces/virgules (insensible à la casse) plus le pseudo-code facultatif none (correspondant au courrier non détecté). Vide lorsqu’il n’est pas réglé. Une entrée peut porter d’autres sous-étiquettes (de-CH) ; chaque entrée est une plage de langue comparée par le filtrage de base de la RFC 4647 §3.3.1, de sorte que de corresponde aussi à un de-CH détecté tandis que de-CH ne corresponde pas à un de nu.

BLACKLIST

(liste, facultative) Langues dont la probabilité est soustraite du score, même syntaxe que WHITELIST. Vide lorsqu’il n’est pas réglé. Une langue peut apparaître sur au plus une des deux listes.

Au moins une des deux listes doit être non vide : les deux étant vides, chaque message obtient le score 0.0, que la barrière stricte score > THRESHOLD fait alors échouer, si bien que l’étape rebondirait (ou marquerait) tout le courrier. La configuration est refusée plutôt qu’acceptée, et la refuser est ce qui empêche « je remplirai les listes plus tard » d’être une panne silencieuse.

THRESHOLD

(flottant, facultatif) Le score qu’un message doit dépasser pour avancer. Par défaut 0.0.

85.2.1.1.14.20. Options de pepsi-stage-vacation

Une étape avec PROGRAM = pepsi-stage-vacation répond au courrier qui arrive pendant que le destinataire d’enveloppe est absent. Chaque option ci-dessous est redéfinissable par adresse, et c’est ainsi que la fonctionnalité est censée être employée : la section INI est le défaut de l’opérateur (pas de congé), et les dates de congé de chaque utilisateur — et, s’il le souhaite, son propre texte de message — viennent de sa ligne pepsi.settings ou d’une portée config_override. Voir pepsi-stage-vacation(1).

NEXT_STAGE

(chaîne, obligatoire) Où le message continue. Il continue toujours : cette étape ajoute une réponse, elle ne consomme jamais un message. pepsi-setup(1) rejette une étape qui en est dépourvue.

RESPONSE_STAGE

(chaîne, obligatoire) Où l’avis d’absence est injecté comme nouveau message à expéditeur nul, afin qu’il soit signé et relayé (typiquement l’étape de signature DKIM). pepsi-setup(1) vérifie qu’elle nomme une étape existante.

VACATION_RANGES

(liste, facultative) Intervalles YYYY-MM-DD:YYYY-MM-DD séparés par des virgules, indiquant les jours d’absence du destinataire. Les deux bornes sont des jours entiers inclus dans le fuseau horaire du serveur ; une fin vide (2026-08-01:) est un congé à durée indéterminée et une date seule est ce jour unique. Vide lorsqu’elle n’est pas définie, ce qui désactive l’étape pour cette adresse — le défaut, et l’état de tout destinataire qui n’a jamais configuré de congé. Un intervalle dont la fin précède le début est rejeté.

DEFAULT_LANGUAGE

(chaîne, facultative) La langue dont le message est employé lorsqu’aucune des langues détectées de l’expéditeur (state.language) n’en a un. en par défaut. Écrite avec l’un ou l’autre séparateur : pt_br et pt-BR sont la même étiquette.

DEFAULT_MESSAGE_SECTION

(chaîne, facultative) La section de configuration contenant un modèle de message en ligne par langue, sous la forme <LANG> = <template>. Vaut par défaut pepsi-vacation-default-message, livrée dans ${DATADIR}/config.d avec dix langues. Une option MESSAGE_<LANG> par adresse de cette section-ci prime sur elle, langue par langue.

EMERGENCY_CONTACT

(adresse, facultative) Une unique adresse nue offerte au modèle de message sous le nom {{EMERGENCY_CONTACT}}. Non définie par défaut, auquel cas le bloc {{#EMERGENCY_CONTACT}} d’un modèle est sauté. Un nom affiché ou une liste d’adresses est rejeté.

VACATION_TAG

(chaîne, facultative) Ajouté au Subject: du message redirigé lorsqu’un avis a été envoyé, afin que le destinataire puisse voir quel courrier a reçu une réponse à sa place. [VACATION] par défaut ; la valeur sentinelle none désactive le marquage. Une valeur vide ne le fait pas — l’analyseur lit une option vide comme absente, ce qui réapplique le défaut. L’ajout est idempotent.

SUPPRESS_DAYS

(entier, facultatif) Combien de temps après avoir répondu à un correspondant celui-ci peut recevoir une nouvelle réponse. 7 par défaut (le défaut de vacation en Sieve, RFC 5230 §4.1) ; 0 répond à chaque message. Ne doit pas dépasser 3650 (dix ans) — la valeur devient un intervalle SQL soustrait de now(), et une valeur plus grande place le résultat hors de la plage timestamptz, ce qui ferait échouer chaque message vers l’adresse plutôt que la configuration qui l’a réglée.

REQUIRE_ADDRESSED_TO

(booléen, facultatif) Ne répondre que lorsque le destinataire apparaît dans To: ou Cc: (RFC 3834 §3), de sorte qu’une copie cachée ou un envoi en masse à une liste ramassée n’attire aucune réponse. yes par défaut.

SUBJECT_PREFIX

(chaîne, facultative) Préfixé au sujet original pour former le sujet de l’avis. Auto: par défaut (RFC 5230 §4.5). Un message sans sujet donne le seul préfixe, et un sujet déjà préfixé ne l’est pas deux fois.

85.2.1.1.14.21. Options de pepsi-stage-secretary

Une étape avec PROGRAM = pepsi-stage-secretary retient le courrier des expéditeurs qu’aucune liste blanche ne connaît et leur demande de confirmer en répondant (confirmation à l’envoi). Chaque option ci-dessous est redéfinissable par adresse, de sorte qu’un utilisateur peut définir son propre texte de défi ou sa PENALTY. Voir pepsi-stage-secretary(1).

NEXT_STAGE

(chaîne, obligatoire) Où se poursuit le courrier en liste blanche, confirmé ou jamais soumis à un défi (un rebond, du courrier soumis localement).

RESPONSE_STAGE

(chaîne, obligatoire) Où le défi et l’avis de confirmation sont injectés comme nouveaux messages à expéditeur nul (typiquement l’étape de signature DKIM).

BOUNCE_STAGE

(chaîne, facultative) Le chemin d’expiration : où va le courrier retenu lorsque personne n’a confirmé à temps, que le défi a fait l’objet d’un rebond, ou que state.spam vaut true. Non définie, un tel courrier est supprimé.

UNCHALLENGEABLE_STAGE

(chaîne, facultative) Où va le courrier qui ne doit pas être soumis à un défi : la RFC 3834 dit de ne pas y répondre, son From: n’est pas l’expéditeur d’enveloppe, l’expéditeur n’est pas authentifié, ou le plafond quotidien de l’expéditeur est épuisé. Non définie, il prend le chemin d’expiration.

WHITELIST_NAME

(chaîne, obligatoire) L’unique liste blanche dans laquelle un expéditeur confirmé est écrit ; peut être un modèle {login}/{localpart}, développé par destinataire comme le fait pepsi-stage-check-whitelist(1). Une liste de noms est rejetée. L’opérateur peut nommer n’importe quelle liste blanche ; une valeur qu’un titulaire de compte définit par courrier via pepsi-stage-edit-settings(1) doit en nommer une de son propre espace de noms <login>/..., ou celle que la configuration de l’opérateur nomme pour lui.

CONTROL_LOCAL_PART

(chaîne, facultative) Partie locale de l’adresse de réponse <CONTROL_LOCAL_PART>-<cookie>@<domain>. secretary par défaut ; au plus 30 lettres ASCII, chiffres, ., _ ou -.

HOLD_TIME

(durée, facultative) Combien de temps le courrier retenu attend. 120 h par défaut ; unités h, m et s uniquement.

REQUIRE_AUTHENTICATED

(booléen, facultatif) Ne soumettre à un défi qu’un expéditeur dont SPF ou DMARC a réussi. yes par défaut.

MAX_CHALLENGES_PER_SENDER

(entier, facultatif) Nombre de défis qu’une adresse peut recevoir par période de 24 heures, toutes listes blanches confondues. 5 par défaut ; 0 signifie aucune limite.

DKIM_REQUIRED

(auto|yes|no, facultatif) Le dkim_required de la ligne de liste blanche qu’écrit une confirmation. auto (le défaut) le rend obligatoire lorsqu’un message retenu pour le défi a réussi DKIM (ou ARC avec DMARC).

CONFIRM_NOTICE

(booléen, facultatif) Indiquer à un expéditeur confirmé que son courrier a été remis. no par défaut.

PENALTY

(chaîne, facultative) Ce que l’expéditeur accepte de payer si son message n’était pas sollicité, proposé au modèle sous la forme {{PENALTY}}. Non définie par défaut.

SUBJECT_HINT_LENGTH

(entier, facultatif) Nombre de caractères du sujet du message retenu que cite le défi. 8 par défaut ; 0 omet l’indice ; au plus 64.

TEMPLATE

(chaîne, facultative) Nom de base des modèles de défi <TEMPLATE>.<lang>.body sous [pepsi] TEMPLATE_DIR. secretary-challenge par défaut.

SUBJECT

(chaîne, facultative) Le sujet du défi lorsqu’aucun SUBJECT_<LANG> ne correspond à la langue choisie. Please confirm your message to {{RECIPIENT}} par défaut.

DEFAULT_LANGUAGE

(chaîne, facultative) Langue utilisée lorsqu’aucune des langues détectées de l’expéditeur n’a de texte. en par défaut. pepsi-setup(1) exige un modèle ou un MESSAGE_<LANG> pour elle.

MESSAGE_<LANG>, SUBJECT_<LANG>, CONFIRM_MESSAGE_<LANG>

(chaîne, facultative) Texte du défi, sujet du défi et texte de confirmation par langue, redéfinissant les modèles pour cette langue seulement.

LOCAL_DOMAINS, TARGETS, RECIPIENT_DELIMITER

(facultatif) Les options de localité partagées (pepsi-stage-relay-to-maildir(1)) : dans quels domaines une adresse de réponse peut se trouver, et comment se développent les marqueurs de nom de liste blanche. LOCAL_DOMAINS vaut par défaut [pepsi-ingress] ACCEPTED_DOMAINS.

85.2.1.1.14.22. Options de pepsi-stage-if

Une étape avec PROGRAM = pepsi-stage-if branche sur un membre du JSON state du message :

STATE_PATH

(chaîne, obligatoire) Le chemin séparé par des points dans le state du message dont la valeur est testée (clés d’objet et indices entiers de tableau, par exemple spam, auth.dkim, dsn.rcpt.0.notify).

VALUE

(chaîne, obligatoire, non vide) La valeur à laquelle le membre à STATE_PATH est comparé, par sa forme textuelle scalaire naturelle (chaîne, true/false, nombre décimal, ou null). Une option vide est lue comme non réglée.

TRUE_STAGE

(chaîne, obligatoire) Où le message avance lorsque la valeur est égale à VALUE. pepsi-setup(1) vérifie qu’elle nomme une étape existante.

FALSE_STAGE

(chaîne, obligatoire) Où le message avance sinon (la valeur diffère, le chemin est absent, ou il se résout en un tableau/objet). pepsi-setup(1) vérifie qu’elle nomme une étape existante.

85.2.1.1.14.23. Options de pepsi-stage-milter

Une étape avec PROGRAM = pepsi-stage-milter remet le message à un daemon milter existant (le protocole de filtrage de courrier de sendmail/Postfix) et l’achemine selon le verdict du filtre. Voir pepsi-stage-milter(1), et notez en particulier que le filtre s’exécute après la mise en file, de sorte qu’un REJECT coûte un rebond là où un MTA aurait répondu 5xx à l’intérieur de la session SMTP.

SOCKET

(chaîne, obligatoire) Où le daemon milter écoute, dans la grammaire S= de sendmail (que Postfix accepte aussi) : unix:/path (ou son synonyme local:/path), inet:host:port, inet:port@host, inet6:[addr]:port ou inet6:port@addr. Un chemin nu sans schéma est rejeté. Pepsi se connecte à cette socket ; il ne démarre, n’arrête ni ne confine jamais le daemon derrière elle.

MILTER_NAME

(chaîne, facultative) Exportée au filtre comme macro {daemon_name} et employée dans les messages de journal. Vaut par défaut le nom propre de l’étape.

ACCEPT_STAGE

(chaîne, facultative) Où SMFIR_ACCEPT envoie le message. Vaut par défaut NEXT_STAGE, ce qui fait d’accepter et de continuer la même chose ; réglez-la pour sauter par-dessus le reste d’une chaîne de filtres, ce que la liste de milters de Postfix fait nativement. pepsi-setup(1) vérifie qu’elle nomme une étape existante.

REJECT_STAGE

(chaîne, facultatif) Où SMFIR_REJECT envoie le message, et vers où les destinataires rejetés individuellement sont répartis. Vaut par défaut le BOUNCE_STAGE de la section. Pointez-la vers une pepsi-stage-discard(1) pour abandonner le courrier rejeté au lieu de le faire rebondir. pepsi-setup(1) vérifie qu’elle nomme une étape existante.

QUARANTINE_STAGE

(chaîne, facultative) Où SMFIR_QUARANTINE envoie le message. Non définie, cela signifie abandonner : Pepsi n’a pas de magasin de quarantaine, seulement une route. Une demande de quarantaine décide de l’acheminement quel que soit le verdict qui la suit, car un milter sendmail met en quarantaine puis renvoie tout de même une acceptation. pepsi-setup(1) vérifie qu’elle nomme une étape existante.

ON_FAILURE

(``tempfail``/``accept``/``reject``/``discard``, par défaut ``tempfail``) Que faire lorsque le milter ne peut être joint, expire ou parle quelque chose d’inanalysable — le milter_default_action de Postfix, avec la même valeur par défaut. tempfail met le message en pause pour réessai, de sorte qu’un filtre arrêté retarde le courrier plutôt que de le perdre ou de le laisser passer non filtré. Un message encore différé après MAX_LIFETIME (par ce chemin ou par le propre SMFIR_TEMPFAIL du filtre) va vers le BOUNCE_STAGE de la section, ou est laissé failed pour pepsi-failure-bouncer(1) s’il n’y en a pas — jamais vers REJECT_STAGE, qui peut abandonner du courrier silencieusement.

ALLOW_ACTIONS

(chaîne, ``addhdrs chghdrs chgbody`` par défaut) Les actions de modification SMFIF_* offertes au filtre, séparées par espaces ou virgules : addhdrs, chghdrs, chgbody, addrcpt, delrcpt, addrcpt_par, chgfrom, quarantine ; plus les raccourcis all et none. Il n’y a pas d”inshdr : libmilter conditionne aussi l”insertion d’en-têtes à SMFIF_ADDHDRS.

Sans bac à sable autour du filtre, ce masque est le seul levier disponible sur le rayon d’action, et le défaut est là où il gagne sa place : chaque filtre de contenu fonctionne avec, tandis qu’un filtre qui veut réécrire l”enveloppe doit se le voir accorder explicitement. Un filtre exigeant une action qui n’a pas été offerte est signalé nommément et prend le chemin ON_FAILURE, plutôt que de voir ses modifications abandonnées en silence comme Postfix les abandonne.

SMFIF_SETSYMLIST n’est délibérément pas listé et n’a besoin d’aucune autorisation : il n’autorise aucune modification du message.

PROTOCOL_VERSION

(entier 2–6, 6 par défaut) La version la plus élevée du protocole milter offerte ; le filtre négocie à la baisse depuis elle. Le milter_protocol de Postfix.

CONNECT_TIMEOUT

(durée, ``30 s`` par défaut) Borne sur l’établissement de la connexion et l’achèvement de la négociation d’options — les deux moitiés de « ce filtre est-il joignable du tout ». Le milter_connect_timeout de Postfix.

COMMAND_TIMEOUT

(durée, ``30 s`` par défaut) Borne sur la réponse à une seule commande jusqu’à la fin du corps. Le milter_command_timeout de Postfix.

CONTENT_TIMEOUT

(durée, ``300 s`` par défaut) Borne sur le verdict de fin de message, là où un filtre de contenu fait son vrai travail. Un SMFIR_PROGRESS du filtre remet le chronomètre à zéro. Le milter_content_timeout de Postfix.

Chacun des trois timeouts doit être supérieur à zéro et au plus égal à 24 h.

RETRY_INITIAL / RETRY_MAX_INTERVAL / RETRY_FACTOR / MAX_LIFETIME

(durées / nombre, facultatif) Le calendrier de reprise partagé pour le chemin d’échec temporaire, avec la même signification que dans les étapes de relais. Par défaut : 300 s, 1 h, 2, 120 h.

MACROS_CONNECT / MACROS_HELO / MACROS_MAIL / MACROS_RCPT / MACROS_DATA / MACROS_EOH / MACROS_EOM

(chaîne, facultative) Les macros sendmail exportées à chaque phase du protocole, séparées par espaces ou virgules. Les valeurs par défaut sont celles de Postfix, de sorte que la documentation propre à un filtre s’applique inchangée : j {daemon_name} {daemon_addr} v _, {tls_version} {cipher} {cipher_bits} {cert_subject} {cert_issuer}, i {auth_type} {auth_authen} {auth_author} {mail_addr} {mail_host} {mail_mailer}, i {rcpt_addr} {rcpt_host} {rcpt_mailer}, et i pour les trois restantes. Une macro dont ce déploiement ne connaît pas la valeur n’est pas envoyée du tout. Réglez une liste sur la sentinelle none pour n’exporter rien à cette phase — une valeur vide se lit comme absente et réapplique le défaut. Un filtre qui nomme sa propre liste avec SMFIF_SETSYMLIST redéfinit celles-ci.

85.2.1.1.14.24. Options de pepsi-stage-route

Une étape avec PROGRAM = pepsi-stage-route choisit une étape suivante pour chaque destinataire d’enveloppe d’après le domaine de ce destinataire, scindant le message sur des lignes sœurs lorsque les destinataires divergent. Elle existe pour une passerelle placée devant un autre système de courrier (voir le chapitre « Microsoft Exchange comme passerelle » du manuel) : les domaines derrière une telle passerelle sont exactement les domaines dont le MX public est la passerelle, de sorte qu’acheminer l’un d’eux vers un relais direct-au-MX soit une boucle de courrier plutôt qu’un échec de remise.

L’ordre de consultation par destinataire est ROUTES, puis l’ensemble des domaines gérés, puis NEXT_STAGE.

ROUTES

(chaîne, facultative) Paires <domain-pattern>=<stage> séparées par espaces ou virgules, consultées en premier et dans l’ordre écrit. Les motifs sont comparés sans distinction de casse et peuvent contenir *, qui correspond à toute suite de caractères ; ce sont des globs, non des expressions régulières, ancrés aux deux extrémités, de sorte que *.example.org corresponde à mail.example.org mais ni à example.org ni à mail.example.org.evil.test. Une valeur qui ressemble à une expression régulière est rejetée plutôt que de ne correspondre silencieusement à rien. Les règles explicites sont consultées avant l’ensemble géré, de sorte qu’un sous-domaine puisse être découpé sans retirer son parent de MANAGED_DOMAINS.

MANAGED_DOMAINS

(chaîne, facultative) Les domaines derrière cette passerelle, séparés par espaces ou virgules, globs * autorisés. Vaut par défaut [pepsi-ingress] ACCEPTED_DOMAINS, de sorte que l’ensemble ne puisse pas dériver de ce que l’ingress accepte réellement. Au moins un domaine doit se résoudre, depuis l’une ou l’autre source.

MANAGED_STAGE

(chaîne, facultative) Où va un destinataire d’un domaine géré — dans un déploiement de passerelle, l’étape qui relaie vers le système situé derrière. Sans elle, les destinataires gérés prennent NEXT_STAGE, dont pepsi-setup(1) doit alors prouver que ce n’est pas une boucle.

NEXT_STAGE

(chaîne, obligatoire) Où va tout autre destinataire. Obligatoire : l’étape ne remet, ne fait rebondir ni n’abandonne jamais un message, chaque destinataire doit donc avoir un endroit où aller.

RECIPIENT_CHECK

(``none``, ``probe`` ou ``map``, facultatif) Comment pepsi-ingress(1) peut savoir si une adresse d’un domaine géré existe sur le système derrière la passerelle, afin de pouvoir refuser une adresse inconnue au moment du RCPT (voir [pepsi-ingress] VERIFY_RECIPIENTS). La route elle-même ne la lit jamais ; elle est définie ici parce que cette section décrit le backend. Utilisée uniquement avec MANAGED_STAGE.

none (la valeur par défaut) laisse les domaines gérés non vérifiés : chaque adresse est acceptée, et le rebond propre au backend fait office de réponse. probe interroge le backend : MAIL FROM:<>, RCPT TO, RSET, sans qu’aucun message soit envoyé. Seul un refus 5.1.x (ou un simple 550) compte comme « utilisateur inexistant ». Tout le reste — backend injoignable, report, boîte aux lettres pleine — accepte. Les réponses sont mises en cache, un « oui » pour une heure et un « non » pour cinq minutes. Un backend qui accepte toute adresse et rebondit plus tard (Exchange avec le filtrage des destinataires désactivé) répond toujours « oui » ; pour un tel backend, utilisez map, qui lit les adresses valides depuis RECIPIENT_MAP.

PROBE_HOST, PROBE_PORT, PROBE_TLS, PROBE_TIMEOUT

(facultatif ; PROBE_HOST obligatoire pour ``probe``) Où et comment sonder : le nom d’hôte ou l’adresse du backend, son port (par défaut 25), opportunistic (la valeur par défaut), starttls, tls ou none, et le délai d’expiration par commande (par défaut 10 s). La sonde porte une adresse, jamais un message, si bien que le TLS opportuniste accepte n’importe quel certificat, comme la remise à un MX ; starttls et tls le vérifient.

RECIPIENT_MAP

(chemin ; obligatoire pour ``map``) Les adresses valides, une par ligne : une adresse, ou @domain pour toute adresse d’un domaine. Tout ce qui suit le premier mot est ignoré, de sorte que le fichier source d’une table Postfix relay_recipient_maps (alice@example.org OK) peut être utilisé tel quel. # commence un commentaire. Le fichier est lu à chaque vérification. S’il ne peut pas être lu, toute adresse est acceptée.

pepsi-setup(1) vérifie que chaque cible nomme une étape existante et refuse une configuration dans laquelle un message destiné à un domaine géré pourrait atteindre pepsi-stage-relay-to-internet(1) — en avançant à travers NEXT_STAGE et toute autre étape d’acheminement, mais délibérément pas à travers BOUNCE_STAGE (un rebond est un nouveau message au sujet d’une remise déjà échouée, et atteint légitimement un relais).

85.2.1.1.14.25. Options de pepsi-stage-aliases

Une étape avec PROGRAM = pepsi-stage-aliases développe les destinataires d’enveloppe d’un message à travers un fichier de mappage d’alias avant de le transférer :

ALIASES

(chaîne, obligatoire) Le fichier de carte d’alias — un chemin de système de fichiers pris tel quel, qui, contrairement à une option de type chemin, n’est donc pas développé par $ — analysé comme une table Postfix virtual(5) : chaque ligne associe une clé (une adresse complète, un attrape-tout @domain, ou un joker * tel que sales-*@example.org) à une ou plusieurs adresses cibles séparées par virgules/espaces ; les commentaires # et les lignes vides sont ignorés. Les destinataires correspondant à une clé sont remplacés par ses cibles (transitivement, avec une protection contre les boucles) et le résultat est dédupliqué ; sur des jokers concurrents, la correspondance la plus spécifique l’emporte. Le fichier est relu seulement lorsque son heure de modification change ; un fichier manquant est traité comme une carte vide. pepsi-setup(1) en vérifie la syntaxe au moment de l’installation lorsqu’il est présent. Voir pepsi-stage-aliases(1).

NEXT_STAGE

(chaîne, obligatoire) Où le message (développé) avance. pepsi-setup(1) vérifie qu’elle nomme une étape existante.

85.2.1.1.14.26. Options de pepsi-stage-edit-settings

Une étape avec PROGRAM = pepsi-stage-edit-settings lit :

EDITABLE_STAGES

(liste, obligatoire) Noms d’étapes séparés par espaces/virgules dont un e-mail de contrôle peut changer les options. Au moins un est obligatoire, chacun doit nommer une étape existante (pepsi-setup(1) le vérifie), et un corps adressant toute étape non listée ici est refusé.

RESPONSE_STAGE

(chaîne, obligatoire) Étape à laquelle la réponse est injectée (typiquement le début du chemin sortant de signature/relais), de sorte qu’elle soit signée en DKIM et remise. Doit se résoudre en une étape existante.

NEXT_STAGE

(chaîne, obligatoire) Où un message non-contrôle est avancé. Une étape sans NEXT_STAGE produit une erreur à l’exécution au premier message ordinaire.

SUBJECT

(chaîne, facultative) Le sujet exact qui marque un message de contrôle, et le sujet de la réponse. Par défaut Pepsi.

CONTROL_LOCAL_PART

(chaîne, facultative) Partie locale de l’adresse de contrôle. Par défaut pepsi.

RESPONSE_FROM

(chaîne, facultative) En-tête From: de la réponse. Par défaut <CONTROL_LOCAL_PART@domain> pour le domaine contrôlé auquel le message était adressé.

UNRESTRICTED_UNSAFE_STAGES

(booléen, facultatif) Lever la restriction de sûreté sur ce qu’un e-mail de contrôle peut régler. Par défaut NO.

Avec la valeur par défaut, deux choses sont refusées, si permissif que soit EDITABLE_STAGES. Une affectation qui règle le PROGRAM d’une étape n’est acceptée que si la valeur est une commande pepsi-stage-* nue sans composante de chemin : un titulaire de compte ne peut donc pas pointer l’une de ses étapes modifiables vers un exécutable arbitraire ; et une affectation qui règle une option d”identité — SIGNING_DOMAIN, qui redéfinit le domaine du From: propre au message et ferait donc signer le courrier d’un compte au nom de n’importe quel domaine dont cet hôte détient une clé — est refusée d’emblée, faute de valeur sûre à autoriser. Régler ceci sur YES supprime les deux contrôles — l’option porte le nom de ce qu’elle fait, et il n’y a aucune raison de l’activer qui ne commence par faire confiance à chaque adresse dont les redéfinitions sont modifiables.

85.2.1.1.14.27. Options de pepsi-stage-vks-confirm

Une étape avec PROGRAM = pepsi-stage-vks-confirm suit le lien de confirmation du courrier de vérification d’adresse d’un serveur de clés, de sorte qu’une clé téléversée devienne trouvable par adresse. Elle siège sur le chemin entrant et fait avancer intact tout ce sur quoi elle n’agit pas — c’est-à-dire presque tout le courrier. Voir pepsi-stage-vks-confirm(1) pour la liste complète des conditions qu’elle vérifie avant de récupérer quoi que ce soit.

NEXT_STAGE

(chaîne, obligatoire) Où va chaque message que cette étape ne consomme pas. Obligatoire plutôt que facultative : une étape du chemin entrant qui abandonnerait silencieusement ce qu’elle ne reconnaît pas perdrait du courrier ordinaire. pepsi-setup(1) vérifie qu’elle nomme une étape existante.

VKS_HOST

(chaîne, facultative) L’unique hôte dont un courrier de vérification peut venir et vers lequel un lien peut pointer. Vaut par défaut l’hôte de [pepsi-keys] VKS_SERVER, et pepsi-setup(1) refuse tout autre hôte : les téléversements vont vers ce serveur, si bien que son courrier de vérification est le seul sur lequel l’étape existe pour agir. Comparé exactement : un sous-domaine d’un serveur de clés n’est pas le serveur de clés. Facultative seulement grâce à ce repli — sans cette option ni hôte VKS_SERVER, l’étape refuse de démarrer, n’ayant aucun moyen de distinguer le courrier d’un serveur de clés de celui de quiconque.

MAX_LINKS

(entier, facultatif) Combien de liens un message peut coûter. 3 par défaut, minimum 1 (0 est refusé : pour ne suivre aucun lien, retirez l’étape du pipeline). Un véritable courrier de vérification en porte un ; la borne est ce qui empêche qu’un message ayant franchi toutes les autres vérifications ne devienne un nombre arbitraire de requêtes.

DISCARD_CONFIRMED

(booléen, facultatif) Si un courrier de confirmation sur lequel l’étape a agi est supprimé plutôt que remis. YES par défaut : c’est du courrier de machine au sujet d’une action que Pepsi a entreprise, adressé à une boîte dont le propriétaire ne l’a pas demandé, et il a déjà été traité au moment où il arriverait. Seul un courrier après lequel au moins une identité a été vérifiée comme publiée est supprimé ; lorsque suivre ses liens n’a rien vérifié, il est remis malgré tout.

REQUIRE_AUTHENTICATION

(booléen, facultatif) Si SPF ou DMARC doit avoir réussi, et pas seulement l’expéditeur d’enveloppe correspondre à VKS_HOST. YES par défaut. Notez qu’une réussite DKIM ne satisfait délibérément pas ceci : elle dit qu’une signature s’est vérifiée, non de qui elle est.

Il n’y a pas de BOUNCE_STAGE : l’étape ne fait jamais échouer un message.

85.2.1.1.15. La section [pepsi-dispatch]

Options pour pepsi-dispatch(1). Le dimensionnement du pool de workers par étape (PARALLELISM, MAX_MESSAGES, QUEUE_LIMIT) réside dans chaque section [stage-<name>] ci-dessus, pas ici. Chaque durée ci-dessous doit être supérieure à zéro et au plus égale à 168 h ; pepsi-setup(1) et le dispatcher refusent toute autre valeur.

CONFIG_FILE

(chemin, facultatif) Le fichier de configuration passé aux workers lancés via -c. Réglez-le sur le chemin de ce fichier chaque fois que le dispatcher est démarré avec un -c explicite (le chemin chargé ne peut être récupéré sinon) ; s’il n’est pas réglé, les workers utilisent la recherche de configuration par défaut.

POLL_INTERVAL

(durée, optionnel) Battement de cœur de sécurité : la durée maximale pendant laquelle le dispatcher dort lorsqu’aucune nouvelle tentative paused, aucun recyclage de worker et aucun délai de démarrage plus proche n’est dû ; il recherche alors du travail et remet en file les enregistrements paused échus. Par défaut 30 s. C’est une échéance absolue, non une période de calme : le trafic de messages, et un STATS_INTERVAL plus court, ne la repoussent pas, de sorte que les enregistrements paused sont remis en file à temps même sur un pipeline chargé.

MAX_RUNTIME

(durée, facultative) Temps réel maximal qu’un worker peut passer sur un message unique. Un worker qui le dépasse est tué (et remplacé) et le message mis à timeout. Par défaut 300 s.

WORKER_IDLE_TIMEOUT

(durée, facultative) Combien de temps un processus worker inactif est conservé avant d’être arrêté. La concurrence totale est réglée par étape (PARALLELISM), pas globalement. Par défaut 5 s.

STATS_INTERVAL

(durée, facultative) À quelle fréquence les statistiques de pipeline en mémoire (exportées par pepsi-httpd(1) à /metrics) sont vidées dans la base de données, en une seule transaction. Aussi vidées dès que le pipeline devient inactif (au plus une fois par seconde) et à l’arrêt ; un dispatcher inactif sans rien de nouveau à consigner n’écrit rien. Par défaut 60 s.

DB_POOL_SIZE

(nombre, facultatif) Nombre maximal de connexions PostgreSQL dans le pool de base de données du dispatcher. Contrairement à un worker d’étape à connexion unique, le dispatcher traite les résultats de nombreux workers (faisant avancer/échouer leurs messages) en concurrence avec ses propres requêtes de coordinateur, il garde donc un petit pool borné. Le travail par instruction est bref, de sorte qu’une poignée de connexions absorbe un fort renouvellement de workers. Par défaut 8 ; ne le relevez que si le coordinateur est privé de connexions, et gardez la somme du pool de chaque composant en dessous du max_connections de PostgreSQL.

FAIR_SCHEDULING

(booléen, facultatif) Partage équitablement le temps de worker de chaque étape entre les expéditeurs (le compte authentifié, sinon l’adresse qui se connecte, une adresse IPv6 étant prise par /64 ; voir « Ordonnancement équitable entre expéditeurs » dans pepsi-dispatch(1)) au lieu de revendiquer strictement les plus anciens d’abord, de sorte que la rafale d’un expéditeur ne retarde pas tous ceux qui sont en file derrière elle. Par défaut yes ; no rétablit l’ordre du plus ancien d’abord.

FAIR_HALF_LIFE

(durée, facultative) La vitesse à laquelle l’avance accumulée d’un expéditeur en temps de worker s’estompe : elle est divisée par deux toutes les FAIR_HALF_LIFE, de sorte que la pénalité d’une rafale passée se dissipe une fois que l’expéditeur s’arrête. Par défaut 60 s.

FAIR_FIFO_PERCENT

(nombre, facultatif) Pourcentage des créneaux revendiqués de chaque étape réservés à ses messages en attente les plus anciens, quel que soit l’expéditeur — la garantie qu’aucun message n’attend indéfiniment, quel que soit le nombre d’autres expéditeurs qui continuent d’arriver. De 1 à 100 ; 100 revient au plus ancien d’abord avec une comptabilité supplémentaire (utilisez FAIR_SCHEDULING = no pour cela). Par défaut 10.

85.2.1.1.16. La section [pepsi-list]

Options pour pepsi-list(1) et le sous-système de listes de diffusion, lues par cet outil, par les étapes de liste et par pepsi-setup(1). Chaque option a une valeur par défaut : un site qui n’héberge aucune liste n’a donc besoin d’aucune section.

Le sous-système de listes de diffusion de Pepsi est une réimplémentation de GNU Mailman 3 ; son modèle de données, son API REST, son vocabulaire de commandes par e-mail et les noms de ses modèles de notification sont la conception du projet GNU Mailman, dont la Free Software Foundation détient les droits. Voir COPYING et vendor/PEPSI-VENDORING.md pour les fichiers repris d’amont, qui demeurent sous la GPL.

La configuration par liste n’est pas ici. Les listes sont créées à l’exécution par des personnes qui ne sont pas l’exploitant, potentiellement par milliers ; ce fichier appartient à l’exploitant et est rechargé d’un bloc. Les 99 attributs par liste résident dans la table mailing_list et se gèrent avec pepsi-list(1). Ce qui suit n’est que ce que le site possède.

SITE_OWNER

(adresse, facultatif) Où vont les notifications d’une liste lorsque la liste n’a pas de propriétaire à elle. Sans elle, une liste sans propriétaire est une erreur pour pepsi-list check et non un avertissement, car ses messages retenus et ses demandes de modération n’atteindraient absolument personne.

BASE_URL

(URL, facultatif) URL publique vers laquelle pointent les liens d’archives et les en-têtes List-*, pour les domaines qui ne posent pas leur propre base_url. Sans elle, aucun en-tête List-Archive: ne peut être écrit.

API_USER, API_PASS

(chaîne, facultatif) Identifiants HTTP Basic de l’API REST de GNU Mailman 3 – les [webservice] admin_user/admin_pass d’amont sous un nom Pepsi. Posez les deux ou aucun : la moitié d’un identifiant n’authentifie personne, et pepsi-list check signale l’un sans l’autre comme une erreur. L’API n’est servie que sur un listener marqué LIST_API = yes.

API_BASE_URL

(URL, facultative) L’origine absolue à partir de laquelle sont construits chaque self_link et chaque Location qu’émet l’API REST, par exemple http://localhost:8001 ; un / final est retiré. Non définie, le Host de la requête elle-même est utilisé, ce qui est correct derrière un proxy inverse.

API_RATE_LIMIT

(entier, facultatif) Requêtes par minute et par adresse source sur l’API REST. 3000 par défaut, délibérément élevé afin qu’une suite de compatibilité ne soit pas bridée ; un 429 de cette API provient de ce limiteur.

DEFAULT_LANGUAGE

(chaîne, facultative) La langue dans laquelle démarre une nouvelle liste, et le bas de la chaîne de préférences (GET /<api>/system/preferences). en par défaut.

RELEASE_STAGE

(chaîne, facultative) La section [stage-<name>] qui exécute pepsi-stage-list-post(1), où l”acceptation d’un message retenu par un modérateur réintègre le pipeline. Sans elle, les messages retenus peuvent être lus et rejetés mais pas acceptés, et pepsi-setup(1) avertit.

NOTICE_STAGE

(chaîne, facultative) L’étape à laquelle les balayages périodiques de rebonds de pepsi-list tasks injectent leurs avis aux membres. pepsi-setup(1) l’exige, et vérifie qu’elle nomme une étape existante, dès qu’une étape pepsi-stage-list-bounce(1) existe : sans elle, le compteur d’avertissements d’un membre augmente sans que le membre en soit jamais informé.

BOUNCE_PROBES

(booléen, facultatif) Si un membre dont le score de rebonds franchit le seuil de la liste reçoit une sonde (le score étant remis à zéro tant qu’elle est en attente, et un rebond de la sonde désactivant le membre) plutôt que d’être désactivé aussitôt. NO par défaut. Voir pepsi-stage-list-bounce(1).

BOUNCE_EVENT_RETENTION

(entier, facultatif) Combien de temps un événement de rebond traité est conservé, en jours. 1 par défaut.

UNSUBSCRIBE_SECRET

(chaîne, facultative) Secret qui sert de clé au jeton de désabonnement en un clic de la RFC 8058, que pepsi-stage-list-deliver(1) calcule et que pepsi-httpd(1) vérifie. Sans lui, la forme en un clic https: n’est pas émise et la forme mailto: reste seule. pepsi-setup(1) l’écrit dans secrets.d/pepsi-list.secret (mode 0640, pepsi-httpd:pepsi) et y fait référence avec @inline-secret@.

TEMPLATE_FETCH_TIMEOUT, TEMPLATE_FETCH_MAX_BYTES, TEMPLATE_FETCH_ALLOW_INTERNAL

(durée, entier, booléen ; facultatifs) Limites sur la récupération de l’URI list_template qui redéfinit le modèle d’une liste, que définit un propriétaire de liste plutôt que l’opérateur : l’échéance de la récupération complète (5 s par défaut), le plus grand modèle accepté (65536 octets par défaut), et si un hôte qui se résout vers une adresse interne peut être récupéré (NO par défaut ; chaque adresse vers laquelle l’hôte se résout est vérifiée).

WEB_RATE_LIMIT, WEB_SEARCH_RATE_LIMIT

(entier, facultatif) Requêtes par minute et par adresse source sur l’interface web publique des listes (un [pepsi-httpd-listener-*] avec LISTS = yes), et le budget distinct, plus serré, de sa route de recherche. 600 et 30 par défaut ; une valeur inférieure à 1 est relevée à 1.

MAX_MESSAGE_SIZE

(entier, facultatif) Plafond du site sur la max_message_size d’une liste, en kilo-octets ; 0 (le défaut) signifie aucun plafond de site. Une valeur par liste supérieure est bornée, et pepsi-list check le signale.

MAX_LIST_HOPS

(entier, facultatif) Combien de fois un message peut traverser une liste avant d’être traité comme un cycle d’abonnements entre deux listes et rejeté. Vaut 5 par défaut. Une liste chapeau – une liste abonnée à une autre liste – est une configuration prise en charge ; ceci est ce qui empêche deux listes mutuellement abonnées d’amplifier. Le compteur voyage dans un en-tête X-Pepsi-List-Hops: et non dans l’état du message, parce que le courrier d’une liste chapeau part par SMTP et revient comme un message tout neuf ; pepsi-ingress retire l’en-tête du courrier qui n’est pas arrivé par un chemin de soumission authentifié ou local, il ne peut donc pas être remis à zéro par un inconnu.

INVITE_RATE

(entier, facultatif) Invitations de bascule par heure. Vaut 300 par défaut. Le premier acte d’un site en migration est un envoi de masse à tout son effectif depuis une IP sans réputation : la campagne d’invitations est donc limitée en débit et reprenable, et non une boucle.

ARCHIVE_RETENTION

(entier, facultatif) Conservation par défaut des archives, en jours ; 0 (le défaut) garde tout. Surchargé par liste avec pepsi-list list set-ext <list> archive_retention_days <n>, où 0 garde l’archive de cette liste quoi que dise cette option. Appliqué chaque jour par le balayage de conservation de pepsi-list tasks --once (l’unité pepsi-list-tasks.timer).

SEARCH_TRIGRAM

(off | short | full, facultatif) Plafond du site sur la portée de l’index de recherche par trigrammes (sous-chaîne et approchée) d’une liste. Vaut short par défaut.

Un plafond, non un défaut : chaque liste choisit off, short ou full jusqu’à lui, de sorte qu’abaisser cette valeur réduit l’index à la prochaine pepsi-archive reindex au lieu de ne toucher que les listes créées ensuite. short indexe l’objet, l’objet du fil et le nom et l’adresse de l’expéditeur ; full y ajoute le corps du message et sera probablement le plus gros objet de la base.

La recherche par trigrammes exige l’extension pg_trgm, livrée dans postgresql-contrib. Un site sans elle s’installe et fonctionne normalement avec la seule recherche plein texte ; pepsi-list check indique dans quel mode le site se trouve.

LIST_FANOUT_BATCH

(entier, facultatif) Enregistrements frères matérialisés par lot d’éclatement. Vaut 256 par défaut.

Un message de liste est remis sous la forme d’un enregistrement de file par destinataire, afin que chaque copie puisse porter l’URI de désabonnement en un clic propre à ce membre. Ceci borne combien en existent à la fois, et donc le stockage transitoire qu’une grosse pièce jointe vers une grande liste occupe : un message de 5 Mo vers une liste de 5 000 membres culmine autour de 1,3 Go au lieu de 25 Go. Augmenter la valeur fait s’écouler un gros envoi plus vite et coûte plus d’espace.

TOMBSTONE_RETENTION

(entier, facultatif) Combien de temps une pierre tombale de suppression est conservée, en jours. Vaut 90 par défaut.

Supprimer un message des archives conserve sa Message-ID pendant ce temps, afin qu’un réenvoi ou un import rejoué ne puisse pas réarchiver en silence ce qui a été supprimé. pepsi-archive purge --forget saute la pierre tombale pour le cas où même quatre-vingt-dix jours seraient de trop.

ARCHIVE_PARTITIONS

(entier, facultatif) Partitions de hachage des tables d’archives. Vaut 32 par défaut. Lu uniquement par pepsi-setup(1), et fixé à l’installation.

PostgreSQL ne sait pas repartitionner à chaud : changer le module implique une nouvelle table et une copie complète de chaque message archivé. pepsi-setup crée les partitions une fois et refuse de les changer en silence lors d’une exécution ultérieure, et pepsi-list check signale une configuration qui contredit ce qui est sur le disque – la valeur installée fait autorité, car les tables ne peuvent pas être modifiées et ce fichier si. Choisissez une fois.

85.2.1.1.17. La section [pepsi-failure-bouncer]

Options pour pepsi-failure-bouncer(1), qui déplace les messages failed/timeout vers une étape de rebond afin que l’expéditeur soit notifié. Lu seulement par cet outil.

BOUNCE_STAGE

(chaîne, requise lorsque l’outil est utilisé) Le label [stage-<name>] vers lequel un message bloqué est déplacé (et réinitialisé à pending). Normalement la même étape de rebond vers laquelle le pipeline achemine déjà les échecs permanents (par exemple bounce). Un message déjà à cette étape est laissé intact, de sorte qu’un rebond qui échoue à l’étape de rebond ne boucle pas. pepsi-setup(1) vérifie que l’étape nommée existe. Nécessaire sur tout déploiement qui exécute pepsi.target : son pepsi-failure-bouncer.timer lance l’outil toutes les dix minutes, et chaque exécution échoue sans cette option. La configuration livrée et celle de l’assistant la fixent à bounce.

MIN_AGE = DURATION

Depuis combien de temps un message doit être failed/timeout avant d’être déplacé (par défaut 1 h) : la fenêtre pendant laquelle un opérateur peut le remettre en place avec pepsi-queue(1) avant que son expéditeur ne soit informé. Mesuré à partir de state.failed_at, que la base de données appose lorsque la ligne échoue ; une ligne sans cet horodatage est déplacée immédiatement. 0 s déplace chaque échec sur-le-champ.

85.2.1.1.18. La section [pepsi-sendmail]

Options pour pepsi-sendmail(1), le client de soumission locale compatible Sendmail que le paquet Debian installe comme /usr/sbin/sendmail. Chaque option a une valeur par défaut, un site n’a donc besoin d’aucune section.

Le client est non privilégié et n’affirme aucune identité : il remet le message à un listener d’ingress de domaine UNIX, qui dérive le compte de l’expéditeur des identifiants du processus appelant rapportés par le noyau (AUTH_PEERCRED, ci-dessus).

SOCKET

(chemin, facultatif) La socket de soumission de domaine UNIX de pepsi-ingress. /run/pepsi/submission.sock par défaut.

Bien qu’elle vive dans la section du client, cette option est lue par les deux extrémités : pepsi-ingress sert cette socket inconditionnellement et synthétise son listener depuis ce chemin, de sorte qu’il n’y ait pour elle aucune section [pepsi-ingress-listener-*] ni seconde déclaration qui pourrait nommer un autre chemin.

Sous systemd, le descripteur est hérité lorsque pepsi-ingress.socket lie déjà ce chemin — apparié par l’adresse à laquelle le descripteur est lié, non par un FD_INDEX — de sorte qu’un changement ici exige un ListenStream= correspondant dans l’unité. Sinon le serveur lie le chemin lui-même, en mode 0666, et refuse de démarrer s’il ne le peut pas. Ce mode n’accorde rien en lui-même : ouvrir la socket ne confère aucun droit d’envoyer, car le noyau fournit l’identité de l’appelant et USERNAME_MAP décide de ce qu’elle peut envoyer comme adresse.

La valeur spéciale none désactive entièrement la soumission locale : aucune socket n’est servie et pepsi-sendmail(1) refuse de s’exécuter, de sorte que les programmes locaux doivent s’authentifier sur 587/465. pepsi-setup(1) le signale une fois.

EHLO_NAME

(chaîne, facultative) Nom annoncé dans EHLO. Par défaut [pepsi-ingress] HOSTNAME. Cosmétique : le serveur authentifie le pair par ses identifiants, pas par ce qu’il prétend ici.

DEFAULT_DOMAIN

(chaîne, facultative) Domaine ajouté au login du compte appelant pour former l’expéditeur d’enveloppe lorsque ni -f ni -r n’a été donné. Vaut par défaut [pepsi-ingress] HOSTNAME (et localhost si même celui-ci n’est pas réglé).

Réglez-le lorsque les adresses que votre USERNAME_MAP reconnaît sont dans un autre domaine : le serveur associe l’uid du pair à un login puis à une adresse, et c’est un désaccord ici qui fait arriver le courrier de cron depuis un expéditeur d’enveloppe que le site ne possède pas.

85.2.1.1.19. La section [pepsi-whitelist]

Options pour pepsi-whitelist(1), l’outil qui gère la liste blanche d’expéditeurs et sait en semer une depuis la boîte aux lettres d’un utilisateur (import). Lues uniquement par cet outil ; toutes les options sont facultatives, un site qui n’utilise que add/list/remove n’a donc besoin d’aucune section.

LOCAL_DOMAINS

(chaîne, facultative) Domaines dont les expéditeurs comptent comme le courrier propre à l’utilisateur lorsqu’une boîte aux lettres est parcourue : un message dont le From:/Sender: est chez l’un d’eux est un message que l’utilisateur a envoyé, ses destinataires deviennent donc des entrées de liste blanche. Séparés par des virgules ou des espaces. Par défaut [pepsi-ingress] ACCEPTED_DOMAINS ; c’est la même option que celle qu’utilisent pepsi-stage-relay-to-maildir(1) et pepsi-stage-dot-forward(1).

TARGETS, RECIPIENT_DELIMITER

(chaîne, facultative) Comme pour les étapes de remise. TARGETS borne les comptes locaux qu”import --all-users sème (par défaut : la plage UID_MIN..``UID_MAX`` de /etc/login.defs) ; RECIPIENT_DELIMITER retire une sous-adresse avant qu’une adresse ne soit comparée.

HOSTERS_FILE

(chemin, facultatif) Fichier listant les hébergeurs e-mail publics, un domaine par ligne (# pour les commentaires ; un *. en tête couvre une arborescence de sous-domaines). Les domaines qui y figurent ne sont jamais proposés comme joker *@domain par import --auto-wildcard, quel que soit le nombre de correspondants que l’utilisateur y a — « tout le monde chez gmail.com » n’est pas un ensemble de personnes que l’utilisateur connaît, et le mettre en liste blanche offrirait à tout spammeur disposant d’un compte gratuit un contournement de la barrière anti-spam. Leurs adresses individuelles sont malgré tout importées. Par défaut ${DATADIR}/hosters.txt, qu’écrit make install ; faites pointer ceci vers votre propre copie pour étendre la liste, car celle installée est écrasée lors d’une mise à niveau.

WILDCARD_THRESHOLD

(nombre, facultatif) Combien d’adresses distinctes chez un même domaine amènent import --auto-wildcard à proposer une unique entrée *@domain pour lui. Par défaut 10.

MAX_ENTRIES

(nombre, facultatif) Nombre maximal de lignes qu’un import peut ajouter. Par défaut 5000. Chaque ligne d’une liste blanche est comparée au From: de chaque message entrant qui la consulte ; c’est donc une borne sur un coût permanent par message, et pas seulement sur la taille de la table.

SCAN_HELPER

(chaîne, facultative) Le binaire helper de parcours de boîte aux lettres, localisé sur le $PATH. Par défaut pepsi-helper-mailbox-scan (voir pepsi-helper-mailbox-scan(1)).

MAILBOX

(chemin, facultatif) Boîte aux lettres à parcourir lorsque l’utilisateur n’en nomme aucune. Par défaut le ~/Maildir de l’utilisateur s’il existe, sinon /var/mail/<login>.

85.2.1.1.20. La section [pepsi-httpd]

Options pour pepsi-httpd(1). Le serveur lit aussi les domaines servis (ACCEPTED_DOMAINS), l’hôte mx de MTA-STS (le HOSTNAME de l’ingress) et les options MTA_STS_* de [pepsi].

MAX_CONNECTIONS

(nombre, facultatif) Nombre maximal de connexions HTTP servies en concurrence. Par défaut 256.

MAX_CONNECTIONS_PER_IP

(nombre, facultatif) Nombre maximal de connexions simultanées depuis une même adresse cliente (une adresse IPv4 ou un /64 IPv6) ; une connexion au-delà est fermée aussitôt. Les connexions par socket UNIX — depuis un proxy inverse — ne portent aucune adresse cliente et ne sont pas comptées, de sorte que derrière un proxy cette limite relève du proxy. Par défaut 32 ; 0 la désactive.

DB_POOL_SIZE

(nombre, facultatif) Nombre maximal de connexions PostgreSQL dans le pool de base de données du serveur HTTP. Le serveur gère les requêtes en concurrence, de sorte que contrairement aux workers d’étape à connexion unique, il peut en utiliser plus d’une. Par défaut 1 ; ne le relevez que si les points de terminaison sont limités par la connexion unique, et gardez la somme du pool de chaque composant en dessous du max_connections de PostgreSQL.

RESUME_AUTHORIZATION_TOKEN

(chaîne, facultative) Jeton porteur gardant POST /resume (comparé en temps constant) ; le point de terminaison est désactivé (404) lorsqu’il n’est pas réglé. Utilisez la forme Taler secret-token: afin que la même valeur puisse être réutilisée comme en-tête Authorization du webhook marchand pepsi-resume (voir pepsi-stage-anti-spam(1) et la section [pepsi-payments]).

ADDIN

(booléen, facultatif) Si les routes du module d’extension Outlook (GET /addin/manifest.xml et GET /addin/taskpane.html) répondent. no par défaut : un déploiement qui ne se place pas devant un Exchange n’en a aucun usage, et un manifeste nommant une passerelle que personne n’a configurée est une demande d’assistance en puissance. Voir le chapitre « Microsoft Exchange comme passerelle » du manuel.

ADDIN_URL

(chaîne, facultative) L’origine https:// publique substituée dans les ressources du module d’extension. Non définie (le défaut), elle est dérivée de l’en-tête Host de chaque requête, ce qui fonctionne aussi bien lorsque pepsi-httpd termine le TLS lui-même que lorsqu’il se trouve derrière un proxy inverse — dans ce dernier cas il voit du HTTP simple sur une socket UNIX et ne peut pas déduire le schéma public de la connexion. Réglez-la lorsque le Host qui atteint Pepsi ne nomme pas la passerelle. Le schéma doit être https, et cela est imposé : Outlook refuse de charger les ressources d’un module d’extension en HTTP simple, de sorte qu’une origine http:// ne pourrait produire qu’un manifeste qui échoue au chargement, et pepsi-httpd refuse donc de démarrer avec une telle origine plutôt que de la servir. La seule exception est un hôte de boucle locale – localhost, tout ce qui est sous .localhost, 127.0.0.0/8 ou [::1] – où le http:// simple est accepté afin qu’un développeur ou un test n’ait besoin d’aucun certificat. La valeur est vérifiée dès qu’elle est définie, que ADDIN soit activé ou non, de sorte qu’une valeur erronée est signalée avant que la fonctionnalité ne soit activée.

Chaque section [pepsi-httpd-listener-<name>] lie une socket, avec les mêmes options SERVE (tcp/unix/systemd) et de transport qu’une section [pepsi-ingress-listener-<name>], sauf qu’un listener tcp a par défaut le PORT 443 et que MODE vaut plain ou tls (pas de STARTTLS). Un listener tls peut régler TLS_CERT/TLS_KEY comme certificat de repli. Elle accepte en outre :

ADMIN = yes | no

Si la surface d’administration — l’API /api/v1, la console d’administration /ui et la page /metrics — est servie sur ce listener. Facultatif ; vaut no par défaut. Sur un listener qui ne l’a pas, ces routes répondent un simple 404 — identique octet pour octet à ce que reçoit n’importe quel chemin inconnu — de sorte que publier le listener public ne publie pas l’administration.

/metrics fait partie de cet ensemble parce que les profondeurs de file par étape, les compteurs de plantage et les noms d’étape décrivent le pipeline ; contrairement aux deux autres, elle ne prend aucun identifiant (un collecteur Prometheus n’en a aucun à présenter), de sorte que sur un listener de métriques cet indicateur est le seul contrôle d’accès. Voir pepsi-httpd(1).

pepsi-httpd(1) refuse de les servir sur un listener marqué qui les emporterait en clair hors de cet hôte : le tcp en clair n’est accepté que sur une adresse de boucle locale, tandis que les listeners tls et les sockets unix conviennent toujours. Un listener SERVE = systemd en clair ne convient jamais — c’est l’unité qui a décidé où écoute le descripteur hérité et le serveur ne peut pas voir cette adresse : le cas qu’il ne peut pas juger est donc refusé plutôt qu’autorisé. Un listener marqué qui échoue au test journalise un avertissement au démarrage et ne sert que les points de terminaison publics, et pepsi-setup(1) rapporte la même chose au moment de la validation.

La configuration livrée marque un listener unix, qui est la forme n’exigeant aucun identifiant : un processus qui se connecte est identifié par SO_PEERCRED. Voir [pepsi-admin] ci-dessous.

LIST_API = yes | no

Si l’API REST compatible GNU Mailman 3 (les routes /3.0/ et /3.1/) est servie sur ce listener. Facultatif ; no par défaut, auquel cas ces routes répondent un simple 404. Elle est soumise au même test de liaison qu”ADMIN (TLS, une socket unix, ou tcp en clair sur la boucle locale), et son identifiant est [pepsi-list] API_USER/API_PASS.

LIST_API_TESTING = yes | no

Si cette API offre en outre le point d’accroche /3.1/reserved/reset, réservé aux tests, qui vide les tables des listes et des archives. Facultatif ; no par défaut, et sans effet à moins que LIST_API soit utilisable sur le listener. Uniquement pour un banc d’essai de compatibilité.

LISTS = yes | no

Si l’interface web publique des listes de diffusion (archives, pages d’abonnement) est servie sur ce listener. Facultatif ; no par défaut. Contrairement aux deux indicateurs ci-dessus, elle est destinée à être joignable depuis l’internet ouvert, de sorte que le test de liaison ne s’y applique pas. Ses limites de débit sont [pepsi-list] WEB_RATE_LIMIT et WEB_SEARCH_RATE_LIMIT.

Chaque section [pepsi-httpd-cert-<name>] enregistre un certificat pour la sélection SNI : SNI (un ou plusieurs noms d’hôte), TLS_CERT et TLS_KEY.

85.2.1.1.21. La section [pepsi-admin]

Options pour l’API d’administration servie par pepsi-httpd(1) sur un listener marqué ADMIN = yes. Chaque option a une valeur par défaut, la section peut donc être omise entièrement. Le modèle d’authentification, le tableau des portées et la référence des points de terminaison sont dans le chapitre « L’API d’administration » du manuel.

Les mêmes options régissent la console d’administration /ui, qui est un client de cette API et n’introduit aucune configuration propre : elle partage les délais de session, les limitations de débit, le plafond de corps, la taille de page et la connexion d’écriture de configuration. Voir le chapitre « La console d’administration » du manuel.

ADMIN_GROUP

(chaîne, facultative) Groupe UNIX dont les membres sont administrateurs locaux sur un listener à socket UNIX, identifiés par SO_PEERCRED. root l’est toujours, groupe ou pas. pepsi-admin par défaut.

SESSION_IDLE

(durée, facultative) Délai d’inactivité d’une session de navigateur, repoussé à chaque requête. 30 m par défaut.

SESSION_LIFETIME

(durée, facultative) Durée de vie dure d’une session de navigateur, jamais prolongée. 12 h par défaut. Il n’y a pas de « se souvenir de moi » : cette console peut révoquer une clé et lire qui correspond avec qui, et les administrateurs locaux — qui se connectent le plus souvent — s’authentifient par SO_PEERCRED et n’ont aucune session à expirer.

EVENT_RETENTION_DAYS

(nombre, facultatif) Durée de conservation des enregistrements d’audit, en jours. Par défaut 90. pepsi-httpd prune applique les deux durées de conservation, exécuté quotidiennement par pepsi-log-prune.timer sous le compte pepsi-httpd — le seul rôle de base de données détenant DELETE sur les journaux, puisqu’aucun composant qui traite du courrier ne doit pouvoir les effacer. Le timer est indépendant du serveur web : la conservation s’applique que pepsi-httpd.service tourne ou non.

MAIL_LOG_RETENTION_DAYS

(nombre, facultatif) Combien de temps les enregistrements du journal de courrier sont conservés, en jours, lorsque [pepsi] MAIL_LOG est activé. 30 par défaut.

Les deux rétentions sont des entiers de jours plutôt que des durées, car Section::duration analyse via jiff::SignedDuration, qui n’accepte que h/m/s et en dessous.

RATE_LIMIT

(nombre, facultatif) Requêtes par minute et par adresse source (un listener à socket UNIX partage une seule clé pour tout l’hôte). 0 désactive la limite. 120 par défaut.

LOGIN_RATE_LIMIT

(nombre, facultatif) Tentatives de connexion par minute, comptées par compte et par adresse source — beaucoup de mots de passe contre un compte et un mot de passe contre beaucoup de comptes sont des attaques différentes. 0 désactive la limite. 10 par défaut.

MAX_BODY

(nombre, facultatif) Plus grand corps de requête accepté, en octets. 1048576 par défaut.

PAGE_LIMIT

(nombre, facultatif) Taille de page par défaut d’un point de terminaison de listage. Un appelant peut en demander jusqu’à 1000 ; chaque listage honore limit et offset dans son SQL et rapporte un total exact à côté de la page, et rien ne renvoie un ensemble de résultats non borné. 100 par défaut ; une valeur configurée hors de 1..``1000`` est ramenée dans cet intervalle plutôt que rejetée.

CONFIG_DB

(chaîne de connexion PostgreSQL, facultative) Connexion employée pour les écritures de configuration. Non définie par défaut, auquel cas PUT/DELETE sur /api/v1/config répondent 503 avec la raison et tout autre point de terminaison n’est pas affecté.

Écrire pepsi.config_override appartient au rôle de base pepsi-config, que pepsi-setup(1) accorde et révoque explicitement à chaque compte de service : un composant qui traite du courrier ne doit pas pouvoir réécrire le pipeline dans lequel il s’exécute. pepsi-httpd est un tel compte, et l’authentification par pair se fonde sur l’uid effectif : sa propre connexion ne peut donc pas être ce rôle. Pointez ceci vers une connexion qui s’authentifie comme pepsi-config — un mot de passe dans un fragment secrets.d lisible par le seul compte pepsi-httpd, ou une correspondance pg_ident. Le serveur vérifie avec SELECT current_user au démarrage et refuse une connexion qui s’authentifie comme autre chose, car une frontière à laquelle le code se contente de croire n’est pas une frontière. Le refus n’est pas fatal : il est journalisé, le chemin d’écriture de la configuration reste désactivé, et le 503 porte le rôle réellement obtenu — un serveur démarré avec un privilège qu’il n’était pas censé avoir serait la pire issue.

La configuration en ligne met en file par la même connexion et pour la même raison : seul pepsi-config peut faire un INSERT dans pepsi.setup_task, et l’applicateur privilégié refuse toute ligne disant autre chose. Sans CONFIG_DB, les points de terminaison de configuration répondent 503 eux aussi — le serveur peut servir les questions et observer une tâche, et ne peut pas en demander une.

APPLY_SOCKET

(chemin, facultatif) Où sonner pour l’applicateur de configuration privilégié. /run/pepsi/setup-apply.sock par défaut.

Après avoir mis une tâche de configuration en file, pepsi-httpd se connecte à cette socket et la referme. Cette connexion est tout le message : rien n’y est écrit et rien n’en est jamais lu, elle ne peut donc pas devenir un canal de commande. Ce qu’elle fait, c’est laisser l’activation par socket de systemd démarrer pepsi-setup apply, qui prend son travail dans la base — où chaque ligne est validée et auditée — et ressort quand il n’y en a plus.

Une socket plutôt qu’un signal ou un lancement, parce que pepsi-httpd s’exécute sans privilèges, n’a aucun moyen de démarrer un processus root et ne devrait pas en acquérir un. C’est l’unique mécanisme qui lui permet de faire s’exécuter un processus privilégié sans pouvoir influencer ce que ce processus fait. Un échec de connexion n’est pas une erreur : la tâche est durablement mise en file dans les deux cas, et pepsi-setup apply --once depuis cron ou une console la reprend.

Ce chemin est aussi ce que sonde APPLIER = auto ; voir ci-dessous.

APPLIER

(auto|yes|no, facultatif) Si un changement de configuration privilégié peut avoir lieu depuis ce serveur, tout court. auto par défaut.

Les unités systemd de l’applicateur sont empaquetées séparément (le paquet Debian pepsi-httpd-admin, ou make install INSTALL_ADMIN_UNITS=no depuis les sources), afin qu’un déploiement administré depuis un terminal puisse retirer l’unique mécanisme par lequel une requête HTTP atteint /etc/pepsi. Une fois parties, rien ne vide pepsi.setup_task et une insertion dedans est inerte — la console ne doit donc pas continuer de proposer des formulaires dont les envois ne seraient silencieusement jamais appliqués.

auto

Sonder deux choses : que pepsi-setup-apply.socket existe comme fichier d’unité là où systemd en cherche un (installé), et qu”APPLY_SOCKET existe, soit une socket et soit inscriptible par ce compte (armé — se connecter à une socket UNIX exige le droit d’écriture). La socket n’est jamais connectée : se connecter est le coup de sonnette, ce qui démarrerait un processus root à chaque rendu de page. La sonde échoue en fermeture : toute incertitude, y compris un chemin qui ne peut être examiné et un nœud de socket laissé par un paquet retiré, se lit comme « pas d’applicateur ».

yes

Supposer que l’applicateur est joignable et sauter la sonde. Pour un déploiement qui vide la file autrement — pepsi-setup apply --once depuis cron, une unité écrite à la main, un hôte sans systemd — là où la sonde rapporterait comme absente une capacité qui existe. C’est une promesse que fait l’opérateur ; rien ne la vérifie.

no

Refuser chaque demande de configuration privilégiée, quel que soit ce qui est installé. Un moyen de rendre la console en lecture seule sans changer l’ensemble des paquets.

Lorsqu’il n’y a pas d’applicateur, pepsi-httpd sert toujours le questionnaire de configuration, les réponses en attente et l’historique des tâches — en lecture seule, contrôles désactivés — et répond aux points de terminaison mutants 503 setup_applier_unavailable. Voir pepsi-httpd(1).

85.2.1.1.22. L’option d’identité de sortie : PUBLIC_IP

PUBLIC_IP = ADDR [ADDR …]

Liste séparée par espaces ou virgules des adresses IPv4 et/ou IPv6 publiques qui envoient du courrier au nom de vos domaines. Chacune devient un mécanisme ip4: ou ip6: dans l’enregistrement v=spf1 que pepsi-setup(1) suggère. Aucune étape ne lit cette option à l’exécution — c’est purement une entrée pour l’enregistrement SPF généré.

PUBLIC_IP est une option par-étape définie dans la section [stage-<name>] d’une étape de relais, et pepsi-setup(1) la collecte depuis chaque étape dont le PROGRAM est pepsi-stage-relay-to-internet(1) ou pepsi-stage-relay-to-smarthost(1) — détectée par PROGRAM, jamais par le nom de section — et fait l’union des résultats. Un déploiement peut donc avoir plusieurs étapes de relais, chacune portant son propre PUBLIC_IP :

  • Sur une étape pepsi-stage-relay-to-internet, ce sont la ou les IP publiques d’envoi de cet hôte : l’hôte remet directement au MX des destinataires depuis celles-ci.

  • Sur une étape pepsi-stage-relay-to-smarthost, ce sont la ou les IP de sortie du smarthost : le courrier quitte internet depuis le smarthost, donc SPF doit l’autoriser (beaucoup de fournisseurs publient à la place un include: que vous ajoutez à l’enregistrement à la main).

Si aucune étape de relais ne définit PUBLIC_IP, l’enregistrement généré est un simple v=spf1 -all — qui indique aux destinataires qu”aucun hôte ne peut envoyer pour vos domaines et fait échouer SPF pour votre propre courrier sortant — et pepsi-setup(1) journalise un avertissement. Un déploiement en réception seule (sans étape de relais) n’a pas de PUBLIC_IP et n’est pas averti.

Chaque adresse doit être une IP publique routable mondialement — l’adresse depuis laquelle les destinataires voient le courrier arriver. pepsi-setup(1) avertit (à la validation et dans la sortie DNS) si un PUBLIC_IP est une adresse non publique (loopback, RFC 1918 / unique-local, link-local, ou CGNAT) : derrière un NAT, utilisez l’IP de sortie publique de l’hôte, pas son adresse LAN, sinon le courrier sortant sur cette famille d’adresses échouera au SPF.

DNS inverse (PTR). Chaque PUBLIC_IP de pepsi-stage-relay-to-internet — l’IP de sortie propre à cet hôte — doit aussi avoir un enregistrement DNS inverse confirmé en direct qui nomme le ``SERVER_NAME`` de l’étape : un PTR pour l’adresse, dont le nom d’hôte se résout à son tour (via A/AAAA) vers la même adresse, et qui est le nom même que l’étape annonce dans l”EHLO. De nombreux serveurs de courrier destinataires traitent un PTR absent, non confirmé en direct ou d’allure générique/dynamique comme un signal de spam et rejettent le courrier ou le classent en indésirable, et une large famille d’entre eux compare en outre le nom EHLO au PTR et refuse la session lorsque les deux nomment des hôtes différents (HELO host does not match rDNS). Être à l’intérieur de vos ACCEPTED_DOMAINS ne satisfait pas ce test — un hôte répondant à plusieurs noms peut en annoncer un et se résoudre en inverse vers un autre, tous deux les siens, et être tout de même refusé. pepsi-setup(1) avertit pour chaque PUBLIC_IP dont le DNS inverse n’est pas correct en ce sens, y compris cette discordance, et imprime la remédiation (voir pepsi-setup(1)). Le DNS inverse d’un PUBLIC_IP réside dans la zone du propriétaire de l’IP (in-addr.arpa / ip6.arpa) — en général votre FAI ou votre hébergeur — si bien que, contrairement aux enregistrements directs, ce n’est souvent pas quelque chose que vous pouvez publier vous-même ; là où cela ne peut être changé, réglez SERVER_NAME (et le HOSTNAME de [pepsi-ingress], l’enregistrement MX et le certificat TLS) sur le nom que le PTR donne déjà. Un PUBLIC_IP de pepsi-stage-relay-to-smarthost nomme les IP de sortie du smarthost, dont l’opérateur du smarthost contrôle le DNS inverse : celles-là ne sont donc pas vérifiées.

L’enregistrement unifié est publié à l’identique pour chaque domaine servi. C’est correct mais large ; dans des configurations particulières où différents domaines envoient depuis différents hôtes, un enregistrement SPF par domaine écrit à la main (ne listant que les IP d’envoi propres à ce domaine) peut être plus strict tout en restant correct. pepsi-setup(1) ne calcule pas ce regroupement automatiquement et le signale dans sa sortie DNS.

85.2.1.1.23. Les sections MTA [pepsi-stage-relay-to-smarthost]

85.2.1.1.23.1. Les sections smarthost (MTA)

Chaque section [pepsi-stage-relay-to-smarthost-mta-<name>] définit un smarthost amont ; le suffixe <name> est un label de forme libre utilisé dans les journaux. Ces sections sont partagées par chaque étape de relais vers smarthost. Un domaine de destinataire est acheminé vers le MTA dont le DOMAINS le liste, ou vers l’unique MTA CATCH_ALL.

HOST

(chaîne, obligatoire) Nom d’hôte ou adresse du smarthost auquel se connecter.

PORT

(nombre, obligatoire) Port TCP sur lequel se connecter (par exemple 587 ou 465).

MODE

(facultatif) Sécurité du transport : starttls (par défaut), tls (TLS implicite) ou plain (en clair).

TLS_VERIFY

(booléen, facultatif) Si le certificat TLS du smarthost est vérifié contre le magasin de confiance système. Par défaut yes ; no accepte n’importe quel certificat (non sûr, pour les tests uniquement).

TLS_CA

(chemin, facultatif) Un certificat de CA supplémentaire (PEM) à approuver en plus du magasin système, par exemple pour une CA de smarthost privée.

TLS_CLIENT_CERT / TLS_CLIENT_KEY

(chemin, facultatif ; les deux ou aucun) Un certificat client (chaîne PEM) et sa clé privée à présenter au smarthost pendant la poignée de main TLS (TLS mutuel). Chargés à neuf à chaque connexion. Nécessite un MODE chiffrant (tls ou starttls) et s’applique à PKIX, TLS_VERIFY = no et DANE indifféremment. La clé est secrète : gardez-la lisible seulement par le groupe pepsi-token sous lequel l’étape de relais s’exécute SGID (sur Debian, placez le certificat + la clé dans le répertoire SGID /var/pepsi/tls). Réglez AUTH = external pour aussi authentifier la session SMTP avec le certificat via SASL EXTERNAL.

DANE

(facultatif) Application DANE/TLSA (RFC 7672) vers ce smarthost : off, warn (le défaut) ou strict. Lorsque le smarthost publie des enregistrements TLSA validés par DNSSEC à _<PORT>._tcp.<HOST>, le certificat est authentifié contre eux, ayant priorité sur TLS_VERIFY (PKIX). En warn, une non-concordance est journalisée et la remise se poursuit ; en strict, un enregistrement utilisable mais non concordant, ou une recherche TLSA échouée, diffère le message. Ignoré lorsque MODE = plain. Nécessite un résolveur validant DNSSEC atteint par un chemin de confiance (Pepsi fait confiance au bit AD de la réponse) ; voir le DNS_SERVERS de l’étape.

ADDRESS_FAMILY

(facultatif) Quelles familles d’adresses IP peuvent être employées pour joindre ce smarthost : any, ipv4 (aussi orthographié v4/v4only) ou ipv6 (v6/v6only).

La précédence est : cette entrée, puis la section [stage-*] propriétaire, puis any. Le niveau par entrée est ce qui rend l’option utile : une destination qui se comporte mal peut être épinglée sans forcer toutes les autres — y compris une qui ne publie que des AAAA — sur la même famille.

Le cas qui motive cela est Microsoft Exchange Online, qui rejette le courrier venu d’une adresse IPv6 émettrice sans enregistrement PTR (550 5.7.1 ... S820). Un hôte à double pile préfère l’IPv6 : une machine au DNS inverse IPv4 correct et au DNS inverse IPv6 non délégué remet donc correctement partout sauf là.

Avec any (le défaut), le nom d’hôte est remis au résolveur du système. Toute autre valeur fait résoudre l’hôte par Pepsi lui-même et essayer tour à tour chaque adresse de la famille choisie. Une destination qui ne publie aucune adresse de la famille choisie est un échec transitoire, non un rebond : c’est une erreur d’opérateur qu’il vaut la peine de retenter, non une pour laquelle il vaudrait la peine de détruire du courrier en file.

AUTH

(facultatif) Mécanisme d’authentification SMTP : none (par défaut), plain, login, cram-md5, digest-md5, scram-sha-1, scram-sha-256, scram-sha-1-plus, scram-sha-256-plus, auto, external, oauth, ntlm ou gssapi. plain/login/cram-md5/digest-md5/la famille scram-*/auto nécessitent tous USERNAME et PASSWORD ; oauth nécessite USERNAME et TOKEN_FILE ; external (SASL EXTERNAL, RFC 4422) nécessite TLS_CLIENT_CERT / TLS_CLIENT_KEY et s’authentifie par ce certificat (aucun mot de passe envoyé), avec un USERNAME facultatif comme identité d’autorisation SASL. cram-md5 (RFC 2195) et scram-sha-1/scram-sha-256 (RFC 5802 / RFC 7677) sont des défi/réponse : le mot de passe n’est jamais envoyé, et SCRAM authentifie en outre le serveur auprès de Pepsi (une mauvaise signature de serveur est un échec permanent). Les variantes SCRAM -plus ajoutent la liaison de canal tls-server-end-point (RFC 5929). auto choisit le mécanisme le plus fort que le smarthost annonce (SCRAM-SHA-256-PLUS > SCRAM-SHA-256 > SCRAM-SHA-1-PLUS > SCRAM-SHA-1 > CRAM-MD5 > LOGIN > PLAIN) ; il ne sélectionne jamais le digest-md5 déprécié, ntlm ou gssapi. digest-md5 (RFC 2831) est aussi un défi/réponse avec authentification du serveur (rspauth) mais est déprécié (la RFC 6331 l’a passé au statut Historic) et fourni seulement pour les smarthosts hérités ; le sélectionner journalise un avertissement depuis pepsi-setup(1) et à l’exécution. ntlm est le mécanisme Microsoft de facto (sans RFC ; NTLMv2 uniquement, avec liaison de canal EPA tls-server-end-point) nécessitant USERNAME/PASSWORD/NT_DOMAIN ; il est faible et n’authentifie pas le serveur, de sorte que pepsi-setup(1) avertit. gssapi est SASL GSSAPI/Kerberos (RFC 4752) ; il ne prend aucun mot de passe, obtenant un ticket de service pour SERVICE_NAME depuis un cache d’identifiants (KRB5CCNAME). Tous ne sont offerts que sur un transport chiffré (MODE = tls/starttls) ; ntlm et gssapi rejettent MODE = plain au moment de la configuration.

USERNAME / PASSWORD

(chaîne, requise lorsque AUTH est plain/login/cram-md5/digest-md5/scram-*/auto/ntlm) Les identifiants SMTP-AUTH. Gardez PASSWORD dans un fichier à mode restreint fusionné avec @inline-secret@. Pour les mécanismes scram-*, les deux sont normalisés avec SASLprep (RFC 4013). USERNAME est aussi l’identité d’autorisation facultative pour AUTH = external et AUTH = gssapi.

NT_DOMAIN / NT_WORKSTATION

(chaîne ; NT_DOMAIN requis lorsque AUTH = ntlm) Le domaine Windows du compte NTLM, et un nom de poste de travail client cosmétique facultatif.

SERVICE_NAME

(chaîne, facultative ; AUTH = gssapi) Le principal de service Kerberos basé sur l’hôte du smarthost, sous la forme service@host. Par défaut smtp@<HOST>.

KRB5CCNAME

(chaîne, facultative ; AUTH = gssapi) Le cache d’identifiants Kerberos à lire pour ce smarthost (par exemple FILE:/var/pepsi/krb5/smarthost.cc), redéfinissant le KRB5CCNAME ambiant. Pepsi ne fait que lire le cache ; un keytab externe + un job k5start/cron doit garder le ticket à jour, et le cache doit être lisible par le worker de relais (le groupe SGID pepsi-token ; voir /var/pepsi/krb5). Un ticket manquant/expiré diffère le message (échec transitoire) plutôt que de le faire rebondir.

TOKEN_FILE

(chemin, requis lorsque AUTH = oauth) Fichier contenant le jeton d’accès OAuth 2.0 courant (débarrassé des espaces), relu à chaque remise. Le mécanisme SASL est choisi à partir de l”EHLO du smarthost (OAUTHBEARER préféré, sinon XOAUTH2). L’étape de relais ne fait que lire ce fichier ; gardez-le à jour avec pepsi-helper-token-refresh(1) (voir les sections [pepsi-helper-token-refresh-*]) ou tout job externe équivalent. Un jeton manquant/expiré/rejeté diffère le message (échec transitoire) plutôt que de le faire rebondir.

HELO_NAME

(chaîne, facultative) Nom annoncé dans EHLO à ce smarthost. Par défaut le SERVER_NAME de l’étape.

DOMAINS

(chaîne) Domaines de destinataires séparés par espaces/virgules acheminés vers ce MTA (insensible à la casse). Requis sauf si CATCH_ALL = yes ; un domaine peut être acheminé par au plus un MTA.

CATCH_ALL

(booléen, facultatif) Si ce MTA reçoit chaque domaine non apparié par une entrée DOMAINS. Par défaut no ; au plus un MTA peut le régler. Un MTA doit lister DOMAINS ou régler CATCH_ALL = yes.

85.2.1.1.24. Les sections [pepsi-helper-token-refresh]

Celles-ci configurent pepsi-helper-token-refresh(1), le service facultatif qui garde à jour les jetons d’accès OAuth des smarthosts AUTH = oauth. L’ensemble de jetons à maintenir est dérivé des sections MTA smarthost : pour chaque [pepsi-stage-relay-to-smarthost-mta-<name>] avec AUTH = oauth, le service cherche une section [pepsi-helper-token-refresh-<name>] correspondante. Le service ne fait pas partie de pepsi.target ; activez-le explicitement.

Comme les sections par cible contiennent les secrets client OAuth, gardez-les dans un fichier lisible seulement par l’utilisateur pepsi-helper-token-refresh et incluez chacune avec la directive @inline-secret@ (qu’un lecteur qui ne peut ouvrir le fichier — l’étape de relais, exécutée en tant que pepsi — saute silencieusement, de sorte que le même pepsi.conf s’analyse pour les deux). Voir pepsi-helper-token-refresh(1) et le chapitre Étendre le pipeline du manuel.

La section de base facultative [pepsi-helper-token-refresh] contient des options non secrètes à l’échelle du service :

STATE_DIR

(chemin, facultatif) Répertoire privé (mode 0700) pour les jetons de rafraîchissement renouvelés par cible. Par défaut /var/pepsi/token-refresh.

Chaque section [pepsi-helper-token-refresh-<name>] (<name> correspondant à un MTA smarthost OAuth) contient :

TOKEN_ENDPOINT

(chaîne, obligatoire) L’URL du point de terminaison de jeton OAuth 2.0 du fournisseur (HTTPS). C’est aussi ainsi que le service distingue une section de secret manquante d’une section illisible : un fichier @inline-secret@ que ce compte ne peut pas ouvrir n’est tout simplement pas là, de sorte qu’un TOKEN_ENDPOINT absent fait sauter cette cible avec un avertissement au lieu de faire échouer le service. Les options restantes ci-dessous sont alors des erreurs, non des sauts.

GRANT

(facultatif) refresh_token (le défaut ; par exemple Google) ou client_credentials (par exemple Microsoft 365 application seule).

CLIENT_ID / CLIENT_SECRET

(chaîne, obligatoire) Les identifiants client OAuth, envoyés dans le corps de la requête.

REFRESH_TOKEN

(chaîne, requise pour GRANT = refresh_token) Le jeton de rafraîchissement à longue durée de vie. Une valeur renouvelée renvoyée par le point de terminaison est persistée sous STATE_DIR et a alors priorité.

SCOPE

(chaîne, requise pour GRANT = client_credentials ; facultative sinon) Le scope demandé.

REFRESH_MARGIN

(durée, facultative) Combien de temps avant l’expiration déclarée d’un jeton le rafraîchir. Par défaut 5 m. Utilise les unités h/m/s uniquement.

85.2.1.1.25. La section [pepsi-payments]

Cette section facultative configure l’intégration de paiement GNU Taler. Lorsqu’elle est absente (ou que MERCHANT_BACKEND_URL n’est pas réglé), pepsi-setup(1) n’effectue aucune vérification marchand et aucun webhook n’est provisionné. La même section est lue à l’exécution par pepsi-stage-anti-spam(1) pour créer des commandes de paiement par message.

MERCHANT_BACKEND_URL = URL

URL de base du backend marchand Taler, incluant facultativement l’instance (…/instances/$ID). pepsi-setup(1) demande GET /config à la racine du backend (tout /instances/$ID final est retiré) pour confirmer que c’est un backend taler-merchant, et GET /private/orders?limit=1 à cette URL pour confirmer le jeton d’accès. Requis pour activer l’intégration.

Ce doit être une URL https://, ou une URL http:// dont l’hôte est l’interface de bouclage (localhost, 127.0.0.0/8, ::1). MERCHANT_ACCESS_TOKEN est attaché à chaque requête comme identifiant porteur : un backend en clair ailleurs — y compris « il n’est que sur le LAN » — remet donc cet identifiant de longue durée à tout ce qui se trouve sur le chemin. Les requêtes sont bornées (10 s pour se connecter, 30 s au total), de sorte qu’un backend qui ne répond pas fasse échouer le message et non l’étape.

MERCHANT_ACCESS_TOKEN = TOKEN

Jeton d’accès pour le backend marchand, sous la forme Taler secret-token:…, envoyé comme un identifiant Authorization: Bearer. Il a besoin des permissions orders-read et webhooks-read/webhooks-write. Requis lorsque MERCHANT_BACKEND_URL est réglé.

Le webhook pepsi-resume provisionné se déclenche sur l’événement pay et fait un POST de {"message_id":"{{order_id}}"} vers https://<host>/resume (l’hôte SNI [pepsi-httpd-cert-*] le plus court), authentifié avec [pepsi-httpd] RESUME_AUTHORIZATION_TOKEN. L”order_id du marchand doit donc être égal au jeton externe du message.

85.2.1.1.26. La section [pepsi-vacation-default-message]

Les avis d’absence par langue sur lesquels pepsi-stage-vacation(1) se rabat, une option par langue

[pepsi-vacation-default-message]
EN = Hello {{SENDER_NAME}},  I am away until {{VACATION_END}}.
DE = Hallo {{SENDER_NAME}},  ich bin bis {{VACATION_END}} abwesend.

Le nom de l’option est l’étiquette de langue (EN, DE, PT_BR — l’un ou l’autre séparateur), et la valeur est un modèle Mustache. Quelle langue est employée, quels champs se développent, et pourquoi deux espaces deviennent un saut de ligne sont tous documentés dans pepsi-stage-vacation(1).

Cette section existe normalement déjà. make install la livre comme ${DATADIR}/config.d/vacation.conf, et le chargeur de configuration de taler analyse chaque fichier de ${DATADIR}/config.d avant pepsi.conf. Une étape configurée sans message à elle dispose donc tout de même de dix langues, et un opérateur qui veut une autre formulation redéfinit dans pepsi.conf la seule langue qui l’intéresse : les définitions ultérieures l’emportent option par option, jamais section par section, de sorte que redéfinir EN laisse les neuf autres en place. Éditer le fichier livré fonctionne aussi, mais une mise à niveau du paquet écrase la modification.

Le nom de la section n’est qu’un défaut (DEFAULT_MESSAGE_SECTION), de sorte qu’un opérateur voulant plusieurs jeux de messages — un formel pour une adresse d’assistance, un laconique pour tout le monde — puisse définir d’autres sections et y pointer différentes étapes, domaines ou adresses.

Un titulaire de compte ne touche jamais à cette section : son propre texte va dans MESSAGE_<LANG> de la section propre à l’étape, que la couche de paramètres peut porter et qui l’emporte langue par langue.

85.2.1.1.27. La section [pepsi-autoconfig]

Cette section facultative publie l”autoconfiguration des comptes de courrier (draft-ietf-mailmaint-autoconfig) : le document XML qu’un client de messagerie récupère, ne connaissant que l’adresse de l’utilisateur, afin de se configurer lui-même au lieu de demander huit paramètres que l’utilisateur ne peut généralement pas fournir. Il est servi par pepsi-httpd(1) à /mail/config-v1.1.xml sur autoconfig.<domain>, et à /.well-known/autoconfig/mail/config-v1.1.xml sur le domaine de courrier lui-même.

La fonctionnalité est désactivée tant qu’aucun serveur entrant n’est nommé. Omettez la section — ou ne réglez ni IMAP_HOST ni POP3_HOST — et les deux points de terminaison répondent 404. Un client qui trouve un document de configuration cesse de parcourir la chaîne de repli, de sorte qu’en publier un incapable de lui dire comment lire le courrier laisse l’utilisateur en plus mauvaise posture que de n’en publier aucun.

Pepsi ne sert pas de boîtes aux lettres (voir pepsi-stage-relay-to-lmtp(1)) : la moitié entrante doit donc nommer le MDA auquel le déploiement est associé, typiquement Dovecot sur le même hôte.

Deux choses extérieures à ce fichier sont également nécessaires. Un enregistrement DNS autoconfig.<domain> doit se résoudre vers ce serveur, et le certificat TLS doit couvrir ce nom — les clients essaient d’abord l’URL https://autoconfig.…, et une erreur de certificat là est une consultation échouée. La moitié « certificat » est prise en charge pour vous lorsque pepsi-setup(1) provisionne les certificats : cette section nommant un serveur entrant, il ajoute autoconfig.<domain>, pour chaque domaine servi, aux noms qu’il demande pour le certificat du [pepsi-httpd-listener-*] TLS. L’enregistrement DNS ne l’est pas, puisqu’il est publié dans votre zone. Un déploiement peu disposé à ajouter le nom peut se reposer sur la seule forme /.well-known/, au prix de n’être trouvé que par les clients qui l’essaient.

IMAP_HOST, POP3_HOST

(nom d’hôte, facultatif) Le serveur de boîtes aux lettres à annoncer. Régler l’un ou l’autre active la fonctionnalité ; n’en régler aucun la désactive. Pas de valeur par défaut — un nom d’hôte inventé serait pire que le silence.

IMAP_PORT, POP3_PORT

(nombre, facultatif) Par défaut 993 et 995, les ports à TLS implicite.

IMAP_SOCKET, POP3_SOCKET

(``SSL`` | ``STARTTLS`` | ``plain``, facultatif) Sécurité du transport, dans le vocabulaire propre au draft (SSL signifie TLS implicite) ; tls et none sont acceptés comme orthographes de SSL et plain. SSL par défaut.

IMAP_AUTH, POP3_AUTH

(facultatif) L’une des valeurs d’authentification du draft : password-cleartext, password-encrypted, NTLM, GSSAPI, TLS-client-cert, OAuth, client-IP-address, none. password-cleartext par défaut — ce qui, sur SSL, est l’arrangement ordinaire du mot de passe sur TLS plutôt que quoi que ce soit envoyé en clair. Une valeur non reconnue est une erreur de démarrage, non une faute de frappe publiée en silence.

SMTP_HOST, SMTP_PORT, SMTP_SOCKET, SMTP_AUTH

(facultatif) Le serveur de soumission à annoncer. Omettez normalement les quatre : ils sont dérivés de la section [pepsi-ingress-listener-*] marquée SUBMISSION = yes — son port, son MODE et son mécanisme d’authentification — de sorte que déplacer la soumission du STARTTLS sur 587 vers le TLS implicite sur 465 mette à jour le document publié tout seul, et que les deux ne puissent pas diverger. Ne les réglez que lorsque le point de terminaison public de soumission n’est pas le listener, par exemple derrière un répartiteur de charge. Régler SMTP_HOST désactive entièrement la dérivation : donnez donc aussi les autres s’ils diffèrent de 587/STARTTLS/password-cleartext.

Un listener de soumission sur socket UNIX ou activé par systemd n’est jamais annoncé : un client distant ne peut pas employer le premier, et le second n’a aucun port dans la configuration à publier.

DISPLAY_NAME, DISPLAY_SHORT_NAME

(texte, facultatif) Ce que le client montre à l’utilisateur. Les deux valent par défaut la première entrée de [pepsi-ingress] ACCEPTED_DOMAINS (le HOSTNAME de l’ingress lorsqu’aucun domaine n’est configuré).

DOCUMENTATION_URL

(URL, facultative) Une page d’aide pour les paramètres du compte, publiée comme élément <documentation> du draft. Omise lorsqu’elle n’est pas définie.

[pepsi-autoconfig]
IMAP_HOST = mail.example.org
POP3_HOST = mail.example.org
DISPLAY_NAME = Example Mail
DISPLAY_SHORT_NAME = Example
# SMTP_* deliberately omitted: derived from the submission listener.

85.2.1.1.28. La section [pepsi-tlsrpt]

Cette section facultative configure le SMTP TLS Reporting (RFC 8460). Elle a deux moitiés indépendantes ; omettez la section pour désactiver les deux. pepsi-setup(1) la lit pour la moitié d’annonce ; la moitié émettrice est lue à l’exécution par les étapes de relais (enregistrement de session) et pepsi-tlsrpt(1) (le job de rapport quotidien).

RUA = URI [, URI …]

Adresse(s) de rapport annoncée(s) dans l’enregistrement TXT _smtp._tls.<domain> que pepsi-setup(1) émet pour chaque domaine, afin que d’autres expéditeurs nous rapportent leurs résultats TLS vers nos domaines. Une URI mailto: ou https:, ou une liste séparée par virgules, stockée verbatim. Lorsqu’elle n’est pas réglée, aucun enregistrement n’est publié.

SEND_REPORTS = yes | no

Si les étapes de relais enregistrent chaque session TLS sortante dans pepsi.tls_session. Facultatif ; par défaut no. C’est l’interrupteur de la seule moitié enregistrement : pepsi-tlsrpt(1) ne le teste pas, il ne trouve simplement aucune session à rapporter lorsque rien ne les enregistre.

REPORT_FROM = ADDRESS

Expéditeur d’enveloppe et From: des e-mails de rapport que pepsi-tlsrpt(1) envoie. Requis pour envoyer des rapports (son domaine est le soumetteur du rapport). Les rapports ne sont pas à expéditeur nul (RFC 8460 §5.3 : ils doivent être alignables DKIM/DMARC) ; la boucle rapport-sur-rapport est empêchée par l’indicateur state.tlsrpt injecté.

REPORT_STAGE = STAGE

Les e-mails de rapport de l’étape de pipeline sont injectés à (de sorte qu’ils soient signés et relayés), comme le BLOCK_RESPONSE_STAGE de pepsi-stage-anti-spam(1). Doit référencer une [stage-*] existante. Requis pour envoyer les rapports par e-mail (mailto:).

ORGANIZATION = NAME

organization-name placé dans les rapports émis. Facultatif ; par défaut le domaine de REPORT_FROM.

CONTACT = ADDRESS

contact-info placé dans les rapports émis. Facultatif.

RETAIN_DAYS = DAYS

Combien de jours pepsi-tlsrpt prune conserve les compteurs pepsi.tls_session. Facultatif ; par défaut 7. pepsi-tlsrpt-prune.timer exécute l’élagage quotidiennement.

85.2.1.1.29. La section [pepsi-telemetry-client]

Cette section facultative configure l’agrégateur local de télémétrie de fonctionnalités, pepsi-telemetry-client(1). Toutes les options ont des valeurs par défaut fonctionnelles ; toute la fonctionnalité est conditionnée par [pepsi] SHARE_TELEMETRY ci-dessus, désactivé à moins que l’opérateur ne l’ait activé — de sorte que rien ici n’ait d’effet tant que ce n’est pas le cas. (Le collecteur central, pepsi-telemetry(1), lit à la place la section séparée [pepsi-telemetry].)

UNIXPATH = PATH

Socket UNIX locale sur laquelle le daemon écoute les événements de fonctionnalités ; le même chemin auquel les programmes producteurs se connectent. Facultatif ; par défaut /run/pepsi-telemetry/socket.

UNIXPATH_GROUP = GROUP

Groupe vers lequel la socket est chgrp-ée (mode UNIXPATH_MODE), afin que les utilisateurs pepsi (workers d’étape) et pepsi-ingress puissent se connecter. Facultatif ; par défaut pepsi-telemetry.

UNIXPATH_MODE = OCTAL

Bits de permission de la socket. Facultatif ; par défaut 660.

SUBMIT_INTERVAL = DURATION

Intervalle entre les soumissions au collecteur (unités h/m/s uniquement — voir la note sur la durée ci-dessus). Facultatif ; par défaut 60 s. Zéro est une erreur de configuration, non une boucle active.

MAX_FEATURES = N

Plafond du nombre de noms de fonctionnalités distincts tenus en mémoire, bornant la mémoire contre un producteur local au comportement défaillant. Facultatif ; par défaut 4096.

85.2.1.1.30. Données stockées

Pour chaque message accepté, pepsi-ingress(1) insère une ligne dans la table pepsi.workqueue contenant un identifiant local (workqueue_id), un token aléatoire, l’horodatage de réception (received_at), l’expéditeur d’enveloppe (mail_from ; la chaîne vide pour l’expéditeur nul <>), la liste des destinataires d’enveloppe (rcpt_to), et les en-têtes from_header et subject analysés. Le message lui-même est stocké scindé en deux — une colonne headers (le bloc d’en-têtes RFC 5322 jusqu’au séparateur de ligne vide non inclus, avec l’en-tête de trace Received: du §4.4 de la RFC 5321 et, au-dessus de lui, l’en-tête Authentication-Results ajoutés en tête ; l’ensemble ARC est ajouté plus tard par pepsi-stage-arc(1)) et un corps (tout ce qui suit la ligne vide ; vide pour un message à en-têtes seuls). L’invariant de reconstruction est raw = headers || CRLF || body. Scinder le message permet aux étapes qui ne touchent que les en-têtes ou l’enveloppe de charger (et réécrire) seulement la colonne headers et de ne jamais tirer le corps (potentiellement volumineux).

Le corps n’est pas une colonne de pepsi.workqueue mais une ligne de sa propre table, pepsi.workqueue_body (body_id, body, et la taille générée octets), que la ligne du message référence par body_id. C’est ce qui évite qu’un message à plusieurs destinataires soit stocké une fois par destinataire : chaque ligne qui en est scindée — paramètres par adresse, une ligne par destinataire d’une étape de relais, diffusion d’une liste de diffusion, bounce ou DSN par destinataire — référence la même ligne de corps, de sorte qu’une contribution de 25 Mio à mille membres représente un corps de 25 Mio et mille petites lignes. Une étape qui réécrit un corps (déchiffrement, pied de page d’une liste) stocke une nouvelle ligne de corps et ne redirige que son propre message (copie sur écriture), de sorte qu’aucune réécriture ne peut atteindre une ligne sœur. Un corps est supprimé par un trigger dès que la dernière ligne qui le référence est supprimée ou redirigée, et pepsi-dispatch(1) balaie l’orphelin rare qu’une course laisse derrière elle (pepsi.workqueue_body_gc()). header_octets est la taille générée correspondante de headers ; les deux colonnes de taille sont ce que somme la vérification d’admission de la file d’attente (MAX_QUEUE_BYTES, pepsi.queue_usage()), lisibles par des rôles qui ne peuvent pas lire le message lui-même. Les verdicts SPF, DKIM et DMARC calculés sont stockés dans le state de la ligne sous une clé auth, et l”authserv_id sous state.origin ; le verdict arc commence à none et est rempli par l’étape ARC. Le dispatcher n’est pas notifié depuis cette transaction : pepsi-ingress(1) regroupe les admissions et émet au plus un réveil par DISPATCH_WAKE_INTERVAL, hors bande et après la validation des lignes, avec une charge utile vide (voir la description de cette option ci-dessus). Un consommateur LISTEN workqueue ne reçoit donc aucune notification par message ni aucune charge utile à analyser.

Chaque ligne porte en outre son état de traitement pour le pipeline d’étapes qui s’exécute après l’ingress : un stage (la section [stage-<stage>] du programme actuellement responsable de faire avancer le message), un status (l’un de pending, running, paused, failed ou timeout), un state (l’objet JSON transporté avec le message, documenté dans pepsi.state(7)), et un timeout (quand un message paused devrait être remis en file). Chaque nouveau message est inséré explicitement à l’étape initiale — stage = init, status = pending — de sorte qu’il entre dans le pipeline à [stage-init]. Ces colonnes sont inspectées et réparées avec pepsi-queue(1).

pepsi.workqueue (avec ses corps dans pepsi.workqueue_body) est la seule file de messages en transit ; le schéma compte une soixantaine de tables en tout. Celle que tout déploiement exerce à côté de la file d’attente est pepsi.dns_address : un cache des adresses A/AAAA résolues pour les hôtes de serveurs de courrier des destinataires, avec la santé de connexion par adresse, maintenu par pepsi-stage-relay-to-internet(1). Chaque ligne consigne un host, une address résolue, l”expires_at du TTL DNS, un indicateur failed et l’heure last_success_at, de sorte qu’une adresse fonctionnelle est préférée jusqu’à expiration de son TTL et qu’un hôte est re-résolu une fois que toutes ses adresses en cache ont échoué ou expiré. Elle ne porte aucune donnée de message et n’est pas gérée par pepsi-queue(1).

Les autres sont les tables de fonctionnalités, chacune décrite avec le composant qui la possède : les compteurs de pipeline stage_stats et dispatch_stats (pepsi-dispatch(1), exportés par pepsi-httpd(1) à /metrics), whitelist (pepsi-whitelist(1)), tls_session (pepsi-tlsrpt(1)), settings (pepsi-settings(1)), vacation_reply (pepsi-stage-vacation(1)), payment_request_reply (pepsi-stage-anti-spam(1)), secretary_challenge et secretary_sent (pepsi-stage-secretary(1)), mailbox_quota (pepsi-quota(1)), config_override (la couche de configuration en base de données, pepsi-config(1)), origin_nonce et auto_pay_spend (pepsi-stage-auto-pay(1)), telemetry (pepsi-telemetry(1)), secure_message et secure_access (pepsi-secure-link(1)), le magasin de clés crypto_identity / peer_key / peer_has_own_key / ca_trust / key_request (pepsi-keys(1) et pepsi-keydisc(1)), les tables de listes de diffusion mailing_list et list_* (pepsi-list(1)), l’archive des listes archive_* (pepsi-archive(1)), les journaux event_log et mail_log, et la surface administrative admin_account / admin_session / api_token / setup_task / setup_task_log (pepsi-httpd(1) et pepsi-setup(1)). Toutes sont créées par pepsi-setup(1). À part secure_message (du texte chiffré attendant son destinataire), l’archive des listes, dont le but est de conserver les contributions, et les messages qu’une liste retient pour modération, aucune ne contient de contenu de message.

La colonne state est l’objet JSON transporté avec le message depuis l’ingress jusqu’à son étape terminale ; c’est le canal par lequel les étapes communiquent. L’ingress la sème avec la provenance d’origine SMTP de la connexion, les verdicts SPF/DKIM/DMARC entrants et tout paramètre DSN RFC 3461 ; les étapes ultérieures y fusionnent leurs propres verdicts et données de travail. Sa disposition complète — chaque clé, qui l’écrit et qui la consomme — est documentée dans pepsi.state(7).

85.2.1.1.31. Exemple

Un redirecteur complet : recevoir sur les trois ports SMTP canoniques, sceller en ARC à l’arrivée, réécrire en SRS, remettre en direct vers le MX, et faire rebondir les échecs (en signant le rebond avant la remise)

[pepsi]
KEY_DIR = /var/pepsi/keys
DKIM_SELECTOR = pepsi
ARC_DOMAIN = example.org
ARC_ALGORITHM = rsa

[pepsi-postgres]
CONFIG = postgres:///pepsi
# SQL_DIR defaults to ${DATADIR}/sql; set it when running from a checkout.

[pepsi-ingress]
HOSTNAME = mail.example.org
ACCEPTED_DOMAINS = example.org example.com
MAX_MESSAGE_SIZE = 26214400

# The three canonical SMTP listeners. TLS_CERT/TLS_KEY are omitted so
# pepsi-setup auto-fills the certbot path and obtains the certificate.

# Port 25: cleartext with opportunistic STARTTLS.
[pepsi-ingress-listener-mx]
SERVE = tcp
BIND_TO = 0.0.0.0
PORT = 25
MODE = starttls
MYNETWORKS = 127.0.0.0/8 ::1/128 10.0.0.0/8

# Port 465: implicit TLS (SMTPS), authenticated submission via Dovecot SASL.
[pepsi-ingress-listener-submissions]
SERVE = tcp
BIND_TO = 0.0.0.0
PORT = 465
MODE = tls
SUBMISSION = yes
SASL_TYPE = dovecot
SASL_PATH = /run/dovecot/auth-client-pepsi

# Port 587: cleartext submission upgraded with STARTTLS.
[pepsi-ingress-listener-submission]
SERVE = tcp
BIND_TO = 0.0.0.0
PORT = 587
MODE = starttls
SUBMISSION = yes
SASL_TYPE = dovecot
SASL_PATH = /run/dovecot/auth-client-pepsi

[pepsi-srs]
SRS_DOMAIN = srs.example.org
SECRET_FILE = /etc/pepsi/srs.secret

# init: ARC-seal the message as received, then hand to SRS.
[stage-init]
PROGRAM = pepsi-stage-arc
NEXT_STAGE = srs

[stage-srs]
PROGRAM = pepsi-stage-srs
NEXT_STAGE = deliver

# deliver: direct-to-MX; failures go to the bounce stage.
[stage-deliver]
PROGRAM = pepsi-stage-relay-to-internet
SERVER_NAME = mail.example.org
POSTMASTER = postmaster@example.org
BOUNCE_STAGE = bounce
# This host's public sending IP(s); pepsi-setup unions PUBLIC_IP from every
# relay stage into the SPF record.
PUBLIC_IP = 203.0.113.7 2001:db8::25

# bounce: build an unsigned DSN, sign it, then deliver it.
[stage-bounce]
PROGRAM = pepsi-stage-bounce
SERVER_NAME = mail.example.org
POSTMASTER = postmaster@example.org
NEXT_STAGE = bounce-sign
BOUNCE_MESSAGE = default

[stage-bounce-sign]
PROGRAM = pepsi-stage-dkim-sign
NEXT_STAGE = deliver

Pour relayer via un smarthost à la place, remplacez le PROGRAM de l’étape deliver par pepsi-stage-relay-to-smarthost et ajoutez des sections [pepsi-stage-relay-to-smarthost-mta-*], par exemple

[pepsi-stage-relay-to-smarthost-mta-smarthost]
HOST = smtp.relay.example.net
PORT = 587
CATCH_ALL = yes

85.2.1.1.32. Fichiers

Chaque composant Pepsi lit le même fichier. Lorsqu’un composant est démarré sans –config, le premier chemin existant de la liste suivante est utilisé :

  • $XDG_CONFIG_HOME/pepsi.conf

  • $HOME/.config/pepsi.conf

  • /etc/pepsi/pepsi.conf

  • /etc/pepsi.conf

pepsi-setup --wizard écrit /etc/pepsi/pepsi.conf ; make install place à côté un pepsi.conf.sample de référence, qui documente chaque option mais n’est pas lui-même une configuration fonctionnelle.

Avant que ce fichier ne soit lu, chaque *.conf de ${DATADIR}/config.d est analysé, de sorte que les valeurs par défaut empaquetées soient en place et que pepsi.conf les redéfinisse option par option (une section définie dans les deux est fusionnée, non remplacée). Deux sont livrés :

  • vacation.conf — les avis d’absence par langue ; voir La section [pepsi-vacation-default-message] ci-dessus.

  • thunderbird.conf — [pepsi] CRYPTO_ALLOW_DOWNGRADE = yes, de sorte que le S/MIME parte en EnvelopedData AES-256-CBC, que Thunderbird sait lire, alors qu’il ne sait pas lire notre valeur par défaut compilée AES-256-GCM. Le fichier s’explique longuement lui-même et est conçu pour être supprimable : le retirer rétablit le chiffrement authentifié sans aucune autre modification.

Ces fichiers appartiennent au paquet : redéfinissez dans pepsi.conf les options que vous voulez plutôt que de les éditer, sinon une mise à niveau écartera la modification.

85.2.1.1.33. Voir aussi

pepsi-ingress(1), pepsi-dispatch(1), pepsi-httpd(1), pepsi-setup(1), pepsi-config(1), pepsi-queue(1), pepsi-status(1), pepsi-sendmail(1), pepsi-whitelist(1), pepsi-settings(1), pepsi-tlsrpt(1), pepsi-quota(1), pepsi-failure-bouncer(1), pepsi-list(1), pepsi-keys(1), pepsi-keydisc(1), pepsi-secure-link(1), pepsi-detect-language(1), pepsi-telemetry(1), pepsi-telemetry-client(1), pepsi-helper-token-refresh(1), pepsi-helper-auto-pay(1), pepsi-helper-mailbox-scan(1), pepsi-stage-arc(1), pepsi-stage-srs(1), pepsi-stage-encrypt(1), pepsi-stage-decrypt(1), pepsi-stage-autocrypt-learn(1), pepsi-stage-secure-link(1), pepsi-stage-vks-confirm(1), pepsi-stage-route(1), pepsi-stage-dkim-sign(1), pepsi-stage-relay-to-internet(1), pepsi-stage-relay-to-smarthost(1), pepsi-stage-relay-to-lmtp(1), pepsi-stage-relay-to-maildir(1), pepsi-stage-dot-forward(1), pepsi-stage-bounce(1), pepsi-stage-discard(1), pepsi-stage-anti-spam(1), pepsi-stage-auto-pay(1), pepsi-stage-check-whitelist(1), pepsi-stage-auto-whitelist(1), pepsi-stage-detect-language(1), pepsi-stage-block-language(1), pepsi-stage-if(1), pepsi-stage-milter(1), pepsi-stage-aliases(1), pepsi-stage-vacation(1), pepsi-stage-edit-settings(1), pepsi-archive(1), pepsi-stage-list(1), pepsi-stage-list-post(1), pepsi-stage-list-deliver(1), pepsi-stage-list-command(1), pepsi-stage-list-bounce(1), pepsi.state(7), systemd.socket(5)

85.2.1.1.34. Bogues

Signalez les bogues au gestionnaire de tickets de Pepsi.