Erreurs "Unexplained Email::Receiver::InvalidPost" inexpliquées

Quelques listes de diffusion sont mises en miroir sur Mailing Lists - Tor Project Forum

Nous avons récemment remarqué que certains messages n’étaient pas mis en miroir de la liste de diffusion Mailman3 vers le forum.

Les journaux de rejet d’e-mails montrent que ces e-mails ont rencontré une erreur Email::Receiver::InvalidPost.

Le message d’erreur enregistré est l’un des deux suivants :

Nous sommes désolés, mais votre message électronique à [« tor-relays@lists.torproject.org »] (intitulé [tor-relays] mesures de bande passante et latence des relais) n’a pas fonctionné.

Raison :

Accès refusé

Si vous pouvez corriger le problème, veuillez réessayer.

ou :

Nous sommes désolés, mais votre message électronique à [« tor-relays@lists.torproject.org »] (intitulé [tor-relays] Re: ponts webtunnel pour le distributeur Telegram) n’a pas fonctionné.

Raison :

Quelque chose s’est mal passé. Peut-être que ce sujet a été fermé ou supprimé pendant que vous le consultiez ?

Si vous pouvez corriger le problème, veuillez réessayer.

Je n’ai rien trouvé de suspect dans ces messages en examinant les en-têtes, bien que dans certains cas, le corps extrait tel qu’enregistré ne contienne que le pied de page de la liste de diffusion, ou dans un autre cas, il s’agisse d’une série de caractères incompréhensibles comme s’il y avait eu un problème de décodage.

J’ai essayé de reproduire ce problème en utilisant une liste de diffusion de test et une catégorie de test, mais sans succès. Toute aide pour déboguer cela serait appréciée.

« accepter les e-mails de comptes anonymes » est-il activé dans les paramètres de chaque catégorie, et pourriez-vous s’il vous plaît envoyer le journal des e-mails de Discourse (légèrement modifié si possible)

1 « J'aime »

Oui, je peux confirmer que ce paramètre est activé.

et pourriez-vous s’il vous plaît envoyer le journal des e-mails de Discourse (légèrement modifié si possible)

Est-ce quelque chose que je dois extraire du conteneur ou de l’hôte ? Nous traitons également le courrier via le conteneur mail-receiver. Ou voulez-vous les journaux qui sont exposés dans l’interface Web (par exemple, /admin/email-logs/rejected) ?

Est-ce que cela vient d’Exchange ?

Parfois, Microsoft Exchange envoie des données corrompues s’il est mal configuré pour penser qu’il communique avec… Je ne suis pas sûr - un autre serveur Exchange ? Quelque chose d’autre au sein de sa propre infrastructure ?

Vous pouvez examiner le courrier brut depuis la console Discourse avec par exemple :

mid = 'message-id from the log'
puts IncomingEmail.find_by(message_id: mid).raw

Cela affiche le courrier brut que Discourse a reçu. Par exemple, le corps de ce message que je viens de retirer de notre liste de rejet entrants est vraiment du charabia :

This is a multi-part message in MIME format.
--=====003_Dragon855807841081_=====
Content-Type: text/plain;
 charset=utf-8
Content-Transfer-Encoding: base64

7bgir+m+vzzIDCLE0mDmZrfIXvvmXjY=

--=====003_Dragon855807841081_=====
Content-Type: text/html;
 charset=utf-8
Content-Transfer-Encoding: base64

LP/0L4tqmfZizO0DCDDE10uOzMZqzSHDjq04SLPaBjibLVHz+V94m1M45NDN
55aM8SMIf9XY4EFjP9CCFz+ojfmJqmubaz+bjrzmubw+bjWTiGSuLg==

--=====003_Dragon855807841081_=====--

car les parties ne se décodent pas en texte valide.

2 « J'aime »

les deux seraient parfaits. Si vous utilisez PuTTy SSH, vous pouvez extraire les journaux du conteneur, et vous pourriez extraire des extraits de l’interface utilisateur de Discourse. Cependant, vous ne pouvez pas facilement rechercher des mots dans la photo pour les masquer :face_exhaling:

J’ai pu extraire deux e-mails avec les en-têtes complets. L’un est d’Apple Mail et l’autre de Claws Mail.

Je serais heureux de les transférer à l’adresse e-mail privée de quelqu’un pour le débogage, afin d’éviter de les coller partout sur Internet.

Je pense que dans les deux cas, c’est probablement Discourse qui ne parvient pas à analyser correctement le contenu de l’e-mail.

Pour information, cela reste un problème. Discourse rejette régulièrement les messages des listes de diffusion de divers expéditeurs avec l’erreur Email::Receiver::InvalidPost, pour des raisons que je n’arrive pas à comprendre.

Si vous cliquez sur l’erreur dans les journaux, la raison du rejet s’affiche-t-elle ?

par exemple :

Si vous cliquez sur l’erreur dans les journaux, est-ce que la raison du rejet l’indique ?

Ces messages se présentent sous deux formes :

Nous sommes désolés, mais votre message électronique à [\"tor-relays@lists.torproject.org\"] (intitulé [tor-relays] Re: rapport d'abus des relais de la famille 7EAAC49A7840D33B62FA276429F3B03C92AA9327) n'a pas fonctionné.

Raison :

Quelque chose s'est mal passé. Ce sujet a peut-être été fermé ou supprimé pendant que vous le consultiez ?

Si vous pouvez corriger le problème, veuillez réessayer.

Je peux confirmer qu’aucune de ces choses (sujet fermé ou supprimé) ne s’est produite dans ces cas.

D’autres fois, la raison est simplement Accès refusé.

Bonjour lavamind - désolé de déterrer un vieux fil de discussion, mais je voulais d’abord vérifier avant d’aller plus loin dans le débogage.

Rencontrez-vous toujours les rejets Email::Receiver::InvalidPost sur la mise en miroir des listes de diffusion à l’heure actuelle (fin 2025 / début 2026) ?

Si oui, pourriez-vous partager un bref aperçu de :

  • à quelle fréquence cela se produit (par exemple, quotidiennement / hebdomadairement, % des messages)
  • si la « Raison » de l’e-mail rejeté est toujours principalement « Accès refusé » par rapport à « sujet fermé/supprimé »
  • si cela affecte une liste/catégorie ou plusieurs

Une fois que nous aurons confirmé que cela se produit toujours, nous pourrons passer à la collecte de l’ensemble minimal de diagnostics pour un échec récent (Message-ID + l’e-mail brut stocké correspondant, etc.).

Pas besoin de vous excuser, je suis très heureux que vous examiniez cela.

Bonjour lavamind - désolé de déterrer un vieux fil de discussion, mais je voulais vérifier avant d’aller plus loin dans le débogage.

Voyez-vous toujours les rejets Email::Receiver::InvalidPost sur la mise en miroir de la liste de diffusion à l’heure actuelle (fin 2025 / début 2026) ?

Oui, le problème persiste.

environ à quelle fréquence cela se produit-il (par exemple, quotidiennement / hebdomadairement, % des messages)

La fréquence est difficile à déterminer exactement, mais le problème affecte au moins plusieurs messages par semaine, une estimation approximative se situe peut-être entre 5 et 10 % des messages ? Certains expéditeurs semblent être surreprésentés dans les journaux d’erreurs, donc au moins cela n’a pas l’air totalement aléatoire.

si la « Raison » de l’e-mail rejeté est toujours principalement « Accès refusé » par rapport à « sujet fermé/supprimé »

C’est toujours un mélange des deux.

si cela affecte une liste/catégorie ou plusieurs

Cela affecte principalement la catégorie tor-relays, mais cette liste reçoit des contributions régulières de plusieurs expéditeurs contrairement aux autres listes que nous mettons en miroir, qui reçoivent beaucoup moins de trafic.

Une fois que nous aurons confirmé que cela se produit toujours, nous pourrons passer à la collecte de l’ensemble minimal de diagnostics pour un échec récent (Message-ID + l’e-mail brut stocké correspondant, etc.).

Nous pourrions examiner ce fil de discussion récent. L’archive de Mailman indique qu’il a reçu 5 messages, mais le sujet miroir du forum n’en contient que 3 publications. Les journaux de rejet contiennent 3 erreurs InvalidPost pour ce sujet (2 du même expéditeur, étrangement) et pour toutes, la raison du rejet affichée est « Quelque chose s’est mal passé. Ce sujet a peut-être été fermé ou supprimé pendant que vous le consultiez ? »

Merci lavamind - c’est un point de données vraiment utile, surtout d’avoir un fil d’Ariane concret du type « L’archive Mailman montre 5, le sujet du forum montre 3 » sur lequel s’ancrer.

Étant donné que vous constatez cela plusieurs fois par semaine (environ 5 à 10 % des messages) et que, pour cet incident, la raison du rejet est constamment la variante trompeuse « sujet fermé/supprimé », la meilleure prochaine étape consiste à capturer un message de bout en bout afin que nous puissions voir ce que Discourse pensait faire.


Pour l’un des 3 e-mails rejetés associés à ce fil miroir, pourriez-vous récupérer ce qui suit :

  1. Depuis /admin/email-logs/rejected, ouvrez l’une des lignes InvalidPost pour cet incident et copiez :

    • le Message-ID
    • la date/heure
    • le (rédigé) À / De / Objet affiché dans la ligne
    • le texte complet de la raison du rejet (tel qu’affiché)
  2. Depuis la console Rails (dans le conteneur de l’application Discourse), extrayez l’e-mail brut stocké par Discourse :

@supermathie, IncomingEmail est-il toujours l’endroit canonique pour récupérer le brut, et y a-t-il autre chose que vous voudriez en plus pour le débogage d’InvalidPost ?

mid = "<collez le Message-ID du journal des e-mails rejetés ici>"
ie  = IncomingEmail.find_by(message_id: mid)

puts ie&.raw
  1. Extrayez également les attributs EmailLog appariés pour le même Message-ID (cela révèle souvent si Discourse l’a traité comme une réponse ou un nouveau sujet, et quels identifiants de sujet/catégorie il a résolus) :
mid = "<même Message-ID que ci-dessus>"

log = EmailLog.where(message_id: mid).order(created_at: :desc).first
pp log&.attributes&.slice(
  "id",
  "email_type",
  "to_address",
  "from_address",
  "subject",
  "post_id",
  "topic_id",
  "user_id",
  "status",
  "bounce_error_code",
  "bounce_key",
  "created_at"
)

Pourquoi ce trio ?

  • IncomingEmail.raw nous indique si l’e-mail est arrivé mal formaté / encodé bizarrement / seulement le pied de page, par opposition à Discourse choisissant la mauvaise partie MIME.
  • EmailLog nous indique ce que Discourse a tenté (nouveau sujet vs réponse, identifiants de sujet/catégorie résolus, etc.).
  • La ligne de l’interface utilisateur de l’e-mail rejeté confirme que nous examinons le même incident et préserve ce que les opérateurs voient.

Si la confidentialité est une préoccupation, n’hésitez pas à masquer les adresses et tout texte de corps de message à l’intérieur du brut, mais veuillez conserver :

  • Les en-têtes MIME (Content-Type, limites, charset, Content-Transfer-Encoding)
  • La structure multipartite (afin que nous puissions voir quelles parties existent)
  • Le Message-ID et les en-têtes de routage de base (vous pouvez masquer les domaines si nécessaire)

Une fois que nous aurons un Message-ID défaillant + IncomingEmail.raw + la tranche EmailLog, nous devrions être en mesure de déterminer rapidement s’il s’agit :

  • d’une incohérence de clé de réponse / routage de sujet,
  • d’un cas limite de permissions,
  • ou d’un échec d’analyse d’e-mail / sélection de partie MIME / décodage.

Merci pour ce tutoriel très détaillé !

Concentrons-nous sur ce message envoyé au sujet de la liste de diffusion.

Les en-têtes de l’incident du journal des messages rejetés indiquent ceci :

Message-ID: <20260103080033.5f6d8f90@dorfdsl.de>
Date: Sat, 03 Jan 2026 08:00:33 +0100
From: Marco Moock via tor-relays <tor-relays@lists.torproject.org>
To: tor-relays@lists.torproject.org
Subject: [tor-relays] Re: Questions about running an exit relay

Le texte complet de la raison du rejet est le suivant :

Nous sommes désolés, mais votre message électronique à ["tor-relays@lists.torproject.org"] (intitulé [tor-relays] Re: Questions about running an exit relay) n'a pas fonctionné.

Raison :

Quelque chose s'est mal passé. Peut-être que ce sujet a été fermé ou supprimé pendant que vous le consultiez ?

Si vous pouvez corriger le problème, veuillez réessayer.

L’enregistrement en texte brut de l’e-mail envoyé à Discourse depuis Mailman (IncomingEmail) est disponible ici (je ne crois pas qu’il contienne des données qui ne sont pas déjà publiques, mais de toute façon, j’ai réglé ce lien pour qu’il expire éventuellement).

Malheureusement, mes tentatives pour extraire le EmailLog n’ont produit aucun résultat : il semble que Discourse n’ait pas d’enregistrement de ce type pour ce message.

Merci @lavamind - c’est excellent (ID de message + texte de rejet + une copie de ce que Discourse a stocké).

Aussi : mes excuses pour la demande concernant EmailLog - il est très plausible (et peut-être attendu) qu’il n’y ait aucune ligne EmailLog pour un rejet entrant comme celui-ci. EmailLog est principalement destiné aux courriels sortants, tandis que les courriels entrants résident dans IncomingEmail (que vous avez déjà récupéré). @supermathie pouvez-vous confirmer que je n’envoie pas les gens dans la mauvaise direction ici ?

Étant donné que nous avons l’IncomingEmail, pourriez-vous coller les champs de métadonnées de cet enregistrement ? Cela nous donnera le contexte « qu’est-ce que Discourse a essayé de faire ? » que j’espérais obtenir de EmailLog.

Dans la console Rails :

# @supermathie vérification : pour le débogage d'un Post invalide entrant, les métadonnées IncomingEmail sont-elles la bonne prochaine chose à collecter ?
mid = "<20260103080033.5f6d8f90@dorfdsl.de>"
ie  = IncomingEmail.find_by(message_id: mid)

pp ie&.attributes&.slice(
  "id",
  "message_id",
  "from_address",
  "to_addresses",
  "cc_addresses",
  "subject",
  "created_at",
  "user_id",
  "post_id",
  "topic_id",
  "error"
)

# optionnel : si vous êtes à l'aise, ceci est souvent utile aussi
# (cela montre ce que Discourse a extrait comme corps par rapport à ce qu'il a stocké en brut)
pp ie&.attributes&.slice("raw", "cooked")

(Si raw/cooked sont volumineux, n’hésitez pas à les omettre - vous avez déjà partagé le brut.)

Pourquoi ces champs sont importants :

  • topic_id / post_id (s’ils sont présents) nous indiquent si Discourse a résolu cela comme une réponse/un nouveau message et ce qu’il ciblait.
  • user_id nous indique à quel utilisateur temporaire/réel Discourse a mappé l’expéditeur (cas de permissions / « Accès refusé »).
  • error est souvent plus spécifique que le texte de rebond générique « sujet fermé/supprimé ».

Si ces attributs montrent que la résolution topic_id/post_id pointe vers le sujet miroir, alors la prochaine étape probable est de déterminer pourquoi le récepteur a décidé qu’il était invalide (corps extrait vide, décodage MIME, désaccord de permissions, désaccord de clé de réponse, etc.). S’il n’y a aucune résolution de sujet/message, nous nous concentrons sur les en-têtes de routage / la détection de réponse.

Et encore une fois - merci pour le lien de collage. Avoir un seul ID de message défaillant concret comme celui-ci est exactement ce dont nous avions besoin pour arrêter de deviner.

Oui, c’est exact. Et je suis d’accord - cela montrera ce qui a été reçu, les associations que Discourse a pu établir, et espérons-le, indiquera la prochaine étape.

1 « J'aime »

Voici les champs de métadonnées pour l’IncomingObject

{"id"=>9785,
"message_id"=>"20260103080033.5f6d8f90@dorfdsl.de",
"from_address"=>"mm@dorfdsl.de",
"to_addresses"=>"tor-relays@lists.torproject.org",
"cc_addresses"=>"",
"subject"=>"[tor-relays] Re: Questions about running an exit relay",
"created_at"=>2026-01-03 07:03:04.639775000 UTC +00:00,
"user_id"=>10477,
"post_id"=>nil,
"topic_id"=>nil,
"error"=>"Email::Receiver::InvalidPost"}

Quant aux contenus brut/cuit, seule la propriété raw contient l’e-mail complet avec les en-têtes. La propriété cooked n’existe pas dans l’objet.

L’exécution de ceci via Email::Receiver.new(rawmessage).select_body renvoie :

=> ["", "", 2]

Je suis donc assez certain que ce qui se passe ici est que Discourse sélectionne incorrectement une partie texte brut vide comme corps du message, probablement celle-ci :

--Sig_/gizYC_1dGsAzUHvksdaMIe2
Content-Type: text/plain;
 charset=UTF-8
Content-Transfer-Encoding: 7bit


ce qui serait une publication invalide.

Nous devrons enquêter un peu sur cela et probablement l’utiliser comme cas de test.

Le mail a la structure suivante :

* #<Mail::Part:39500, Multipart: false, Headers: <MIME-Version: 1.0>, <Content-Type: text/plain; charset=us-ascii>, <Content-Transfer-Encoding: 7bit>, <Content-Disposition: inline>, <Content-ID: <6958bf289b75c_b28a46298091029@forum-01-app.mail>>>
  "___…tor-relays mailing list…"
* #<Mail::Part:39520, Multipart: true, Headers: <Content-Type: multipart/signed; boundary="Sig_/gizYC_1dGsAzUHvksdaMIe2"; micalg=pgp-sha256; protocol="application/pgp-signature">, <Content-Transfer-Encoding: 7bit>>>
  * #<Mail::Part:39540, Multipart: false, Headers: <Content-Type: text/plain; charset=US-ASCII>, <Content-Transfer-Encoding: quoted-printable>>>,
    "On 02.01.2026…"
  * #<Mail::Part:39560, Multipart: false, Headers: <Content-Type: text/plain; charset=UTF-8>, <Content-Transfer-Encoding: 7bit>>>,
    ""
  * #<Mail::Part:39580, Multipart: false, Headers: <Content-Type: text/plain; charset=US-ASCII>, <Content-Transfer-Encoding: quoted-printable>>>,
    "On 02.01.2026…"
  * #<Mail::Part:39600, Multipart: false, Headers: <Content-Type: text/plain; charset=UTF-8>, <Content-Transfer-Encoding: 7bit>>>,
    ""
  * #<Mail::Part:39620, Multipart: false, Headers: <Content-Type: text/plain; charset=US-ASCII>, <Content-Transfer-Encoding: quoted-printable>>>,
    "On 02.01.2026…"
  * #<Mail::Part:39640, Multipart: false, Headers: <Content-Type: text/plain; charset=UTF-8>, <Content-Transfer-Encoding: 7bit>>>,
    ""
  * #<Mail::Part:39660, Multipart: false, Headers: <Content-Type: text/plain; charset=US-ASCII>, <Content-Transfer-Encoding: quoted-printable>>>,
    "On 02.01.2026…"
  * #<Mail::Part:39680, Multipart: false, Headers: <Content-Type: application/pgp-signature>, <Content-Description: Digitale Signatur von OpenPGP>>>,
    PGP signature
  * #<Mail::Part:39700, Multipart: false, Headers: <Content-Type: application/pgp-signature>, <Content-Transfer-Encoding: 7bit>, <Content-Description: Digitale Signatur von OpenPGP>>>,
    PGP signature
  * #<Mail::Part:39720, Multipart: false, Headers: <Content-Type: application/pgp-signature>, <Content-Transfer-Encoding: 7bit>, <Content-Description: Digitale Signatur von OpenPGP>>>
    PGP signature

(oui, il y a trois copies du contenu réel, du contenu vide et de la signature PGP)

Cette première partie text/plain est ajoutée par le logiciel de liste de diffusion et ressemble à ceci :

_______________________________________________
tor-relays mailing list -- tor-relays@lists.torproject.org
To unsubscribe send an email to tor-relays-leave@lists.torproject.org

c’est ce que Discourse (en fait, le gem mail via .text_part) choisit comme contenu du message :

> puts mail.text_part.to_s
MIME-Version: 1.0
Content-Type: text/plain;
 charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
Content-ID: <6958bf289b75c_b28a46298091029@forum-01-app.mail>

_______________________________________________
tor-relays mailing list -- tor-relays@lists.torproject.org
To unsubscribe send an email to tor-relays-leave@lists.torproject.org

et est traité comme un corps vide avec une signature élidée.

S’il n’y avait pas cette partie principalement vide ajoutée par la liste de diffusion, Discourse aurait extrait le contenu suivant pour la publication :

> We received a court order to preserve the data on the system and were
> forbidden from informing the system owner, which was awkward since
> they had informed the system owner...

Quelles données ont-ils demandées ?

> Since then I've always run my exit on a separate system on it's own
> IP so if there were a legal demand to turn over "the system" it would
> really only be that system. I'm not a lawyer but I don't think docker
> provides enough isolation for that.

Peuvent-ils vous interdire d'arrêter le relais ?
Si oui, vous pourriez alors exploiter un nouveau "système" sur une autre IP.

(partie élidée ci-dessous)

On 02.01.2026 18:46 Jon via tor-relays <tor-relays@lists.torproject.org> wrote:

-- 
kind regards
Marco

Send spam to abfall1767375998@stinkedores.dorfdsl.de

Je ne peux vraiment pas reprocher à Discourse sa gestion des mails ici - si je devais répartir les torts, je commencerais probablement par le logiciel de liste de diffusion pour avoir effectivement ajouté du contenu vide au début. Cela aurait été mieux adapté à la fin, après le vrai message.

Cela aurait fonctionné avec le gem Mail et aurait également mieux rendu dans les clients de messagerie - voici ce que cela donne dans Thunderbird tel que reçu à l’origine :

et ma version “corrigée” (test-fixed.eml.txt (14.3 KB))
avec la signature de la liste de diffusion en bas au lieu du haut :

J’ai contacté un abonné (humain) à cette liste et voici à quoi ressemble le corps du message brut dans son MUA avec quelques en-têtes filtrés :

Subject: [tor-relays] Re: Questions about running an exit relay
List-Id: "support and questions about running Tor relays (exit, non-exit,
 bridge)" <tor-relays@lists.torproject.org>
Archived-At: 
 <https://lists.torproject.org/mailman3/hyperkitty/list/tor-relays@lists.torproject.org/message/OAX7EO72GLXS4KPKUG7QSG7EOAR2WYVA/>
List-Archive: 
 <https://lists.torproject.org/mailman3/hyperkitty/list/tor-relays@lists.torproject.org/>
List-Help: <mailto:tor-relays-request@lists.torproject.org?subject=help>
List-Owner: <mailto:tor-relays-owner@lists.torproject.org>
List-Post: <mailto:tor-relays@lists.torproject.org>
List-Subscribe: <mailto:tor-relays-join@lists.torproject.org>
List-Unsubscribe: <mailto:tor-relays-leave@lists.torproject.org>
From: Marco Moock via tor-relays <tor-relays@lists.torproject.org>
Reply-To: Marco Moock <mm@dorfdsl.de>
Content-Type: multipart/mixed; boundary="===============8958541500975114832=="

--===============8958541500975114832==
Content-Type: multipart/signed; boundary="Sig_/gizYC_1dGsAzUHvksdaMIe2";
 protocol="application/pgp-signature"; micalg=pgp-sha256

--Sig_/gizYC_1dGsAzUHvksdaMIe2
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: quoted-printable

On 02.01.2026 18:46 Jon via tor-relays
 <tor-relays@lists.torproject.org> wrote:

> We received a court order to preserve the data on the system and were
> forbidden from informing the system owner, which was awkward since
> they had informed the system owner...

Which data did they request?

> Since then I've always run my exit on a separate system on it's own
> IP so if there were a legal demand to turn over "the system" it would
> really only be that system. I'm not a lawyer but I don't think docker
> provides enough isolation for that.

Can they deny you to turn the relay off?
If so, you could then operate a new "system" on another IP.

--=20
kind regards
Marco

Send spam to abfall1767375998@stinkedores.dorfdsl.de

--Sig_/gizYC_1dGsAzUHvksdaMIe2
Content-Type: application/pgp-signature
Content-Description: Digitale Signatur von OpenPGP

-----BEGIN PGP SIGNATURE-----
iQJPBAEBCAA5FiEEpXefSZn9R6zNZtTQE76RLz2tRfAFAmlYvpEbFIAAAAAABAAO
bWFudTIsMi41KzEuMTEsMiwyAAoJEBO+kS89rUXw8kgP/2jkrwfSWHY6EY4WJjn6
EDEqT00pgpwEn9ZpUqLTreS3/ocfHC4g29HIsxpJcj/bH+hNAx96HEz9YmC4JfEt
LDjYc6D+5NBBFQGy0vaJ/LXLQc63CRE/yySSOYxFBZK+uMytNHoZDTjhfRroICbQ
guoO7A4/VuYrGAzCWQkBUmnBjj2LJhuLDW84ObMXhA/EuNy5FIAqyLZxoGmFEfvu
We5d0Hr3+wihzyrgGiG4u8UGFOyL+/PC11CFQyQ0j03cBzhZ5PVdtkqPNHauAcjQ
Gt/HQmaOSGKq0VODRjiHAe5TuRtV6jOfUNgS1Q2vB4FKYmeDQb82ooNfOiJWy3ey
Jpwgg700ppqgZUclpMPlzxKwi2dT/PSO6yYuy+G5sfa0Hxmn5DsQaiSPMTiEP2WC
NwAENYIuHeQOHWiS8B3oVSRW/naLzkmpfChFnTKGsrhLqKQc/iuvv639aHwg9BP7
YEbWbdpFpIU36czfxoTcDYDR1e4JLWryEFKIgo4TIaz4t17NmkxjXB6dHZKLLAdU
AT6LmL6mOTaXe9ewD9pf9Vf2nG0RGVJyZRUDmFzfU0Rx2qi7KdcmmRpZg/2QtJeA
Pmrv8NFuFEL0BrhTvo7C60m+gjLaXPNClgKEN0vkEzjLp/ZKjI9FslP61xUMg8lQ
3xT/HTkNt9uNH2ziBMXLK+5c
=0Euf
-----END PGP SIGNATURE-----

--Sig_/gizYC_1dGsAzUHvksdaMIe2--

--===============8958541500975114832==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
tor-relays mailing list -- tor-relays@lists.torproject.org
To unsubscribe send an email to tor-relays-leave@lists.torproject.org

--===============8958541500975114832==--

Il n’y a pas de duplication, et les parties sont correctement ordonnées. Je m’attendrais à ce que ce soit plus proche de ce que Mailman envoie réellement aux abonnés de la liste, sinon si la plupart des gens recevaient des messages avec le pied de page en haut, nous l’entendrions peut-être ?

Je me demande alors si quelque chose d’autre dans le pipeline de traitement pourrait perturber le corps du message. Notre serveur Discourse traite d’abord l’e-mail entrant via Postfix, qui est configuré pour le transmettre à un conteneur mail-receiver, qui le transmet ensuite au conteneur Discourse.

Oh ! Compte tenu de cela, je suis retourné enquêter à nouveau… et il s’avère que c’est bien notre problème après tout.

À partir de l’e-mail brut que vous avez publié ci-dessus, je viens de découvrir que IncomingEmail.raw ne stocke pas réellement l’e-mail brut… nous le modifions d’abord avec Email::Cleaner.

Cela semble être la faute de la gemme mail de Ruby… elle réorganise les parties d’un message électronique lors de sa réécriture :

[1] pry(main)> m = File.open('test.eml').read;
[2] pry(main)> Mail.new(m).parts
=> [
  #<Mail::Part:39680, Multipart: true, Headers: <Content-Type: multipart/signed; boundary="Sig_/gizYC_1dGsAzUHvksdaMIe2"; protocol="application/pgp-signature"; micalg=pgp-sha256>>,
  #<Mail::Part:39700, Multipart: false, Headers: <MIME-Version: 1.0>, <Content-Type: text/plain; charset="us-ascii">, <Content-Transfer-Encoding: 7bit>, <Content-Disposition: inline>>
]
[3] pry(main)> Mail.new(Mail.new(m).to_s).parts
=> [
  #<Mail::Part:39720, Multipart: false, Headers: <MIME-Version: 1.0>, <Content-Type: text/plain; charset=us-ascii>, <Content-Transfer-Encoding: 7bit>, <Content-Disposition: inline>, <Content-ID: <6966b4914df79_31d5b1d38126@mars.mail>>>,
  #<Mail::Part:39740, Multipart: true, Headers: <Content-Type: multipart/signed; boundary="Sig_/gizYC_1dGsAzUHvksdaMIe2"; micalg=pgp-sha256; protocol="application/pgp-signature">, <Content-Transfer-Encoding: 7bit>>
]

ce qui provoque le problème :

[38] pry(main)> puts Email::Receiver.new(m).select_body[0];
=> We received a court order to preserve the data on the system and were
=> forbidden from informing the system owner, which was awkward since
=> they had informed the system owner...

Which data did they request?

=> Since then I've always run my exit on a separate system on it's own
=> IP so if there were a legal demand to turn over "the system" it would
=> really only be that system. I'm not a lawyer but I don't think docker
=> provides enough isolation for that.

Can they deny you to turn the relay off?
If so, you could then operate a new "system" on another IP.

[39] pry(main)> puts Email::Receiver.new(Mail.new(m).to_s).select_body[0];
«no output»
Détails de la différence

test.eml : message brut tel que fourni
test-rubyparsed.eml : message analysé par ruby puis reconverti en chaîne de caractères
test-pythonparsed.eml : message analysé par python puis reconverti en chaîne de caractères

--- test.eml	2026-01-13 15:58:18.769489410 -0500
+++ test-rubyparsed.eml	2026-01-13 16:11:17.767312268 -0500
@@ -1,25 +1,46 @@
+Date: Tue, 13 Jan 2026 16:07:21 -0500
+From: Marco Moock via tor-relays <tor-relays@lists.torproject.org>
+Reply-To: Marco Moock <mm@dorfdsl.de>
+Message-ID: <6966b40914be8_31d5b1d38719@mars.mail>
 Subject: [tor-relays] Re: Questions about running an exit relay
+MIME-Version: 1.0
+Content-Type: multipart/mixed;
+ boundary="===============8958541500975114832=="
+Content-Transfer-Encoding: 7bit
 List-Id: "support and questions about running Tor relays (exit, non-exit,
   bridge)" <tor-relays.lists.torproject.org>
-Archived-At: 
- <https://lists.torproject.org/mailman3/hyperkitty/list/tor-relays@lists.torproject.org/message/OAX7EO72GLXS4KPKUG7QSG7EOAR2WYVA/>
-List-Archive: 
- <https://lists.torproject.org/mailman3/hyperkitty/list/tor-relays@lists.torproject.org/>
+Archived-At: <https://lists.torproject.org/mailman3/hyperkitty/list/tor-relays@lists.torproject.org/message/OAX7EO72GLXS4KPKUG7QSG7EOAR2WYVA/>
+List-Archive: <https://lists.torproject.org/mailman3/hyperkitty/list/tor-relays@lists.torproject.org/>
 List-Help: <mailto:tor-relays-request@lists.torproject.org?subject=help>
 List-Owner: <mailto:tor-relays-owner@lists.torproject.org>
 List-Post: <mailto:tor-relays@lists.torproject.org>
 List-Subscribe: <mailto:tor-relays-join@lists.torproject.org>
 List-Unsubscribe: <mailto:tor-relays-leave@lists.torproject.org>
-From: Marco Moock via tor-relays <tor-relays@lists.torproject.org>
-Reply-To: Marco Moock <mm@dorfdsl.de>
-Content-Type: multipart/mixed; boundary="===============8958541500975114832=="
+
+
+--===============8958541500975114832==
+MIME-Version: 1.0
+Content-Type: text/plain;
+ charset=us-ascii
+Content-Transfer-Encoding: 7bit
+Content-Disposition: inline
+Content-ID: <6966b40914ae9_31d5b1d38641@mars.mail>
+
+_______________________________________________
+tor-relays mailing list -- tor-relays@lists.torproject.org
+To unsubscribe send an email to tor-relays-leave@lists.torproject.org
 
  --===============8958541500975114832==
-Content-Type: multipart/signed; boundary="Sig_/gizYC_1dGsAzUHvksdaMIe2";
- protocol="application/pgp-signature"; micalg=pgp-sha256
+Content-Type: multipart/signed;
+ boundary="Sig_/gizYC_1dGsAzUHvksdaMIe2";
+ micalg=pgp-sha256;
+ protocol="application/pgp-signature"
+Content-Transfer-Encoding: 7bit
+
  
  --Sig_/gizYC_1dGsAzUHvksdaMIe2
-Content-Type: text/plain; charset=US-ASCII
+Content-Type: text/plain;
+ charset=US-ASCII
 Content-Transfer-Encoding: quoted-printable
  
 On 02.01.2026 18:46 Jon via tor-relays
@@ -39,7 +60,8 @@
 Can they deny you to turn the relay off?
 If so, you could then operate a new "system" on another IP.
 
---=20
+-- =
+
 kind regards
 Marco
  
@@ -47,6 +69,7 @@
  
 --Sig_/gizYC_1dGsAzUHvksdaMIe2
 Content-Type: application/pgp-signature
+Content-Transfer-Encoding: 7bit
 Content-Description: Digitale Signatur von OpenPGP
  
 -----BEGIN PGP SIGNATURE-----
@@ -69,14 +92,5 @@
 
 --Sig_/gizYC_1dGsAzUHvksdaMIe2--
 
---===============8958541500975114832==
-Content-Type: text/plain; charset="us-ascii"
-MIME-Version: 1.0
-Content-Transfer-Encoding: 7bit
-Content-Disposition: inline
-
-_______________________________________________
-tor-relays mailing list -- tor-relays@lists.torproject.org
-To unsubscribe send an email to tor-relays-leave@lists.torproject.org
-
+--===============8958541500975114832==
+
--- test.eml	2026-01-13 15:58:18.769489410 -0500
+++ test-pythonparsed.eml	2026-01-13 16:19:30.385608544 -0500
@@ -1,10 +1,8 @@
 Subject: [tor-relays] Re: Questions about running an exit relay
 List-Id: "support and questions about running Tor relays (exit, non-exit,
  bridge)" <tor-relays.lists.torproject.org>
-Archived-At: 
- <https://lists.torproject.org/mailman3/hyperkitty/list/tor-relays@lists.torproject.org/message/OAX7EO72GLXS4KPKUG7QSG7EOAR2WYVA/>
-List-Archive: 
- <https://lists.torproject.org/mailman3/hyperkitty/list/tor-relays@lists.torproject.org/>
+Archived-At: <https://lists.torproject.org/mailman3/hyperkitty/list/tor-relays@lists.torproject.org/message/OAX7EO72GLXS4KPKUG7QSG7EOAR2WYVA/>
+List-Archive: <https://lists.torproject.org/mailman3/hyperkitty/list/tor-relays@lists.torproject.org/>
 List-Help: <mailto:tor-relays-request@lists.torproject.org?subject=help>
 List-Owner: <mailto:tor-relays-owner@lists.torproject.org>
 List-Post: <mailto:tor-relays@lists.torproject.org>
3 « J'aime »