← RFC Reference

RFC 6377: DKIM 和邮件列表

Mailing Lists & Header Fields Published March 2026
ELI5: 当你将一封带有 DKIM 签名的电子邮件发送到邮件列表时,列表软件通常会更改你的邮件——添加页脚、修改主题、改写发件人地址。这些更改会破坏你的 DKIM 签名,就像打开防篡改密封一样。RFC 6377 记录了这个问题,并向列表运营者和发件人提供了关于如何最小化损害的建议。

为什么存在这个问题

DKIM(RFC 6376)使用密码学哈希对电子邮件头和正文内容进行签名。签名后的任何修改都会使签名失效。邮件列表在设计上会在传输过程中修改邮件。这造成了根本性的矛盾:

当 DMARC 出现时(要求 DKIM 或 SPF 对齐),这种矛盾成为了可交付性危机。来自带有 p=reject DMARC 策略域的邮件发送到邮件列表时,开始对所有列表订阅者退件。RFC 6377 发布用来记录该问题并推荐缓解策略。

工作原理

邮件列表对邮件的修改

典型的邮件列表管理器(Mailman、Sympa、LISTSERV、Google Groups)可能执行以下任意组合的修改:

修改 破坏 DKIM? 详情
添加 List-* 头 仅当 h= 覆盖它们时 List-Unsubscribe、List-Id、List-Post 等
添加/修改主题前缀 是,如果主题已签名 例如 [列表名] 原始主题
添加正文页脚 是 附加取消订阅说明或免责声明
重写 From 头 是 将 From 改为列表地址(DMARC 缓解)
改变 Reply-To 仅当 Reply-To 已签名时 将 Reply-To 设置为列表地址
改变信封发件人 否(DKIM 签名头,不签名信封) 改变 MAIL FROM 用于退件处理
MIME 重构 是 包装在 multipart 中以添加文本页脚

签名验证流程

; 步骤 1:作者向列表发送 DKIM 签名邮件
From: alice@example.com
To: dev-list@lists.example.org
Subject: Proposed API change
DKIM-Signature: d=example.com; h=from:to:subject; ...

; 步骤 2:列表软件修改邮件
From: alice@example.com            ← 未改变(或已重写)
To: dev-list@lists.example.org
Subject: [dev] Proposed API change  ← 已修改:添加了前缀
List-Id: <dev-list.lists.example.org>  ← 已添加
DKIM-Signature: d=example.com; h=from:to:subject; ...

; 原始正文 + 附加页脚
The body text here...

--
To unsubscribe, visit https://lists.example.org/unsub  ← 已添加

; 步骤 3:收件人服务器验证 DKIM
; 结果:失败(主题和正文在签名后被修改)

列表运营者的推荐做法

RFC 6377 推荐邮件列表最小化修改以保留 DKIM 签名:

  1. 不要修改主题头。 避免加前缀 [列表名]。改用 List-Id 头 — 邮件客户端可以基于它进行筛选。
  2. 不要添加正文页脚。 如果需要页脚内容,使用 MIME 封装,或将页脚作为单独的 MIME 部分而不是追加到现有正文。
  3. 添加新的 DKIM 签名。 列表应使用自己的 DKIM 密钥(d=lists.example.org)对修改后的邮件进行签名。这不会修复原始签名,但提供了来自列表域的有效签名。
  4. 为 DMARC 考虑 From 重写。 当原始发件人的域发布 p=reject 时,将 From 头重写为列表域,并将原始发件人放在 Reply-To 中。这被广泛实现为"From 修改"。

发件人的推荐做法

  1. 使用宽松规范化。 使用 c=relaxed/relaxed 而非 c=simple/simple 进行签名。宽松规范化容许某些列表软件引入的轻微空白变化。
  2. 仅签名必要的头。 h= 标记应覆盖你关心的头(From、Subject、Date、To、Message-ID),但不包括列表常见添加的头(List-Id、List-Unsubscribe)。
  3. 谨慎使用 l= 正文长度标记。 l= 标记限制正文中有多少被签名,所以附加页脚不会破坏签名。但这有安全影响 — 攻击者可以在签名部分下方附加恶意内容。

关键技术细节

DMARC 的复杂性

RFC 6377 早于 DMARC(RFC 7489),但它描述的问题在 DMARC 部署后变得更加严重。使用 DMARC p=reject 时:

; 作者的域发布严格的 DMARC
_dmarc.example.com TXT "v=DMARC1; p=reject; ..."

; 邮件通过邮件列表,DKIM 破坏
; 收件人服务器检查 DMARC:
;   - SPF:失败(信封发件人是列表,不是 example.com)
;   - DKIM:失败(签名被列表修改破坏)
;   - DMARC:失败 → 拒绝
; 结果:邮件对所有列表订阅者退件

这就是为什么开发了 ARC(RFC 8617) — 在邮件列表等中介修改前保留身份验证结果。

ARC 作为现代解决方案

经过验证的接收链(ARC)协议让邮件列表等中介在修改邮件前记录原始身份验证结果。收件人的服务器之后可以使用 ARC 链恢复原始 DKIM/SPF 通过,即使列表已破坏原始签名。

From 重写策略

邮件列表最常见的 DMARC 缓解是 From 重写:

; 原始邮件
From: Alice Smith <alice@strict-dmarc.com>

; 列表 From 重写后
From: Alice Smith via Dev List <dev-list@lists.example.org>
Reply-To: Alice Smith <alice@strict-dmarc.com>

这在显示文本和 Reply-To 中保留原始发件人身份,同时使 From 域与列表的 DKIM 签名匹配。

常见错误

可交付性影响

Related RFCs