薛定谔的电子邮件
摘要
文章详细介绍了作者因SPF、DKIM、DMARC等认证协议导致的电子邮件转发挑战,并描述了使用Outlook规则和Cloudflare服务等工具解决该问题的各种尝试。
<p>追踪我处理失败电子邮件重定向的过程。</p>
<p><a href="https://lobste.rs/s/qtsnvd/schrodinger_email">评论</a></p>
查看缓存全文
缓存时间: 2026/08/22 11:06
# 薛定谔的邮箱:https://yashgarg.dev/posts/the-schrodinger-email/
目录
- 1. [问题所在](#the-problem)
- 2. [尝试 #1 —— Outlook 规则](#attempt-1---outlook-rule)
- 2.1. [第一个线索](#the-first-clue)
- 2.2. [身份验证相关](#the-authentication-stuff)
- 2.3. [原始邮件本身没问题](#the-original-email-was-fine)
- 3. [尝试 #2 —— 添加 @outlook.com 别名](#attempt-2--add-an-outlookcom-alias)
- 4. [尝试 #3 —— Cloudflare 邮件路由](#attempt-3--cloudflare-email-routing)
- 5. [尝试 #4 —— Email Worker](#attempt-4--email-worker)
- 6. [最终解决方案](#the-final-solution)
邮件能有多难?我曾经也这么想。大错特错。这篇文章基本就是我在邮件基础设施上瞎折腾并自食其果的记录。
## 问题所在
作为一个拥有多张信用卡的人(别评判!)—— 我喜欢使用像 [CRED](https://cred.club/) 或 [Fold](https://fold.money/) 这样的应用在一个地方追踪它们。这些应用经常要求访问邮箱以读取账单,而我不想授予它们对我邮箱的完全访问权限。因此,我有一个单独的邮箱地址,通过[邮件规则](https://support.microsoft.com/en-us/outlook/mail/manage-email-messages-by-using-rules-in-outlook)来转发邮件。但问题在于,*转发*操作会移除原始发件人信息,也就是银行的信息,而我希望保留所有这些信息。理想情况下,这一切应该能正常运行,我也不用写这篇文章了 :P
## 尝试 #1 —— Outlook 规则
我创建了一个规则,用于*将任何邮件重定向到我的 Gmail 地址*以进行测试。规则本身是有效的,但没有任何状态指示,所以你无法判断它是否失败?用户体验太差了。幸运的是,Gmail 的[邮件管理员](https://en.wikipedia.org/wiki/Postmaster_(computing))会发送一个通知,说明重定向失败,原因是:**“Gmail 检测到此消息可能可疑,因为发送域的信誉非常低。”** 这是一个硬性的 [SMTP](https://en.wikipedia.org/wiki/Simple_Mail_Transfer_Protocol) 拒绝,事情正是从这里开始变得有趣的。
### 第一个线索
原始的测试邮件是从 Gmail 发送到 Outlook 的。当 Outlook 接收它时,身份验证结果完全正常:
```
SPF: PASS
DKIM: PASS
DMARC: PASS
```
为什么当 Outlook 试图转发时,Gmail 会拒绝它?重要的细节是**邮件转发会创建另一个 SMTP 投递**。所以,流程本质上是:第一跳完成的身份验证并不意味着第二跳会被自动接受。
### 身份验证相关
那么 [SPF](https://en.wikipedia.org/wiki/Sender_Policy_Framework)、[DKIM](https://en.wikipedia.org/wiki/DomainKeys_Identified_Mail) 和 [DMARC](https://en.wikipedia.org/wiki/DMARC) 到底与此有何关系?这些是标准的电子邮件身份验证协议,用于验证邮件来源,并帮助防止欺骗和滥用。
#### 发送方策略框架 (SPF)
SPF 基本上解决的问题是:
> **这台服务器是否被允许代表此域名发送邮件?**
如果 `example.com` 通过其自己的邮件服务器发送电子邮件,SPF 可以验证这些服务器是否被授权。但转发改变了投递消息的服务器。原始消息可能来自 Google 的基础设施。经过 Outlook 重定向后:Gmail 现在是从 Microsoft 的基础设施而非原始发件人的基础设施接收消息。这会使 SPF 变得复杂。
#### 域名密钥识别邮件 (DKIM)
DKIM 的工作方式不同。原始发件人可以对消息进行密码学签名。只要转发系统不修改消息的签名部分,该签名就可以在转发中保留。这是 DKIM 对于转发邮件特别重要的一个原因。
#### 基于域的消息认证、报告与合规性 (DMARC)
DMARC 将身份验证结果与可见的 `From:` 地址中的域名关联起来。该策略作为 DNS TXT 记录发布在 `_dmarc` 下:
```
_dmarc.example.com TXT "v=DMARC1; p=reject"
```
这里,`p=reject` 告诉接收邮件服务器拒绝未通过该域 DMARC 策略的消息。因此,转发可能造成以下几方面的不匹配:
- 最初发送消息的实体,
- 现在传输该消息的实体,
- 以及消息声称来自的域名。
存在像 [ARC](https://en.wikipedia.org/wiki/Authenticated_Received_Chain) 这样的机制,可以在转发跳之间保留身份验证信息,但接收邮件服务器仍然会做出自己的投递决策。而且,Gmail 不仅查看 SPF/DKIM/DMARC。它还有反垃圾邮件和信誉系统来防止滥用。
### 原始邮件本身没问题
查看测试消息的邮件头,Outlook 已成功验证了原始的 Gmail 消息:
```
spf=pass
dkim=pass
dmarc=pass
```
所以第一跳是正常的。失败发生在 Outlook 的转发引擎尝试第二跳时。邮件头给了我另一个线索:
```
Resent-From: auto-submitted: auto-generated
x-ms-exchange-generated-message-source: Mailbox Rules Agent
```
换句话说,这不是我手动发送的另一封邮件。**是 Outlook 的邮箱规则代理生成了这次重定向投递。**
我发现微软本应在这个问题在2024年得到修复?微软已经[记录](https://support.microsoft.com/en-US/Support/known-issues/fixes-or-workarounds-for-recent-issues-on-outlook-com)了涉及国家/地区域名地址和 Gmail 因本质上相同错误而拒绝消息的问题。记录的解决方法是添加一个 `@outlook.com` 别名。于是我为同一个 Microsoft 帐户添加了一个 `[email protected]` 的别名。我还将 `@outlook.com` 地址设置为主别名,而不是 `@outlook.in`。然后我再次运行了完全相同的重定向测试。**它仍然失败了**,因为重定向消息的邮件头仍然包含:
```
Resent-From:
x-ms-exchange-generated-message-source: Mailbox Rules Agent
```
新的 `@outlook.com` 别名并未改变自动重定向所使用的身份。因此,别名解决方法对于这个特定的重定向路径没有帮助。
## 尝试 #3 —— Cloudflare 邮件路由
好吧。如果 Outlook 不想直接投递到 Gmail,也许我可以在中间加入另一层[邮件路由](https://www.cloudflare.com/products/email-routing/)。我设置了路由规则,比如将 `[email protected]` 的邮件转发到 Gmail。这个想法是让 Cloudflare 来处理转发,而不是让 Outlook 直接将重定向消息投递到 Gmail。
不幸的是,这也没有解决问题。增加一层转发本身并不能解决邮件跨越多个 SMTP 跳时可能发生的身份验证和信誉问题。
此时,我的邮件架构开始看起来像这样:(此处省略架构图)
不用说,这也没用。
## 尝试 #4 —— Email Worker
我在想,与其直接重定向到我的 Gmail 地址,如果我使用 `[email protected]` 并通过一个 [Email Worker](https://developers.cloudflare.com/email-service/api/route-emails/email-handler/) 进行路由,然后由我自己转发消息呢?代码可以很简单,像这样:
```javascript
export default {
async email(message, env, ctx) {
console.log("From:", message.from);
console.log("To:", message.to);
await message.forward("[email protected]");
},
};
```
这个想法是,我将消息接收到我的 Worker 中,然后完全控制它的后续处理。但我没有意识到,Cloudflare 会在消息到达 Worker **之前**执行其身份验证检查。如果入站邮件未通过这些检查,它就会在有机会运行我的代码之前被拒绝。
> Cloudflare 对传入邮件执行 SPF、DKIM、DMARC 和 ARC 检查。根据发件人的 DMARC 策略,未通过身份验证的消息将被拒绝。
就这样,我最后的希望也破灭了。
## 最终解决方案
我做了我非常不想做的事情。我手动将所有**与银行相关的邮件**从 Outlook 移到了我的 Gmail 地址。这并非我真正想要的优雅解决方案,但经历这一切之后,它比与邮件基础设施斗争要简单得多。我在这上面花了比预期更多的时间,但无论如何,完成了。
下次再见! 👋
相似文章
电子邮件的未来
Fastmail探讨了AI驱动的邮件过滤和助手如何使邮件认证标准(SPF、DKIM、DMARC)成为防止伪造和网络钓鱼的关键基础设施。
电子邮件加密
本文追溯了电子邮件从其去中心化、基于信任的起源到现代安全问题的历史,解释了SMTP和MIME等协议是如何作为技术限制的变通方案而出现的,但这使电子邮件容易受到窃听和篡改。
从自有可路由IPv4块起步的硬核自托管邮件
一份关于使用专属IPv4块自托管邮箱的详细技术指南,涵盖信誉管理、SPF、DKIM、DMARC以及使用Dovecot和Roundcube等工具的服务器设置。
自建电子邮件持续急剧下降
过去十年的DNS测量显示,电子邮件基础设施正围绕两大提供商整合,DMARC实施趋于平稳,且存在庞大的长尾基础设施,引发了对弹性的担忧。
DMARC 保护您免受哪些威胁,以及它无法保护什么
解释 DMARC 实际保护的内容,阐明其相对于 SPF 和 DKIM 的狭窄范围,以及为何它不是垃圾邮件或网络钓鱼过滤器。