8. Dépannage

Commencez par deux commandes ; la plupart des problèmes apparaissent dans l’une d’elles :

pepsi-status
journalctl -u 'pepsi-*' -p warning --since '1 hour ago'

Exploiter Pepsi explique les journaux et ce que rapporte pepsi-status. Les problèmes ci-dessous sont ceux que les premiers déploiements ont rencontrés le plus souvent.

8.1. Problèmes courants

8.1.1. Aucun courrier n’arrive

  • Un autre MTA occupe le port 25. Debian en installe un par défaut. systemctl start pepsi.target échoue alors, et systemctl status pepsi-ingress.socket affiche Result: resources. ss -ltnp 'sport = :25' nomme le programme ; arrêtez-le et désactivez-le (voir Installation, « Migrer depuis un serveur de messagerie existant »).

  • Le DNS ou le pare-feu. L’enregistrement MX du domaine doit nommer cet hôte et le port 25 doit être ouvert depuis Internet. pepsi-setup -c /etc/pepsi/pepsi.conf run affiche les enregistrements qu’il attend et vérifie ceux qui sont publiés.

  • Pepsi refuse le message. Le serveur de l’expéditeur reçoit la raison, tout comme le journal de pepsi-ingress. Les raisons habituelles : 550 5.1.1 pour une adresse vers laquelle rien sur cet hôte ne remet (voir VERIFY_RECIPIENTS dans pepsi-ingress(1)) ; 550 pour un échec DMARC certain sous DMARC_ENFORCE ; 452 4.3.1 lorsque la file d’attente ou le disque est plein (voir MAX_QUEUE_ROWS et MIN_FREE_SPACE dans pepsi.conf(5)).

8.1.2. Le courrier sortant n’est pas remis

pepsi-status liste les messages en attente à chaque étape. Les messages qui restent paused à une étape de relais sont en cours de nouvelle tentative ; pepsi-queue list ID --state-only montre la dernière réponse du serveur distant. Causes courantes :

  • Le port 25 sortant est bloqué. De nombreux hébergeurs et fournisseurs d’accès résidentiels le bloquent. Relayez plutôt via un smarthost (pepsi-setup --wizard).

  • Le serveur destinataire rejette le courrier ou le classe comme spam. Vérifiez que les enregistrements SPF, DKIM et DMARC qu’affiche pepsi-setup run sont publiés, et que l’adresse de l’hôte a un nom DNS inverse correspondant à [pepsi-ingress] HOSTNAME.

8.1.3. sendmail ou le courrier de cron échoue avec « temporary failure »

pepsi-sendmail remet le courrier à pepsi-ingress via /run/pepsi/submission.sock et se termine avec le code 75 (échec temporaire) lorsque personne n’y répond. Vérifiez que pepsi.target tourne. Si /run/pepsi a été supprimé à la main, systemd-tmpfiles --create le recrée avec les bonnes permissions ; redémarrez ensuite pepsi-ingress.

8.1.4. Un programme se termine avec le code 78

Le schéma de la base de données n’est pas celui avec lequel le programme a été construit, typiquement dans les minutes qui suivent une mise à niveau, avant que pepsi-setup schema n’ait été exécuté. Le message indique le remède ; Mise à niveau contient le tableau des cas. Les services réessaient d’eux-mêmes et reviennent dès que le schéma correspond.

8.1.5. « permission denied » de la part de la base de données

Les droits des rôles de la base de données sont fixés par pepsi-setup. Après la restauration d’une base de données, ou après avoir modifié des rôles à la main, exécutez à nouveau pepsi-setup -c /etc/pepsi/pepsi.conf run.

8.1.6. Messages en failed ou timeout

La plupart des erreurs ne mettent pas du tout fin à un message, car elles sont imputables à cet hôte plutôt qu’au message :

  • Une connexion à la base de données perdue : le message est mis en pause et réessayé toutes les 30 secondes jusqu’au retour de la base de données, et chaque réessai est journalisé sous pepsi-dispatch (« lost its database connection »).

  • Toute autre erreur signalée par une étape — une clé, un modèle, une table ou un magasin de confiance qui ne peut être lu, un helper qui ne peut être démarré, une instruction de base de données refusée, un service qui ne répond pas : le message reste paused à son étape avec l’erreur dans state.last_error, et est réessayé après une minute, puis à des intervalles qui doublent jusqu’à une heure, pendant le MAX_LIFETIME de l’étape (120 heures sauf configuration contraire). L’étape journalise chaque réessai (« failed at stage “…” (attempt N); retrying in …s »). Corrigez la cause et la file se vide d’elle-même ; pepsi-status montre entre-temps les messages en attente. Lorsque MAX_LIFETIME est écoulé, le message part vers le BOUNCE_STAGE de l’étape, dont le DSN indique à l’expéditeur qu’une erreur locale a persisté.

  • Une étape dont la configuration ne s’analyse plus ne démarre pas du tout : le dispatcher journalise « the worker refused to start », garde les messages en file et réessaie toutes les quelques secondes. La ligne de journal propre à l’étape dit ce qui ne va pas.

  • Un worker qui plante ou se bloque au-delà de MAX_RUNTIME met en pause le message qu’il traitait et le réessaie une minute plus tard ; ce n’est qu’à la troisième fois que le message est abandonné.

  • Un milter qui continue de différer un message, ou qui ne peut être joint, le retient lui aussi pendant MAX_LIFETIME, puis le fait rebondir (ou le laisse failed) — il ne l’abandonne jamais via le REJECT_STAGE du filtre. Un milter qui ne diffère que certains destinataires ne retient que leur copie, sous la forme d’un message paused distinct à l’étape du milter, tandis que les autres sont remis.

Un message ne finit en failed que lorsqu’une étape a trouvé un défaut dans le message lui-même, lorsqu’une étape sans BOUNCE_STAGE a épuisé ses réessais, ou lorsqu’il a fait planter son worker trois fois ; et en timeout lorsqu’il l’a bloqué trois fois. state.failure_class et state.last_error disent lequel et pourquoi.

Les erreurs de remise venant du serveur suivant (un MX qui refuse ou est injoignable, une recherche DNS qui expire) sont réessayées de la même manière par les étapes de relais elles-mêmes. Un message en échec vaut encore souvent la peine d’être réessayé une fois la cause corrigée.

pepsi.target exécute pepsi-failure-bouncer --once toutes les dix minutes (pepsi-failure-bouncer.timer). Il déplace chaque message failed ou timeout qui l’est depuis [pepsi-failure-bouncer] MIN_AGE (une heure sauf configuration contraire) vers l’étape nommée par [pepsi-failure-bouncer] BOUNCE_STAGE (bounce dans la configuration livrée et dans celle de l’assistant), qui envoie à l’expéditeur une notification d’état de remise selon ce que demande son NOTIFY, et journalise chacun avec la raison. Un expéditeur dont le message n’a pas authentifié le domaine ne reçoit aucune notification sous BOUNCE_UNAUTHENTICATED = drop, et le message est supprimé, avec un avertissement dans le journal de l’étape de rebond. Une copie d’une contribution à une liste de diffusion est supprimée plutôt que renvoyée en rebond. Ainsi, un message en échec reste environ MIN_AGE dans la file ; pour le réessayer plutôt que de le faire rebondir, agissez dans ce délai :

pepsi-queue list --status failed          # which messages, at which stage
pepsi-queue list 1234 --state-only        # why: state.last_error, state.bounce, …
pepsi-queue set-stage 1234 relay          # retry it from a stage of your choice
pepsi-failure-bouncer --once              # or bounce all of them now
pepsi-queue delete 1234                   # or discard it

Les options de list se placent après le mot list. systemctl list-timers pepsi-failure-bouncer.timer indique quand aura lieu le prochain balayage, et journalctl -u pepsi-failure-bouncer combien de messages chacun a déplacés.

8.1.7. Conserver les messages en échec pour le diagnostic

Sur une machine de développement ou de test, un message en échec est généralement précisément ce que vous voulez examiner, et un rebond une heure plus tard le détruit. Augmentez MIN_AGE, ou désactivez-y le balayage :

systemctl mask --now pepsi-failure-bouncer.timer

mask plutôt que disable : pepsi.target requiert le timer, de sorte qu’un timer simplement désactivé ou arrêté redémarre avec la cible. Les messages en échec restent alors dans la file jusqu’à ce que vous les réessayiez, les fassiez rebondir ou les supprimiez comme ci-dessus. Pour réactiver le balayage :

systemctl unmask pepsi-failure-bouncer.timer
systemctl start pepsi-failure-bouncer.timer

Le balayage suivant fait alors rebondir tout ce qui a échoué entre-temps ; supprimez d’abord ce que vous ne voulez pas voir rebondir. Ne laissez pas le timer masqué sur un serveur qui traite du vrai courrier : personne n’est informé d’un message en échec, ni l’expéditeur ni vous, à moins que vous ne surveilliez problem_total (voir Surveillance).

pepsi-failure-bouncer peut aussi s’exécuter comme un service qui fait rebondir chaque message en échec au moment où l’échec survient. Aucune unité n’est livrée pour ce mode ; masquez le timer avant de le lancer depuis votre propre unité.

8.2. Questions fréquentes

Pepsi tient-il un journal de qui a écrit à qui ?

Pas par défaut. Un message remis est supprimé de la file d’attente et seul le journal le mentionne. [pepsi] MAIL_LOG active un enregistrement par message ; lisez d’abord l’avertissement dans pepsi.conf(5).

Où se trouve la file d’attente ?

Dans PostgreSQL, table pepsi.workqueue. pepsi-queue et pepsi-status sont les moyens pris en charge pour l’examiner ; un simple SELECT fonctionne aussi.

Comment voir le pipeline que cet hôte exécute ?

pepsi-config dump affiche la configuration effective (--origin montre aussi quels réglages la base de données surcharge), et pepsi-setup run affiche, pour chaque domaine, comment les destinataires sont vérifiés. L’assistant explique les pipelines que construit l’assistant.

Puis-je revenir à la version précédente ?

Pas sur place : le schéma n’est migré que vers l’avant. Restaurez la sauvegarde prise avant la mise à niveau, puis installez les paquets plus anciens ; voir Mise à niveau.

Pepsi peut-il tourner à côté de Postfix ou d’Exim ?

Pas tous deux sur le port 25. Pepsi peut importer la configuration de l’autre serveur ; voir Installation.

Pourquoi la console affiche-t-elle tout en lecture seule ?

Le paquet pepsi-httpd-admin, qui exécute les modifications de la console, n’est pas installé ou sa socket ne tourne pas ; voir Paquets Debian.

8.3. Désinstallation

Paquets Debian. apt remove pepsi arrête les services et supprime les programmes ; la configuration, les clés, la base de données et les comptes de service restent, de sorte qu’une installation ultérieure reprend là où elle s’était arrêtée. apt purge pepsi supprime le reste de ce que le paquet a installé mais, à dessein, conserve toujours la configuration, la base de données, les clés, les portefeuilles et les comptes, et affiche les commandes qui les suppriment. Les voici, en tant que root :

runuser -u postgres -- dropdb pepsi
rm -rf /var/pepsi /var/lib/pepsi-wallets /etc/pepsi
for u in pepsi pepsi-ingress pepsi-httpd pepsi-owner pepsi-config \
         pepsi-helper-token-refresh pepsi-keydisc pepsi-crypto \
         pepsi-whitelist pepsi-wallets; do deluser "$u"; done
for g in pepsi-maildir pepsi-forward pepsi-token pepsi-admin \
         pepsi-telemetry; do delgroup "$g"; done

Les rôles de base de données de mêmes noms peuvent ensuite être supprimés avec dropuser. Supprimez pepsi-telemetry et pepsi-httpd-admin de la même manière s’ils sont installés.

Installation depuis les sources. Arrêtez et désactivez pepsi.target, puis exécutez make uninstall avec les mêmes PREFIX/DESTDIR que lors de l’installation. Cela supprime les programmes, les données livrées et les unités systemd, mais pas la configuration, les clés ni la base de données ; supprimez-les comme ci-dessus.

Avertissement

Tout ce qui est supprimé de cette manière disparaît définitivement, y compris la clé de chiffrement de clés sans laquelle les clés privées stockées ne peuvent pas être ouvertes. Faites d’abord une sauvegarde (Sauvegarde et restauration) s’il y a la moindre chance que vous vouliez un jour retrouver les clés, les listes de diffusion ou leur archive.