2. Démarrage sur un VPS bon marché

Une présentation de bout en bout : en partant d’un serveur privé virtuel fraîchement loué et d’un nom de domaine que vous venez d’enregistrer, elle vous mène jusqu’à un premier e-mail reçu et remis dans une boîte aux lettres locale, avec un véritable rebond renvoyé pour tout ce qui ne peut être remis. Les autres chapitres expliquent chaque pièce en profondeur ; celui-ci les enchaîne.

2.1. Ce que nous allons construire

Un petit hôte de courrier qui accepte le courrier pour example.org sur le port SMTP standard et remet chaque message dans le Maildir local du destinataire sur le même serveur. Tout ce qu’il ne peut remettre localement — un destinataire inconnu, une boîte aux lettres pleine ou non inscriptible — est transformé en un véritable rebond (une notification d’état de remise) et renvoyé à l’expéditeur d’origine, plutôt que de disparaître silencieusement dans la file d’attente. Le pipeline entrant est court

inbound SMTP  ->  [stage-init]  ->  [stage-local]
(pepsi-ingress)   pepsi-stage-arc   pepsi-stage-relay-to-maildir
                  (record the       (deliver to the user's
                   inbound verdict)  ~/Maildir/new/)

et tout ce qu’il ne peut remettre est signé et renvoyé par courrier à l’expéditeur via un court chemin sortant

[stage-bounce]      ->  [stage-sign]       ->  [stage-internet]
pepsi-stage-bounce      pepsi-stage-dkim-sign   pepsi-stage-relay-to-internet
(build the DSN)         (sign the bounce)       (send it to the sender's MX)

Remplacez example.org par votre propre domaine et alice par un vrai nom de compte partout. Comme l’hôte envoie désormais aussi ce rebond — signé en DKIM, depuis une adresse autorisée par SPF — cette configuration publie les enregistrements d’authentification d’expéditeur qui permettent aux destinataires de faire confiance à son courrier sortant : DKIM, SPF et DMARC, dont un hôte en réception seule n’aurait pas besoin. (MTA-STS et le TLS reporting, qui durcissent le TLS entrant et nécessitent le serveur HTTPS en service, sont laissés de côté ici et ajoutés en durcissement facultatif — voir Étapes suivantes.) Une dernière section réutilise exactement le même chemin sortant pour ajouter un port de soumission authentifié afin que vos propres utilisateurs puissent envoyer à travers l’hôte également.

Note

Périmètre. C’est le déploiement réaliste le plus simple — recevoir du courrier, le remettre localement et faire rebondir ce qu’il ne peut pas remettre. Pour un hôte de redirection (ARC + SRS + re-signature DKIM au retour), voir Introduction et pepsi-stage-relay-to-internet, et Étapes suivantes pour savoir comment faire grandir cet hôte jusque-là.

Pepsi remet dans un Maildir mais ne livre aucun serveur IMAP/POP, de sorte qu’une fois le courrier arrivé, vous le lisez sur la machine elle-même (mutt, mail) jusqu’à ce que vous ajoutiez un serveur de boîtes aux lettres tel que Dovecot. Voir Étapes suivantes.

2.2. Prérequis

  • Un VPS avec une adresse IPv4 publique et statique (et idéalement une adresse IPv6) et un accès root. Nous utilisons 203.0.113.7 / 2001:db8::25 comme valeurs fictives.

  • Un domaine enregistré dont vous pouvez éditer le DNS (example.org).

  • Le port TCP 25 doit atteindre le VPS dans les deux sens. Le port 25 entrant porte le courrier que vous recevez ; le port 25 sortant permet à l’hôte de renvoyer les rebonds aux expéditeurs. De nombreux fournisseurs bon marché bloquent le 25 sortant par défaut — si le courrier entrant n’arrive jamais, ou si les rebonds ne quittent jamais la file d’attente, c’est la cause habituelle ; demandez au fournisseur de l’ouvrir. (Si le 25 sortant ne peut être débloqué, envoyez plutôt les rebonds via un smarthost — voir pepsi-stage-relay-to-smarthost.)

  • DNS inverse (PTR). Réglez l’enregistrement PTR du VPS sur mail.example.org — cela se fait dans le panneau de contrôle du fournisseur de VPS, pas dans la zone de votre domaine. Il doit nommer le même hôte que celui que vous annoncez dans l”EHLO : beaucoup de destinataires comparent les deux et refusent la session lorsqu’ils diffèrent (HELO host does not match rDNS), ce sur quoi il est facile de trébucher sur une machine qui répond à plusieurs noms. pepsi-setup run avertit pour chaque adresse d’émission dont le PTR est manquant, non confirmé ou nomme un hôte différent, et pepsi-setup --wizard propose le nom du PTR comme nom d’hôte pour exactement cette raison.

  • Les prérequis de build de Installation : une chaîne d’outils Rust, PostgreSQL et (pour le TLS automatique) certbot. Installez-les avec le gestionnaire de paquets de votre plateforme.

2.3. Étape 1 — Déléguer le DNS et placer les enregistrements de base

Pepsi ne contient aucun serveur DNS ; vous publiez les enregistrements là où la zone de votre domaine fait autorité. Vous avez deux choix, et « délégation » signifie des choses différentes pour chacun :

  • Héberger la zone chez un fournisseur DNS (votre registraire, ou un service tel qu’un hôte DNS géré). Ici, le registraire délègue déjà example.org aux serveurs de noms de ce fournisseur ; vous n’ajoutez que des enregistrements dans leur panneau. C’est le chemin le plus simple.

  • Exécuter votre propre serveur de noms faisant autorité (BIND, NSD, Knot, …) sur le VPS ou ailleurs. Alors, chez le registraire, vous réglez les enregistrements NS de example.org sur vos serveurs de noms et, si un serveur de noms est lui-même à l’intérieur de example.org, ajoutez les enregistrements glue A/AAAA correspondants chez le registraire afin que la délégation puisse être résolue

    ; at the registrar (delegation + glue)
    example.org.        NS    ns1.example.org.
    ns1.example.org.    A     203.0.113.7
    

Dans les deux cas, une fois la zone sous votre contrôle, ajoutez les deux enregistrements dont l’hôte de courrier a immédiatement besoin

; the mail host's address
mail.example.org.   A     203.0.113.7
mail.example.org.   AAAA  2001:db8::25

; mail for the domain goes to that host
example.org.        MX    10 mail.example.org.

Note

Les enregistrements restants — SPF, DKIM et DMARC — sont ajoutés à l”Étape 6 — Publier les enregistrements restants et vérifier après que pepsi-setup a généré la clé DKIM et imprimé le texte exact à publier. (Les enregistrements MTA-STS et TLS-reporting ne sont ajoutés que si vous activez ces fonctionnalités facultatives — voir Étapes suivantes.) Ajoutez toutefois l’enregistrement A/AAAA maintenant : le certificat TLS automatique à l’étape 5 exige que mail.example.org se résolve déjà vers ce VPS.

2.4. Étape 2 — Installer Pepsi

Cette présentation construit et installe depuis une copie de travail des sources, afin que chaque étape soit visible. Sur Debian et dérivées, vous pouvez à la place installer le .deb, dont le postinst fait les étapes 2 et 3 pour vous — voir l’onglet Paquet Debian de Installation et le chapitre Paquets Debian ; le reste de ce chapitre s’applique inchangé.

Récupérez d’abord le sous-module intégré (vendored), puis installez les binaires, le SQL et l’exemple de configuration en une seule étape

git submodule update --init --recursive
make install PREFIX=/usr SYSCONFDIR=/etc

Cela installe les binaires pepsi-*, les migrations SQL et un exemple /etc/pepsi/pepsi.conf. Voir Installation pour ce que fait chaque étape (et Cycle de vie du schéma de base de données pour la manière dont le schéma de base de données évolue) ; exécutez make install en tant que root afin que le helper de remise locale puisse être installé avec ses privilèges (étape suivante).

2.5. Étape 3 — Préparer le système

La remise locale écrit dans les répertoires personnels d’autres utilisateurs ; Pepsi sépare donc les privilèges avec des utilisateurs de service dédiés et un helper setuid à portée étroite. Les noms de comptes ne sont pas une convention — ils sont compilés dans le code : créez-les donc exactement tels qu’ils sont écrits (utilisez les outils d’utilisateur/groupe de votre plateforme) :

  • pepsi — l”utilisateur de service sous lequel s’exécutent le dispatcher et chaque worker d’étape ;

  • pepsi-ingress — le compte propre du serveur SMTP (il refuse de démarrer en tant que root lorsque ce compte n’existe pas) ;

  • pepsi-owner — le compte d’amorçage auquel pepsi-setup s’abaisse lorsqu’il est exécuté en tant que root, et le propriétaire du schéma de base de données ;

  • un groupe pepsi-maildir qui garde le helper de remise.

Installation liste l’ensemble complet (y compris les comptes pour la console web, le magasin de clés et les autres helpers privilégiés) ; les quatre ci-dessus sont ceux qu’utilise cette présentation.

Le chemin de remise a deux bits de privilège, que make install règle automatiquement lorsqu’il est exécuté en tant que root et que le groupe pepsi-maildir existe déjà ; sinon, réglez-les à la main :

  • pepsi-helper-maildir-writer(1) doit être setuid-root et restreint au groupe (chown root:pepsi-maildir … ; chmod 4750 …), et

  • pepsi-stage-relay-to-maildir doit être setgid pepsi-maildir et appartenir à pepsi (chown pepsi:pepsi-maildir … ; chmod 2550 …), ce qui est ce qui permet au worker pepsi non privilégié d’exécuter le helper et à rien d’autre de le faire.

Voir ces deux chapitres pour la justification.

Créez la base de données. Pepsi se connecte via la socket locale en tant qu’utilisateur système qui se connecte (authentification peer), donc chacun de ces comptes a besoin de son propre rôle de connexion — le serveur se connecte en tant que pepsi-ingress, les étapes en tant que pepsi, et pepsi-setup installe et possède le schéma en tant que pepsi-owner. Créez l’ensemble complet des rôles, et pas seulement les trois sous lesquels s’exécute ce parcours : pepsi-setup run accorde des droits à chacun d’eux, et comme il effectue son travail en base de données en tant que pepsi-owner, qui ne peut pas créer de rôles, un rôle manquant l’arrête avec permission denied to create role. En tant que superutilisateur postgres, avec une base de données correspondant à CONFIG = postgres:///pepsi ci-dessous

for r in pepsi-owner pepsi pepsi-ingress pepsi-httpd pepsi-whitelist \
         pepsi-config pepsi-crypto pepsi-keydisc pepsi-telemetry; do
    createuser "$r"        # createuser takes one role name at a time
done
createdb -O pepsi-owner pepsi

Enfin, créez au moins un compte de boîte aux lettres locale pour recevoir le courrier

useradd --create-home alice

2.6. Étape 4 — Écrire la configuration

Tous les composants lisent un seul fichier, /etc/pepsi/pepsi.conf. L’exemple installé à l’étape 2 est un redirecteur complet ; pour cette présentation, vous voulez plutôt la configuration minimale de remise locale plus rebond. Il y a deux façons équivalentes de la produire — laisser pepsi-setup la générer à partir de quelques réponses, ou l’écrire à la main — et elles construisent le même pipeline. (Le format et chaque option sont décrits dans Configuration et pepsi.conf(5).)

pepsi-setup --wizard mène un court questionnaire, écrit un /etc/pepsi/pepsi.conf complet et déjà validé, puis propose d’exécuter le provisionnement de l’étape 5 pour vous. Démarrez-le

pepsi-setup --wizard

Répondez aux invites comme suit. Appuyez sur Entrée pour accepter un [default] ; les invites non listées ici peuvent toutes garder leurs valeurs par défaut (elles sont à no pour cet hôte minimal) :

  • Sens du courrier desservi par cet hôte — inbound

  • Nom d’hôte du serveur de courrier (nom MX / EHLO) — mail.example.org. La valeur par défaut proposée ici est le nom vers lequel l’adresse publique de cet hôte se résout en inverse ; si ce n’est pas mail.example.org, corrigez l’enregistrement PTR avant d’aller plus loin plutôt que de le remplacer ici.

  • Domaine(s) pour lesquels nous acceptons le courrier — example.org

  • Adresse postmaster — acceptez la valeur par défaut (postmaster@example.org)

  • Adresse(s) IP publique(s) d’envoi pour SPF — 203.0.113.7 2001:db8::25

  • Chaîne de connexion PostgreSQL — acceptez la valeur par défaut (postgres:///pepsi)

  • Remettre le courrier des comptes système locaux dans leur Maildir — yes

  • Relayer aussi vers un smarthost les destinataires que la remise locale ne prend pas en charge — no

  • Servir une politique MTA-STS via HTTPS — no (durcissement facultatif, ajouté plus tard ; voir Étapes suivantes)

  • Envoyer et annoncer les rapports SMTP TLS (TLSRPT) — no

L’assistant valide le résultat, écrit le fichier et demande s’il faut exécuter la configuration initiale complète maintenant : répondez yes pour plier l’étape 5 dans cette étape, ou no pour exécuter pepsi-setup run vous-même ensuite. Vos réponses sont enregistrées dans une section [pepsi-wizard], de sorte que relancer l’assistant les pré-remplit.

Le fichier qu’il écrit construit le même chemin entrant que celui rédigé à la main dans l’autre onglet — ARC, puis la remise Maildir, avec la queue bounce/signature/internet derrière — ainsi que quelques valeurs par défaut raisonnables en production (DANE = warn, durées de vie des messages). Il en diffère sur un point délibéré. La configuration rédigée à la main envoie le NEXT_STAGE de [stage-local] vers le chemin de rebond, si bien que tout ce que la remise locale ne peut pas consommer rebondit ; l’assistant pointe au contraire UNKNOWN_MAILBOX_STAGE vers le rebond (un utilisateur inconnu de l’un de nos propres domaines) et donne à l’étape une queue SRS + relais inconditionnelle (srs → dkim-sign-relay → internet) pour les destinataires qui ne sont pas une erreur — un alias qui se développe hors site, un ~/.forward chez un autre fournisseur. Il remet également vers n’importe quel compte de connexion ordinaire ; ajoutez TARGETS = alice à [stage-local] pour restreindre la remise à des comptes nommés.

Le même questionnaire sans terminal. pepsi-setup questions l’imprime en JSON — l’identifiant, la forme, la valeur par défaut et le texte d’aide de chaque question — et pepsi-setup --wizard --answers answers.json y répond à partir d’un fichier de ces identifiants. C’est le questionnaire interactif avec les réponses fournies, non une seconde implémentation, de sorte que les branches et la validation par champ sont celles ci-dessus. C’est aussi le modèle que rend la configuration initiale dans le navigateur ; voir la section « Configurer dans un navigateur » de Installation.

Remplacez /etc/pepsi/pepsi.conf par ce qui suit

[pepsi]
# Where pepsi-setup writes the generated DKIM/ARC keys.
KEY_DIR = /var/pepsi/keys
DKIM_SELECTOR = pepsi
# Identity that signs the ARC seal recording the inbound verdict.
ARC_DOMAIN = example.org
# This minimal host does not serve an MTA-STS policy (that needs the
# HTTPS server), so do not advertise one. See "Next steps" to add it.
MTA_STS_MODE = none

[pepsi-postgres]
CONFIG = postgres:///pepsi

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

# The MX listener on port 25. MODE = starttls with no TLS_CERT/TLS_KEY
# lets pepsi-setup fill in the certbot certificate paths (Step 5).
[pepsi-ingress-listener-mx]
SERVE = tcp
BIND_TO = 0.0.0.0
PORT = 25
MODE = starttls

# New messages enter here. ARC-seal the SPF/DKIM/DMARC verdict Pepsi
# computed at the boundary, then hand the message to local delivery.
[stage-init]
PROGRAM = pepsi-stage-arc
NEXT_STAGE = local

# Deliver to a local user's Maildir. By default any regular login account
# (the /etc/login.defs UID range) may receive mail, so 'alice' is already
# covered; set TARGETS to restrict delivery to an allow-list (e.g.
# TARGETS = alice). Anything not deliverable here is sent to the bounce
# path: an unknown recipient via NEXT_STAGE, a mailbox that fails to
# accept it via BOUNCE_STAGE.
[stage-local]
PROGRAM = pepsi-stage-relay-to-maildir
SERVER_NAME = mail.example.org
NEXT_STAGE = bounce
BOUNCE_STAGE = bounce

# --- Outbound bounce path: turn an undeliverable message into a DSN and
# mail it back to the original sender. Three short stages: build, sign,
# send.

# Rewrite the message in place into an (unsigned) RFC 3464 bounce
# addressed to the original sender, then hand it to the signer.
[stage-bounce]
PROGRAM = pepsi-stage-bounce
SERVER_NAME = mail.example.org
NEXT_STAGE = sign

# DKIM-sign the bounce so it authenticates at the sender's server.
[stage-sign]
PROGRAM = pepsi-stage-dkim-sign
NEXT_STAGE = internet

# Deliver the signed bounce directly to the sender's mail exchanger.
[stage-internet]
PROGRAM = pepsi-stage-relay-to-internet
SERVER_NAME = mail.example.org
# Read by pepsi-setup to build the SPF record authorising this host to
# send (the bounces above, and any outbound mail you add later).
# PUBLIC_IP is a per-STAGE option: pepsi-setup finds it by walking the
# [stage-*] sections and keeping the relays, never by a section named
# after the program -- with no relay stage setting it the record is a
# bare "v=spf1 -all", which makes our own mail fail SPF.
PUBLIC_IP = 203.0.113.7 2001:db8::25

Un message destiné à un destinataire qui n’est pas une boîte aux lettres locale autorisée est transformé en rebond et renvoyé par courrier à l’expéditeur, plutôt que d’échouer silencieusement : un destinataire @example.org inconnu emprunte le NEXT_STAGE de [stage-local] vers le chemin de rebond, et une boîte aux lettres connue qui ne peut être écrite (disque plein, permissions) est réessayée puis fait l’objet d’un rebond via BOUNCE_STAGE. Les deux pointent vers le même [stage-bounce].

Notez que NEXT_STAGE va ici vers l’étape de rebond, et non vers [stage-internet]. Cet hôte ne dessert que des boîtes aux lettres locales : tout destinataire qu’il ne peut pas remettre est donc un utilisateur inconnu de notre propre domaine, et relayer ceux-là plus loin consulterait le MX d”example.org, trouverait ce même hôte et nous renverrait le courrier directement — une boucle. Transformer cet hôte en un véritable redirecteur — où un alias peut légitimement s’étendre vers une adresse ailleurs — est une étape distincte (Étapes suivantes) ; là, NEXT_STAGE atteint bien un relais, et UNKNOWN_MAILBOX_STAGE maintient les utilisateurs locaux inconnus sur le chemin de rebond (voir pepsi-stage-relay-to-maildir).

2.7. Étape 5 — Provisionner le schéma, les clés et le certificat

Si vous avez utilisé l’assistant à l’étape 4 et répondu yes à « exécuter la configuration initiale maintenant », c’est déjà fait — relancez la commande ci-dessous à tout moment pour capturer à nouveau les enregistrements DNS (c’est idempotent). Sinon, exécutez l’outil d’amorçage une fois, en capturant les enregistrements DNS qu’il imprime

pepsi-setup -c /etc/pepsi/pepsi.conf run > pepsi-dns.zone

Cela valide la configuration, installe le schéma pepsi, génère les clés DKIM/ARC par domaine sous KEY_DIR, obtient le certificat TLS pour mail.example.org via certbot (cela nécessite que l’enregistrement A de l’étape 1 soit en service et que le port 80 entrant soit joignable), et imprime les enregistrements DNS restants dans pepsi-dns.zone. C’est idempotent et sûr à relancer.

Si vous préférez gérer le certificat vous-même, passez --no-certbot et réglez TLS_CERT/TLS_KEY dans la section du listener. Le flux de provisionnement complet est dans pepsi-setup et Installation.

2.8. Étape 6 — Publier les enregistrements restants et vérifier

Ouvrez pepsi-dns.zone et publiez les enregistrements qu’il liste dans votre zone :

  • la clé publique DKIM (pepsi._domainkey.example.org TXT),

  • la politique SPF listant les adresses d’envoi de cet hôte, et

  • une politique DMARC (_dmarc.example.org TXT).

(Seuls ceux-ci sont imprimés pour l’hôte minimal ; un enregistrement MTA-STS ou TLS-reporting apparaît ici aussi une fois que vous activez ces fonctionnalités — voir Étapes suivantes.)

La politique DMARC suggérée est v=DMARC1; p=none, qui demande aux destinataires de signaler le courrier échouant à l’authentification sans agir dessus. Commencez par là, mais n’y restez pas : ajoutez rua=mailto:<address> afin que les rapports agrégés vous parviennent, et une fois qu’ils montrent votre propre courrier en réussite, resserrez p= en quarantine puis reject. Publiez-la à la main, avec soin — un enregistrement DMARC qui ne s’analyse pas est écarté en silence, et un domaine dont la politique est à un ; manquant d’être valide paraît protégé sans l’être. C’est précisément à cela que sert le check ci-dessous.

Deux blocs supplémentaires apparaissent dès que cet hôte fait de la cryptographie de bout en bout, et tous deux visent à permettre aux correspondants de trouver les clés de vos utilisateurs (Gestion des clés) :

  • un enregistrement A/AAAA openpgpkey.example.org pointant vers cet hôte, requis par la méthode advanced du Web Key Directory — celle que tout client actuel essaie en premier. pepsi-setup demande aussi à certbot de couvrir ce nom : publiez donc l’enregistrement avant la prochaine délivrance de certificat. La méthode direct sur l’apex fonctionne sans lui, un enregistrement manquant est donc une dégradation plutôt qu’une panne ;

  • un enregistrement OPENPGPKEY (RFC 7929) ou SMIMEA (RFC 8162) par identité publiée. Ne publiez ceux-ci que si votre zone est signée par DNSSEC : un enregistrement de clé non signé est une clé fournie par quiconque peut répondre pour la zone, ce qui n’améliore en rien l’absence de clé. Le Web Key Directory n’a pas besoin de DNSSEC, car HTTPS authentifie le domaine lui-même.

Une fois le DNS propagé, vérifiez ce qui est en service par rapport à ce que Pepsi attend

pepsi-setup -c /etc/pepsi/pepsi.conf check

Ceci est informatif (il sort toujours avec 0) ; il signale un enregistrement DKIM ou SPF manquant ou discordant (et MTA-STS, une fois activé) afin que vous puissiez corriger la zone avant de vous y fier. Il valide aussi strictement l’enregistrement DMARC et signale comme [INVALID] celui que les destinataires ignoreraient, en nommant l’étiquette fautive — la seule défaillance de cette liste qui ne produit aucun rebond, aucune ligne de journal et aucune plainte de quiconque.

2.9. Étape 7 — Démarrer les services

Deux processus de longue durée s’exécutent en continu, chacun sous son propre compte :

  • pepsi-ingress serve — le serveur SMTP entrant, qui s’abaisse à l’utilisateur pepsi-ingress, et

  • pepsi-dispatch serve — le coordinateur d’étapes (exactement un par hôte), qui s’exécute en tant que pepsi et démarre chaque worker d’étape sous cet utilisateur.

Exécutez chacun sous le gestionnaire de service/processus de votre plateforme afin qu’ils démarrent au démarrage de la machine et redémarrent en cas d’échec. Les programmes d’étape eux-mêmes sont lancés par le dispatcher ; vous ne les démarrez jamais à la main. Lier le port 25 nécessite un privilège : démarrez pepsi-ingress en tant que root — il lie ses écouteurs puis passe au compte pepsi-ingress avant de servir une connexion — ou utilisez l’activation par socket. N’accordez pas plutôt une capacité de fichier : dans la disposition de publication, pepsi-ingress est un lien symbolique vers l’unique binaire multi-appel, de sorte que la capacité s’appliquerait à chaque programme regroupé. Voir Installation et pepsi-ingress.

2.10. Étape 8 — Envoyer le premier e-mail

Depuis un compte chez un autre fournisseur, envoyez un message à alice@example.org (ou utilisez un outil tel que swaks --to alice@example.org --server mail.example.org). Regardez-le avancer dans le pipeline

pepsi-status -c /etc/pepsi/pepsi.conf

Un message remis est retiré de la file d’attente, de sorte qu’une exécution saine montre un arriéré vide et un compteur de remise incrémenté. Confirmez que le courrier est réellement arrivé

ls /home/alice/Maildir/new/
mutt -f /home/alice/Maildir          # or: mail

Si le fichier est là, vous avez reçu votre premier e-mail.

2.11. Étape 9 — Ouvrir la console (facultatif)

Tout ce qui précède est également visible dans un navigateur. Ajoutez un listener administratif lié à la boucle locale

[pepsi-httpd-listener-admin]
SERVE = tcp
BIND_TO = 127.0.0.1
PORT = 8443
MODE = plain
ADMIN = yes

et un compte pour s’y connecter — sur la socket locale, un membre du groupe pepsi-admin n’en a pas besoin, mais un navigateur ne peut pas ouvrir une socket UNIX : créez-en donc un et atteignez le listener par un tunnel SSH

ssh -L 8443:127.0.0.1:8443 root@mail.example.org

Ouvrez ensuite http://127.0.0.1:8443/ui. Le tableau de bord montre la même file que celle qu’a imprimée pepsi-status, les pages de configuration montrent d’où vient chaque valeur, et le journal d’audit consigne chaque modification faite depuis n’importe quelle surface. Voir La console d’administration pour la référence des pages et L’API d’administration pour l’API dont elle est cliente. La console n’exerce aucun contrôle de service : redémarrer un composant reste l’affaire de systemctl.

2.12. Envoyer du courrier aussi : ajouter un port de soumission

Jusqu’ici, l’hôte ne fait que recevoir. Pour permettre à vos propres utilisateurs d”envoyer du courrier à travers lui depuis un client de messagerie (Thunderbird, Evolution, KMail, ou K-9 Mail sur un téléphone), ajoutez un listener de soumission authentifié et un chemin de remise sortant. Un client s’authentifie avec un nom d’utilisateur et un mot de passe ; pepsi-ingress enregistre alors le message avec state.local_origin = true, ce qui à la fois lui permet de relayer vers n’importe quel domaine (pas seulement example.org) et permet au pipeline de le distinguer du courrier entrant.

Ouvrez les ports TCP entrants 465 et/ou 587 sur le pare-feu du VPS, de la même manière que vous avez ouvert le port 25.

2.12.1. Séparer l’entrant et le sortant

Vous avez déjà construit un chemin de remise sortant pour les rebonds — [stage-sign] → [stage-internet], avec l’enregistrement SPF couvrant cet hôte. Les soumissions authentifiées réutilisent exactement ce chemin ; vous n’avez qu’à les y router.

Le courrier sortant doit emprunter un chemin différent du courrier entrant, et se tromper ici provoque une boucle de courrier : si vous pointiez simplement [stage-init] vers [stage-sign], le courrier entrant serait signé et relayé à nouveau vers l’extérieur au lieu d’être remis localement. À la place, branchez sur state.local_origin au point d’entrée avec une étape pepsi-stage-if — le courrier d’origine locale (authentifié) va vers le chemin sortant, tout le reste vers le chemin entrant. La scission doit venir avant pepsi-stage-arc : ARC préserve l’authentification d’un expéditeur en amont à travers votre saut de redirection, elle n’a donc aucun sens pour — et ne doit jamais toucher — le courrier que vos propres utilisateurs émettent (ce courrier est authentifié par [stage-sign] à la place ; le sceller avec ARC ne ferait que publier le propre fail SPF de la soumission). Faites donc du routeur l’étape d’entrée [stage-init] et déplacez ARC sur la branche entrante

# Entry: split by direction FIRST. Authenticated submissions (local_origin =
# true) are outbound and reuse the signing path; everything else is inbound and
# goes through ARC. This only moves the stage; it never changes the message.
[stage-init]
PROGRAM = pepsi-stage-if
STATE_PATH = local_origin
VALUE = true
TRUE_STAGE = sign       # outbound: our users' mail (reuses the bounce path)
FALSE_STAGE = arc       # inbound: ARC-seal, then deliver locally

# ARC now sits on the inbound branch (received mail only), feeding local
# delivery just as [stage-init] used to.
[stage-arc]
PROGRAM = pepsi-stage-arc
NEXT_STAGE = local

[stage-sign], [stage-internet] et la ligne PUBLIC_IP sont déjà dans votre configuration depuis le chemin de rebond, de sorte que les soumissions les partagent inchangés. [stage-arc] est l’ancien corps de [stage-init] (inchangé mais renommé), et [stage-local] est aussi inchangé — ses NEXT_STAGE/BOUNCE_STAGE font toujours rebondir le courrier destiné à des utilisateurs locaux inconnus plutôt que de le relayer où que ce soit. (L’étape ARC ignore aussi d’elle-même tout message state.local_origin, de sorte qu’un mauvais placement ne peut pas sceller une soumission — mais la garder hors de la branche sortante évite le saut inutile.)

Note

Le chemin sortant nécessite le port 25 sortant (voir Prérequis), que les fournisseurs bon marché bloquent souvent. Si le vôtre est bloqué, remettez plutôt via un smarthost amont : remplacez [stage-internet] par une étape pepsi-stage-relay-to-smarthost et définissez le smarthost — voir pepsi-stage-relay-to-smarthost. Pour renvoyer des rapports de non-remise lorsqu’un MX refuse le courrier sortant de vos utilisateurs, donnez aussi à [stage-internet] un BOUNCE_STAGE = bounce.

2.12.2. Fournir un backend de mots de passe (Dovecot)

Un listener de soumission a besoin d’un moyen de vérifier les mots de passe. Pepsi ne tient aucune base de données de mots de passe propre ; il vérifie les identifiants via une socket SASL Dovecot. Installez Dovecot et configurez-le pour authentifier vos comptes (les utilisateurs système que vous avez créés, ou des utilisateurs virtuels). Le serveur entrant de Pepsi s’exécute en tant qu’utilisateur non privilégié pepsi-ingress, qui ne peut pas ouvrir la socket auth-client partagée et réservée à root de Dovecot ; donnez-lui donc un listener dédié qu’il possède — dans /etc/dovecot/conf.d/10-pepsi.conf

service auth {
  unix_listener auth-client-pepsi {
    mode = 0600
    user = pepsi-ingress
  }
}

Vous n’avez pas à l’écrire à la main : pepsi-setup run détecte une socket inaccessible et propose d’installer exactement ce drop-in (en le validant avec doveconf et en rechargeant Dovecot), ou l’affiche s’il ne le peut pas.

Dovecot est aussi ce que vous ajouteriez pour permettre aux clients de lire leurs Maildirs via IMAP (Étapes suivantes). Sa configuration complète dépasse ce guide ; voir la documentation de Dovecot.

2.12.3. Ajouter les listeners de soumission

Ajoutez un listener en TLS implicite sur 465 (recommandé pour les clients) et/ou un listener STARTTLS sur 587. SUBMISSION = yes rend l’authentification obligatoire et applique les corrections RFC 6409 (un Date:/Message-ID: manquant est ajouté) ; SASL_TYPE/SASL_PATH câblent Dovecot. L’authentification n’est jamais offerte que via TLS. Comme pour le listener MX, laisser TLS_CERT/TLS_KEY non réglés permet à pepsi-setup d’installer automatiquement le certificat mail.example.org

# Port 465: implicit TLS.
[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 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

Relancez l’amorçage pour que les certificats des nouveaux listeners et l’enregistrement SPF mis à jour soient pris en compte, puis redémarrez les services

pepsi-setup -c /etc/pepsi/pepsi.conf run > pepsi-dns.zone

Publiez les enregistrements mis à jour (l’enregistrement SPF liste maintenant cet hôte) et revérifiez avec pepsi-setup -c /etc/pepsi/pepsi.conf check.

2.12.4. Connecter un client de messagerie

Dans les paramètres de compte du client, configurez le serveur sortant (SMTP) :

  • Serveur / hôte : mail.example.org

  • Port / sécurité : 465 avec TLS implicite (SSL/TLS), ou 587 avec STARTTLS

  • Authentification : mot de passe normal

  • Nom d’utilisateur / mot de passe : le compte que Dovecot attend (par exemple alice ou alice@example.org) et son mot de passe

Si vous avez aussi configuré Dovecot pour IMAP, pointez le serveur entrant vers le même hôte (IMAP, port 993, TLS). Envoyez un message de test à une adresse chez un autre fournisseur, confirmez qu’il a quitté la file d’attente

pepsi-status -c /etc/pepsi/pepsi.conf

et vérifiez qu’il est arrivé. La délivrabilité sortante dépend de la même hygiène DNS que la réception — un PTR/DNS inverse correct, l’enregistrement SPF listant cet hôte et la signature DKIM (tous configurés ci-dessus) ; une IP toute neuve est parfois greylistée au premier contact, de sorte qu’un court délai sur le tout premier message est normal.

2.13. Dépannage

Rien n’arrive

Vérifiez que l’enregistrement MX se résout vers mail.example.org et que l’enregistrement A/AAAA de celui-ci pointe vers le VPS ; confirmez que le port 25 entrant est ouvert (testez depuis un autre hôte) ; confirmez que le PTR/DNS inverse est réglé. Surveillez le journal de l’ingress.

Un message est bloqué ou failed

Inspectez-le avec pepsi-status et pepsi-queue. Un destinataire qui n’est pas dans TARGETS ou qui n’a pas de compte rebondit vers l’expéditeur (surveillez [stage-bounce] et [stage-internet]), il n’est pas laissé dans la file d’attente ; une ligne timeout/en pause signifie souvent un problème de système de fichiers (par exemple un disque plein) dans le répertoire personnel du destinataire, réessayé avant de rebondir. Un rebond qui se bloque à son tour signifie généralement que le port 25 sortant est bloqué (voir ci-dessous).

L’étape du certificat a échoué

certbot a besoin que mail.example.org se résolve déjà vers ce VPS et que le port 80 entrant soit joignable. Corrigez le DNS/le port 80 et relancez pepsi-setup … run, ou utilisez --no-certbot et fournissez TLS_CERT/TLS_KEY vous-même.

« Permission refusée » à la remise

Les bits de privilège de l’étape 3 sont incorrects : le helper doit être 4750 root:pepsi-maildir et l’étape relay-to-maildir 2550 pepsi:pepsi-maildir. Relancez make install en tant que root avec le groupe et le compte pepsi présents, ou réglez-les à la main.

Un client ne peut s’authentifier ou envoyer

L’authentification n’est offerte que via TLS — utilisez le port 465 (TLS implicite) ou 587 avec STARTTLS et « mot de passe normal ». Une réponse 530 signifie que la session n’était pas authentifiée ; vérifiez que la socket d’authentification de Dovecot (SASL_PATH) est lisible par l’utilisateur pepsi-ingress — le compte auquel le serveur SMTP s’abaisse, et celui que nomme le drop-in ci-dessus — et que Dovecot accepte les identifiants.

Le courrier sortant est bloqué

La remise Internet directe nécessite le port 25 sortant ; si le fournisseur le bloque, basculez [stage-internet] vers un smarthost (voir la note ci-dessus). Inspectez les lignes bloquées avec pepsi-status et pepsi-queue.

2.14. Étapes suivantes

  • Lire le courrier à distance. Ajoutez un serveur IMAP (par exemple Dovecot) pointé vers le même ~/Maildir afin que les clients de messagerie puissent le récupérer ; Pepsi ne gère que la remise dans le Maildir. Si vous avez déjà ajouté Dovecot pour l’authentification de soumission ci-dessus, activer IMAP est une petite étape supplémentaire.

  • Transformer ceci en redirecteur. Insérez pepsi-stage-srs sur le chemin entrant afin que le courrier réexpédié à un tiers passe SPF, en réutilisant le relais sortant ([stage-sign] → [stage-internet]) déjà présent dans cette configuration (Introduction).

  • Personnaliser les rebonds. Le chemin de rebond est déjà câblé ; vous pouvez localiser ou personnaliser le texte du DSN avec un modèle BOUNCE_MESSAGE — voir pepsi-stage-bounce.

  • Durcir le TLS entrant (MTA-STS + TLS reporting). Indiquez aux autres expéditeurs d’utiliser un TLS validé vers votre MX en servant une politique MTA-STS, et collectez les TLS Reports (RFC 8460). Les deux nécessitent le serveur HTTPS (pepsi-httpd) en service et un certificat pour chaque mta-sts.<domain> ; la façon la plus simple de les ajouter est de relancer pepsi-setup --wizard et de répondre yes aux deux questions de sécurité du transport (il pré-remplit vos réponses antérieures).

  • Filtrer et protéger. Superposez le blocage de langue, la mise en liste blanche des expéditeurs ou le péage à l’envoi — voir Fonctionnalités prises en charge et les chapitres par étape.

  • Placer Pepsi devant un déploiement Exchange ou Microsoft 365 existant. Pepsi peut se placer devant et derrière Exchange comme passerelle cryptographique transparente, de sorte que les utilisateurs obtiennent S/MIME et OpenPGP sans toucher à leurs clients. C’est une topologie différente de celle ci-dessus — le courrier est acheminé vers Exchange plutôt que remis localement, ce qui rend la prévention des boucles obligatoire plutôt que recommandée — et elle a son propre chapitre : Microsoft Exchange comme passerelle.