浅谈通过邮件头(Email Headers)识别伪造邮件

背景

这两周做一个发邮件的需求,一波三折,期间既尝试了公司内部的发邮件服务,也尝试了调用 Gmail 个人邮箱的 API 来发送。对邮件服务的原理因此就有些好奇,上网搜了一些相关信息,整理如下。

(多说一句:刚工作那会儿我干过类似的事儿,当时是在一个创业公司,我想从家里登录办公室的电脑,但公司没有固定公网 ip,于是我写了一个 Shell 脚本,检测到公司路由器公网 ip 变化了就发一封邮件给我。从路由器到服务器之间配置了端口转发。)

什么是邮件头(Email Headers)

正常收发邮件的普通用户,是看不到邮件头的。邮件应用会默认隐藏邮件头。

但邮件头很有用。你可能已经注意到,在发邮件时,from (发件人)字段是可以自行指定的,例如 Java 中是这样:

MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress("someone@somedomain"));

那么收信人怎么知道信中声称的发信人不是伪造的呢?这时候邮件头就派上用场了。

和数据包一样,邮件也不是直接从发件人那里发送到收件人那里的,而是在多个邮件传输代理(MTA,Mail Transfer Agent)中辗转数次,每一次都送到离收件人更近的 MTA 服务器上,最终送给收件人。

在这里插入图片描述
图片来源

这期间的每一个 MTA 都会在邮件上加上一个 Header,最终在收件人那里能看到所有这些 Header,即邮件头(Email Headers)。

如何获取邮件头

一版在网页邮箱中,都能找到展示邮件头的相应选项。

Gmail 示例:
在这里插入图片描述
在这里插入图片描述
点击 Show original 之后,就能看到原始邮件了,原始邮件中最靠前的部分就是邮件头。

再以我最常用的新浪邮箱为例:
在这里插入图片描述

分析邮件头

首先把邮件头(或者整个原始邮件)粘贴到 VS Code,选择语言为 Email。或者保存为 .eml 格式也行,VS Code 会自动识别:
在这里插入图片描述
这样就可以借助语法高亮,很清楚地识别邮件头的各个字段了。下面简单说几个常用的字段。

Header 是从下往上依次添加的,越靠下的部分越接近发件人,所以看的时候要从下往上依次看,弄清楚从发件人到收件人的链路。

Received

这是分析邮件头时最重要的一个字段。该字段告诉你邮件是如何一步一步经由各个 MTA 发到你手上的。

其中,每一次经由一个 MTA 都会加上一个 Received 字段,其中的 fromby 分别是发送的 MTA 和收取的 MTA。

例如:

Received: from rn2-txn-msbadger05101.apple.com (HELO rn2-txn-msbadger05101.apple.com)([17.111.110.85])
        by sina.com (10.71.8.23) with SMTP
        id 60E926D7000026EC; Sat, 10 Jul 2021 12:49:28 +0800 (CST)

其中,from rn2-txn-msbadger05101.apple.com (HELO rn2-txn-msbadger05101.apple.com)([17.111.110.85]) 这行是说邮件在这一步是从这个 MTA 发出的。你可以根据域名、ip 等信息判断,这的确是从苹果公司的服务器发出来的;

by sina.com (10.71.8.23) 则说明,邮件被新浪收到了。这的确是一封苹果公司发到我新浪邮箱的邮件。

SPF(Sender Policy Framework)

SPF 是用来帮助判断发件人是否伪造的。正常情况下,SPF 取值应为 Pass。例如:

Received-SPF: Pass (sina.com: SPF record at _spf-txn.apple.com designates 17.111.110.85 as permitted sender) identity=from;

DKIM(Domain Keys Identified Mail)

这也是用来帮助判断邮件发件人真实性的一个很重要的字段,可以简单理解为电子签名。DKIM 通常长这样:

DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=email.apple.com;
        s=email0517; t=1625892495;
        bh=mQkSp8cygTZ7zTrw7YuQofK1z6wuyCw6Yp1/eOBHFFc=;
        h=Date:From:To:Message-ID:Subject:Content-Type;
        b=Qis7zZOXz6vvVArRizpgnsJKO7iSUmeJ7QtEjeEQ5+4hv+KAEQCiPeyjcc6hqRrkJ
         RFYvYH5fQjIGXvGnXhWtjE4J5QrhGOPbRfn3Yp2mhdo+d+JfvJTF6Nx2tD56jgu756
         1+trUOezTshdsOv8XcXrGWBEag5mfPfTOjnfUy9W6Ec4wiEjFS0FYsl2e8eNOCi1Nu
         EzLmhu3c/VGo1WNz5WYeoTP3LAJ/UZlqsFVxFoBRxUtTNPwBn/aIqmmA4mZnjkSwpb
         gd2TCsweb3emVq+5ZfSrayemmyRNh/Yqobj1y21QGzrimlNKr4HmFG5ALQwo9DVT+F
         VIl1PvL1td2lg==

我最近在做发邮件需求时就踩到了一个坑,怀疑是跟 DKIM 相关。我们调用公司的邮件服务,往公司内部邮箱发,本来发的很正常,结果突然有一天就怎么也收不到邮件了。

我们前后排查了大大小小各种原因,折腾了好久,最后(隔了一两天吧)收到一封系统通知才知道:邮件被拦截了!而且甚至都没出现在垃圾箱中。后来我在公司邮箱的隔离所中,果然找到了丢失的邮件。

之前怎么也想不到,有的邮件根本到不了你的垃圾箱中,就已经被拦截了。

这两天我分析了一下我们当初发的邮件的邮件头,发现甚至连这个 DKIM 字段都没有!

也难怪会被判断为垃圾邮件,给拦截了呢。

  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值