网络

邮件头分析器

把一封邮件的原始邮件头贴进来,看清它实际经历了什么:途经的每一台服务器,以及每一跳花掉的时间;接收方当时对 SPF、DKIM、DMARC 得出的结论;还有 From、Return-Path、Reply-To 各自声称的身份是否一致。被编码成乱码的主题会一并还原,全部解析都在浏览器里完成,不上传。

  • Received 头还原成投递时间线,逐跳标出耗时
  • 逐项解读接收方写下的认证结果,并说明每种结论的含义
  • 对比 From、Return-Path、Reply-To,识别藏在显示名里的另一个地址
  • DKIM 签名按标签拆解,重点标出只签了部分正文的 l= 标签
  • 还原编码主题,兼容 Shift_JIS、GB2312、Big5 等旧字符集
0 字符

Gmail 选「显示原始邮件」,Outlook 打开「属性」或「查看邮件源」,Apple Mail 开启「全部标题」。

复制和下载时隐去邮箱名与地址末段,保留域名——认证问题要讨论的正是域名。

粘贴一段邮件头,即可看到投递路径、认证结果,以及这封邮件声称的身份。

功能简介

一段邮件头能回答三个问题:邮件走了哪条路、接收方怎么判断它、它自称是谁。下面每一节各答一个。

  1. 01

    路径,以及每一跳的耗时

    Received 头会被倒序还原成邮件实际走过的顺序,再把相邻两条的时间戳相减,那段卡了六分钟的排队就不再是隐形的。最慢的一跳会被单独标出——邮件为什么晚到,答案通常就在那里。

  2. 02

    认证结果不止照抄

    Authentication-Results 里的每一种方法都会连同结论一起解释清楚,包括软失败和失败的区别,以及「没有记录」和「验证没过」根本不是一回事。

  3. 03

    几个地址互相对照

    From、Return-Path、Reply-To、Sender 并排列出,藏在显示名里的另一个邮箱地址会被单独点名——大多数客户端只显示名字,这类伪造正是靠这一点生效的。

  4. 04

    DKIM 签名逐个标签拆开

    域名、selector、算法,以及被签名的头字段清单;其中两个标签最值得看:只签了正文开头一段的 l=,和压根没把 From 纳进来的 h=。

  5. 05

    编码主题当场还原

    写成 =?UTF-8?B? 那种形式的主题会当场解码,仍在流通的旧字符集也支持:Shift_JIS、GB2312、Big5、ISO-8859 系列。工单里那行乱码主题,多半就是这么来的。

  6. 06

    内容不出本页

    邮件头里往往带着收件人地址、内网主机名和私有地址段。解析全部在浏览器里完成,另有一个脱敏开关,复制或下载时会隐去邮箱名与地址末段。

如何使用

拿到原始邮件而不是渲染后的界面,粘贴进来,然后按顺序往下读。

  1. 01

    打开原始邮件:Gmail 用「显示原始邮件」,Outlook 用「属性」或「查看邮件源」,Apple Mail 开启「全部标题」。

  2. 02

    把整段内容贴进输入框。第一个空行之后是正文,会被忽略。

  3. 03

    先看结论和发现列表,它们会直接点出问题在哪,省得自己翻。

  4. 04

    再看认证结果,了解接收方当时的记录。先看最上面的普通 Authentication-Results,再根据 authserv-id 判断该邮件系统是否值得信任。

  5. 05

    沿投递路径从起点往下看,找出耗时集中在哪一跳。

  6. 06

    如果需要顺带核对某个签名域名的 DNS 记录,直接从签名卡片跳到 SPF DMARC 检测。

功能说明

读邮件头的难处,大多藏在那些看着像噪音的细节里。解析正是围绕这些情况做的。

  • 先做折行还原,一条被拆成五行的 Received 会被当作完整的一条读,而不是五个片段
  • 路径按倒序重建,因为服务器是把自己的 Received 加在最前面而不是最后
  • 某一跳的时间早于上一跳时,会报成时钟不同步,而不是显示一个负的耗时
  • 摘要使用最上面的普通 Authentication-Results,但会明确说明:决定其可信度的是 authserv-id,而不是它所处的位置
  • ARC 组单独计数,因为经过邮件列表的邮件被重新封装本来就是常态
  • 发送方地址取自方括号里的写法,避免把主机名或 TLS 注释里的数字误当成来源地址

适合哪些场景

会去翻邮件头,通常出于两种情形:该到的邮件晚了,或者不该到的邮件到了。

  1. 定位延迟卡在哪一段

    一封走了二十分钟的邮件,一定是在某个具体的地方等着。逐跳耗时会指出是哪台服务器扣住了它——这决定了该找发件方还是收件方。

  2. 判断可疑邮件是否名副其实

    显示名写着一家公司、地址却是另一家,或者 DMARC 直接失败。两者都能在几秒内看清,而在邮件客户端里一个都看不到。

  3. 弄清为什么进了垃圾箱

    过滤器一般会留下自己的理由:SpamAssassin 的得分和命中的规则,或者 Microsoft 的垃圾邮件可信度。据此才能判断该修认证还是修信誉。

  4. 确认自己的邮件签名正常

    给自己发一封,再读 DKIM 签名:由哪个域名签的、用的哪个 selector,以及 From 头到底在不在签名范围内。

  5. 解释转发邮件为何 DMARC 失败

    转发会破坏 SPF,邮件列表还常常破坏 DKIM。ARC 组和跳转列表会显示邮件在哪里被谁重新封装过。

  6. 还原成了乱码的主题

    显示成 =?UTF-8?B? 开头、或者在日志里变成一串问号的主题,都能在这里还原,包括老系统仍在使用的那些旧字符集。

  7. 把证据贴进工单又不泄露地址

    打开脱敏开关,邮箱名和地址末段会被隐去,域名保留,摘要可以直接贴进团队共用的跟踪系统。

  8. 带人上手读邮件头

    每条结论都附有它的实际含义,于是一封真有问题的邮件本身就成了教材,讲清 SPF、DKIM、DMARC 各自到底在断言什么。

延伸阅读

邮件头讲的是一封邮件的遭遇,而它背后的记录属于域名。要查看某个域名发布的 SPF、DKIM 与 DMARC,请用 SPF DMARC 检测。想直接查询任意记录类型,或者从根服务器往下追踪委派链,可以用 DNS 查询。想弄清第一条 Received 里那个地址属于谁的网络,可以用 IP 地址查询

使用建议

几个习惯能让读邮件头更快,也能让结论更站得住。

  • 要原始邮件,不要转发件。转发会重写邮件头,最后读到的是转发这一程,而不是你真正关心的那封。
  • 先看最上面的普通 Authentication-Results,但要核对其 authserv-id 是否属于你信任的邮件系统。更早的记录可以作为背景,不能当作独立证据。
  • 有数据时,比较 From 与接收方记录为 SPF 通过的身份。Return-Path 有参考价值,但不能代替 SPF 实际评估的身份。
  • 时间戳彼此矛盾时,逐跳耗时只能当参考。一台服务器的时钟不准,它前后的耗时就全都失去意义。
  • 看 DKIM 签名不能只看有没有,要看 h= 标签。没覆盖 From 的签名,保护力远不如它看上去那么强。
  • 往共用工单里贴邮件头之前先脱敏。邮箱名、内网主机名、私有地址段全都在里面。

边界与注意事项

这里的一切都来自你粘贴进来的文本。这给结论划出了明确的边界。

  • DKIM 签名只做解析,不做验签。验签需要未经改动的正文和 DNS 里的公钥,而且传输途中任何改动都会让一条本来完好的签名失效。
  • 认证结果是接收方的说法,不是独立复核。本页无法重新跑一遍 SPF 或 DMARC,只能如实转述接收服务器记下的结论。
  • 最后一跳可信服务器以下的邮件头都可能是伪造的。发信方写下的一切都由他们掌控,包括那些看起来很像真实经历的 Received 头。
  • 域名归属比对用的是完整的 Public Suffix List,它随页面一起下发,不需要查询。而 RFC 9989 改用 DNS tree walk 来确定 DMARC 的组织域,所以严格求值下个别域名的分组仍可能不一样。
  • 不做任何 DNS 查询。某个 selector 现在是否还在发布、某个发送地址是否真属于它声称的网络,都需要本页并不执行的查询。
  • 过滤器分数描述的是某一个接收方在某一天的判断。同一封邮件在别处可能得到不同分数,分数干净也不等于邮件安全。
  • 只读邮件头部分。第一个空行之后的内容,包括附件和正文里的追踪像素,一概不看。

常见问题

关于查看邮件头、追踪投递路径,以及一段邮件头能证明什么、不能证明什么的常见问题。

怎么查看邮件的原始邮件头?

Gmail 里打开邮件,点右上角三个点,选「显示原始邮件」。Outlook 网页版在三个点菜单里选「查看邮件源」;桌面版依次是「文件」「属性」,看「Internet 邮件头」那一栏。Apple Mail 在「显示」「邮件」里开启「全部标题」。把整段复制过来即可,整封原始邮件也行,第一个空行之后的内容会被忽略。

怎么通过邮件头判断邮件卡在了哪一段?

每台经手的服务器都会把 Received 头加在最前面,并记下自己收到邮件的时间,所以这份清单是倒着的。倒过来才是真实顺序,相邻两个时间戳之间的间隔,就是邮件等待被下一台服务器接收的时长。某一跳超过一分钟,延迟就在那里。不过要先看时钟:如果某台服务器时间设错了,它前后的耗时都没有意义——所以一旦某跳的时间早于上一跳,工具会直接报成时钟不同步,而不是给出一个负数。

邮件头可以伪造吗?

发件方自己写的字段都可以伪造,包括 From、Reply-To、Date,以及为了把路径显得更长而编造的 Received 头。邮件离开发件方控制后新增的头也只有在信任边界内才有证据价值:先看最上面的普通 Authentication-Results,再核对它的 authserv-id 是否属于你信任的邮件系统。更早的记录只是更早的断言,不是独立证据;如果链路起点就是恶意服务器,记录也可能不可信。

Authentication-Results 能告诉我什么?

它记录了接收服务器跑完 SPF、DKIM、DMARC 之后的结论。spf=pass 表示发送服务器获得了信封域名的授权;dkim=pass 表示某条签名验证通过,被签名的部分原样抵达;dmarc=pass 表示上述之一为一个与收件人所见 From 一致的域名通过了验证——正是这一步把认证和它声称的身份绑在一起。本工具会把每个结论连同它的实际含义一起展示,转述接收方的判断,而不是重新验证一遍。

SPF 明明通过了,DMARC 为什么还是失败?

因为 DMARC 还要求对齐。SPF 校验的是 Return-Path 里的信封发件人,而经第三方服务发信时,那通常是对方自有域名下的一个退信地址。于是 SPF 为服务商通过了,From 显示的却是你的域名,两者对不上,DMARC 照样失败。用自有域名做 DKIM 签名是更稳妥的一半,因为 DKIM 的对齐能挺过转发,SPF 不能。

DKIM 签名里的 l= 标签是什么?

它给正文规定了一个长度,签名只覆盖开头的 l 个字节。之后追加的内容照样验签通过,也就是说别人可以往一封已签名的邮件里续写内容。这个标签的初衷是让签名扛得住邮件列表在末尾追加的页脚,而这也正是工具要标出它的原因:一条只覆盖了正文中不确定比例的签名,说服力弱于覆盖全文的签名。

主题为什么显示成 =?UTF-8?B? 这样的乱码?

那是 RFC 2047 编码。邮件头字段只允许 ASCII,其他文字要用 base64 或 quoted-printable 编码,并在前面写明字符集。客户端会在显示前解码,所以编码形式只会出现在日志、工单或复制出来的邮件头里。本工具会把它还原,也支持老系统仍在使用的旧字符集:Shift_JIS、GB2312、Big5 以及 ISO-8859 系列。

能从邮件头里找到发件人的真实 IP 吗?

有时候可以。最下面那条 Received 记录了第一台接收服务器看到的地址,如果邮件是从邮件客户端发出的,那往往就是发件方所在的网络。但如果邮件来自网页版邮箱,这个地址属于服务商;而自建服务器的发件方可以随意编造更早的 Received 头。只有你信任的服务器所添加的那几跳才算证据,而其中的地址又常常是私有地址段,出了那个网络就什么也标识不了。

这个工具会上传我的邮件吗?

不会。解析全部在浏览器里完成,任何内容都不会发出去。这一点在这里比在多数工具上都更要紧,因为一段邮件头里通常有收件人地址、内网主机名、队列 ID 和私有地址段。工具另外提供脱敏开关,复制或下载时会隐去邮箱名和地址末段,方便把结果放进共用工单。

ARC 是什么,为什么我转发的邮件里有它?

转发会破坏认证:转发方不在原域名的授权列表里,SPF 就会失败;邮件列表还常常改写主题或追加页脚,把 DKIM 也一起破坏掉。ARC 让中转方把「改动之前我看到的结果」记下来并封存,最终接收方可以自行决定是否采信。出现多个 ARC 组,只是说明邮件经过了多个这样的中转方——凡是从邮件列表过来的邮件,本来就是这个样子。

显示名的那条警告是什么意思?

意思是地址前面那个名字本身包含了一个邮箱地址,而它并不是邮件的真实发件地址。由于大多数客户端只显示这个名字,一封邮件可以看起来来自某家银行,实际却发自一个毫不相干的邮箱。这是成本最低的一种伪造,不需要攻破任何基础设施,而且不去看原始 From 头就发现不了。

它和 SPF DMARC 检测有什么区别?

两者站在同一个问题的两端。检测工具读的是域名在 DNS 里发布了什么——SPF 链、DMARC 策略、DKIM 密钥,评判的是配置。本工具读的是一封已经送达的邮件,还原它实际经历了什么。配置域名时用前者,某封邮件出了问题时用后者。签名卡片上有跳转,在这里发现的签名域名,可以一键拿去那边核对。

更多相关工具

核对签名域名背后的记录,直接查询 DNS,或者弄清某个发送地址属于谁的网络。