未解释的电子邮件::接收者::无效帖子错误

Got a few mailing lists mirrored over at Mailing Lists - Tor Project Forum

我们最近注意到,一些邮件未能从 Mailman3 邮件列表镜像到论坛。

邮件拒绝日志显示这些邮件遇到了 Email::Receiver::InvalidPost 错误。

日志中的错误消息是以下两种之一:

We’re sorry, but your email message to [“tor-relays@lists.torproject.org”] (titled [tor-relays] authority bandwidth measurements and latency) didn’t work.

Reason:

Access Denied

If you can correct the problem, please try again.

或:

We’re sorry, but your email message to [“tor-relays@lists.torproject.org”] (titled [tor-relays] Re: webtunnel bridges for the telegram distributor) didn’t work.

Reason:

Something has gone wrong. Perhaps this topic was closed or deleted while you were looking at it?

If you can correct the problem, please try again.

查看邮件头后,我找不到这些邮件有什么问题,尽管在某些情况下,日志中提取的正文只包含邮件列表页脚,或者在另一个实例中,它是一堆乱码字符,好像出现了某种解码错误。

我尝试使用测试邮件列表和测试类别重现此问题,但未成功。如果您能帮助调试此问题,我们将不胜感激。

是否在每个类别设置中都启用了“接受来自匿名账户的电子邮件”,另外,能否发送 Discourse 电子邮件日志(如果可能,请稍作编辑)

1 个赞

是的,我可以确认此设置已启用。

并且您能否发送 Discourse 电子邮件日志(如果可能,请进行少量编辑)?

这是我需要从容器或主机中提取的内容吗?我们还通过 mail-receiver 容器处理邮件。还是您想要 Web UI 中显示的日志(例如 /admin/email-logs/rejected)?

这是从 Exchange 发送过来的吗?

有时 Microsoft Exchange 会发送垃圾邮件,如果它被错误配置为认为它正在与……我不确定——另一个 Exchange 服务器?它自己基础设施中的其他东西?

您可以使用 Discourse 控制台查看原始邮件,例如:

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

这会显示 Discourse 收到的原始邮件。例如,我刚从我们的入站拒绝列表中提取的这条消息正文确实是垃圾邮件:

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_=====--

因为这些部分解码后不是有效文本。

2 个赞

两者都会很棒。如果您使用 PuTTy SSH,您可以提取容器日志,并且可以截取 Discourse UI 的片段。但是,您无法轻松地在照片中搜索单词以进行编辑😮‍💨

我已经成功提取了两封包含完整邮件头的邮件。一个是 Apple Mail,另一个是 Claws Mail。

我很乐意将它们转发给某人的私人电子邮件地址以进行调试,这样我们就可以避免在互联网上到处粘贴。

我认为在这两种情况下,很可能是 Discourse 未能正确解析电子邮件内容。

就记录而言,这仍然是一个问题。Discourse 经常因我无法弄清楚的原因,以 Email::Receiver::InvalidPost 错误丢弃来自不同发件人的邮件列表消息。

如果单击日志中的错误,它是否会在退回原因中显示原因?

例如:

“如果点击日志中的错误,它会在反弹原因中显示原因吗?”

这些消息有两种形式:

抱歉,您发送给 [\"tor-relays@lists.torproject.org\"] 的电子邮件(主题为 [tor-relays] Re: abuse report from relays in family 7EAAC49A7840D33B62FA276429F3B03C92AA9327)未能成功发送。

原因:

出现了一些问题。也许您在查看此主题时它已被关闭或删除?

如果您能纠正问题,请重试。

我能确认在这些情况下并未发生此类事情(主题已关闭或删除)。

其他时候,原因仅仅是“拒绝访问”。

您好 lavamind - 抱歉打扰旧帖,但在我们深入调试之前,我想先确认一下。

截至目前(2025 年末/2026 年初),您是否仍然在邮件列表镜像中看到 Email::Receiver::InvalidPost 的拒绝情况?

如果是,您能否分享一个快速快照,说明:

  • 大约多久发生一次(例如,每天/每周,消息的百分比)
  • 被拒绝邮件的“原因”是否仍然主要是“访问被拒绝”与“主题已关闭/删除”
  • 是否影响了一个列表/类别还是多个

一旦我们确认问题仍然存在,我们就可以着手收集单个最近失败的最小诊断信息(Message-ID + 相应的已存储原始邮件等)。

不用道歉,我很高兴你正在调查此事。

嗨 lavamind - 抱歉顶起一个旧帖子,但在我们深入调试之前,我想先确认一下。

截至目前(2025 年末/2026 年初),你是否仍然在邮件列表镜像中看到 Email::Receiver::InvalidPost 拒绝?

是的,问题仍然存在。

它发生的频率大致是多少(例如,每天/每周,消息的百分比)

频率很难确切确定,但该问题至少影响每周几条消息,粗略估计可能在 5% 到 10% 之间?一些发件人在错误日志中似乎被过度代表,所以至少看起来不完全是随机的。

被拒绝的电子邮件的“原因”是仍然主要是“访问被拒绝”与“主题已关闭/已删除”

仍然是两者的混合。

它影响一个列表/类别还是多个

它主要影响 tor-relays 类别,但与我们镜像的其他流量较低的列表不同,该列表会定期收到来自多个发件人的输入。

一旦我们确认它仍然存在,我们就可以开始收集单个最近失败的最小诊断集(Message-ID + 相应的存储的原始电子邮件等)。

我们可以查看这个最近的帖子。Mailman 的存档显示它收到了 5 封邮件,但论坛镜像主题中只有 3 个帖子。拒绝日志包含此主题的 3 个 InvalidPost 错误(奇怪的是,其中 2 个来自同一发件人),并且它们都被显示的拒绝原因为“发生了一些错误。也许您在查看时此主题已被关闭或删除?”

感谢 lavamind——这是一个非常有帮助的数据点,特别是有一个具体的“邮件列表存档显示 5 封,论坛主题显示 3 封”的主题可以作为参考。

考虑到您每周都会遇到这种情况(粗略估计占消息的 5-10%),并且对于这次事件,退信原因始终是误导性的“主题已关闭/已删除”变体,下一步最好的做法是捕获一封端到端的失败邮件,以便我们能看到 Discourse 认为它在做什么。


对于与该镜像主题相关的 3 封被拒绝的电子邮件中的一封,您能否获取以下信息:

  1. /admin/email-logs/rejected 中,打开该事件的一行 InvalidPost 记录并复制:

    • Message-ID
    • 日期/时间
    • 行中显示的 (已编辑的)收件人/发件人/主题
    • 完整的退信原因文本(显示的内容)
  2. 在 Rails 控制台中(在 Discourse 应用程序容器中),提取 Discourse 存储的原始电子邮件:

@supermathie IncomingEmail 仍然是获取原始邮件的规范位置吗?为了调试 InvalidPost,您还需要它旁边的其他信息吗?

mid = "<粘贴来自被拒绝邮件日志中的 Message-ID>"
ie  = IncomingEmail.find_by(message_id: mid)

puts ie&.raw
  1. 另外,提取同一 Message-ID 对应的配对的 EmailLog 属性(这通常会揭示 Discourse 是将其视为回复还是新主题,以及它解析出的主题/类别 ID):
mid = "<与上面相同的 Message-ID>"

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"
)

为什么是这三项?

  • IncomingEmail.raw 告诉我们邮件是格式错误/编码奇怪/仅包含页脚到达,还是 Discourse 选择的“错误”的 MIME 部分。
  • EmailLog 告诉我们 Discourse 尝试了什么(新主题与回复,解析出的主题/类别 ID 等)。
  • 被拒绝邮件的 UI 行确认我们正在查看相同的事件,并保留了管理员看到的内容。

如果隐私是问题,您可以随意编辑地址和原始邮件中的任何正文文本,但请保留:

  • MIME 标头(Content-Type、边界、charset、Content-Transfer-Encoding)
  • 多部分结构(以便我们能看到存在哪些部分)
  • Message-ID 和基本路由标头(如果需要,可以编辑域名)

一旦我们有了一个失败的 Message-ID + IncomingEmail.raw + EmailLog 片段,我们应该能很快判断出这是:

  • 回复键/主题路由不匹配,
  • 权限的边缘情况,
  • 还是电子邮件解析/MIME 部分选择/解码失败。

感谢您提供的详细演练!

让我们关注发送到邮件列表主题的这条消息

被拒绝的帖子日志事件标题显示如下:

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

完整的拒绝原因文本如下:

We're sorry, but your email message to ["tor-relays@lists.torproject.org"] (titled [tor-relays] Re: Questions about running an exit relay) didn't work.

Reason:

Something has gone wrong. Perhaps this topic was closed or deleted while you were looking at it?

If you can correct the problem, please try again.

从 Mailman 发送到 Discourse 的电子邮件的纯文本记录(IncomingEmail)可以在这里找到(我不认为它包含任何非公开数据,但无论如何我设置了该链接会过期)。

不幸的是,我提取 EmailLog 的尝试未能产生任何结果:看起来 Discourse 没有关于该消息的此类记录。

感谢 @lavamind - 这真是太棒了(Message-ID + 拒绝文本 + Discourse 存储内容的副本)。

另外:关于 EmailLog 的请求是我的疏忽——对于此类入站拒绝,没有 EmailLog是完全合理的(也许是预期的)。EmailLog 主要用于传出邮件,而入站邮件存在于 IncomingEmail 中(您已经提取了)。@supermathie 您能确认我没有误导大家吗?

鉴于我们确实IncomingEmail,您能否粘贴来自该记录的元数据字段?这将为我提供我希望从 EmailLog 中获取的“Discourse 尝试做什么?”的上下文。

在 Rails 控制台中:

# @supermathie 快速检查:对于入站 InvalidPost 调试,IncomingEmail 元数据是下一步要收集的正确信息吗?
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"
)

# 可选:如果您方便,这通常也很有用
# (它显示了 Discourse 从正文中提取了什么与它原始存储了什么)
pp ie&.attributes&.slice("raw", "cooked")

(如果 raw/cooked 非常大,可以省略它们——您已经分享了 raw。)

为什么这些字段很重要:

  • topic_id / post_id(如果存在)告诉我们 Discourse 是否将此解析为回复/新帖子以及它针对的是什么。
  • user_id 告诉我们 Discourse 将发件人映射到哪个临时/真实用户(权限/“访问被拒绝”的情况)。
  • error 通常比通用的“主题已关闭/删除”的退回文本更具体。

如果这些属性显示 topic_id/post_id 解析指向镜像主题,那么下一步很可能是弄清楚接收方决定它无效的原因(提取的正文为空、MIME 解码、权限不匹配、回复密钥不匹配等)。如果它显示没有主题/帖子解析,我们将重点关注路由标题/回复检测。

再次感谢您的粘贴链接。拥有这样一个具体的失败 Message-ID 正是我们停止猜测所需要的。

是的,这是正确的。我同意——它将显示收到了什么,Discourse 能够建立哪些关联,并希望指示下一步操作。

1 个赞

以下是 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"}

至于原始/处理后的内容,只有 raw 属性包含带有标头的完整电子邮件。cooked 属性不存在于该对象中。

[quote=“lavamind, post:13, topic:377793”]发送到 Discourse 的邮件(来自 Mailman 的 IncomingEmail)的纯文本记录可在此处查看:here
[/quote]

将该内容通过 Email::Receiver.new(rawmessage).select_body 运行后返回:

=> ["", "", 2]

因此我相当确定这里发生的情况是 Discourse 错误地选择了一个空的纯文本部分作为消息正文,可能是这个部分:

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


这将是一个无效的帖子。

我们需要对此进行一些调查,并可能将其用作测试用例。

邮件的结构如下:

* #<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

(是的,实际内容有三份副本,空内容和 PGP 签名)

第一个 text/plain 部分由邮件列表软件添加,看起来像这样:

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

Discourse(实际上是通过 .text_part 的邮件 gem)将其内容识别为:

> 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

并将其视为带有省略签名的空白正文。

如果不是邮件列表添加的这个几乎空白的部分,Discourse 会从帖子中提取以下内容:

> 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...

他们要求了哪些数据?

> 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.

他们能拒绝你关闭中继吗?
如果可以,你可以在另一个 IP 上运行一个新的“系统”。

(下面省略了一部分)

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

我真的找不出 Discourse 在这里处理邮件有什么问题——如果让我来分配责任,我可能会先从邮件列表软件开始,因为它有效地在开头添加了空白内容。这部分内容放在末尾会更合适,在真实消息 之后

它本可以与 Mail gem 正常工作,在邮件客户端中看起来也会更好——这是 Thunderbird 中收到的原始邮件的样子:

这是我的“修复”版本(test-fixed.eml.txt (14.3 KB)),将邮件列表签名放在底部而不是顶部:

我联系了一位该列表的(人工)订阅者,这是他们在 MUA 中看到的原始邮件正文,其中一些邮件头已被过滤:

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==--

没有重复项,并且部分顺序正确。我猜这更接近 Mailman 实际发送给列表订阅者的内容,否则如果大多数人收到的邮件页脚在顶部,我们可能会听到一些动静?

那么,我怀疑是管道中的其他内容在干扰邮件正文。我们的 Discourse 服务器首先使用 Postfix 处理传入的电子邮件,Postfix 配置为将其移交给 mail-receiver 容器,然后该容器再将其移交给 Discourse 容器。

哦!鉴于此,我回去重新调查了一下……结果发现这确实是我们的问题。

从你上面发布的原始邮件中,我刚刚发现 IncomingEmail.raw 实际上并没有存储原始邮件……我们用 Email::Cleaner 对其进行了清理。

这似乎是 Ruby mail gem 的问题……它在写回邮件消息时会重新排序邮件消息的部件

[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>>
]

这导致了问题:

[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»
差异详情

test.eml: 提供的原始消息
test-rubyparsed.eml: 经 ruby 解析后再转回字符串的消息
test-pythonparsed.eml: 经 python 解析后再转回字符串的消息

--- 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: <6966b40914df7_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,14 +69,15 @@
  --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 个赞