为什么我们可以在中国用Gmail发邮件

许多网络服务在中国被禁已经很多年了。你不能访问诸如谷歌、推特等全球知名网站。然而,你有没有注意到尽管Gmail被禁了,我们仍可以用任意国内邮件服务提供商给Gmail邮箱发邮件。你有可能会认为服务商会有他们自己的海外代理服务器,这当然是可以的。然而在本文中,我们将发现没有代理服务器直接从计算机发邮件也是可以的。通过HTTP和SMTP的关系,其次是 DNS MX的记录,让我们通过对传送数据包的观察来看看这过程是怎么实现的。

TL;DR 特定的SMTP端口和DNS MX记录IP数据包绕过防火墙。

一个有趣的测试

让我们通过终端发送给Gmail,您可以使用您喜欢的任何邮件客户端。然而,只有在终端中,我们才可以发掘真正发生在数据包过滤器后面的部分。

$ mail im.longkai@gmail.com
Subject: Hello, Gmail
Bye.
.

注意最后的 . 跟着一个换行符, 结束了这封邮件(认为C是空结尾字符串).

接着登录你的gmail邮箱(如果你在中国,这一步操作需要网络代理). 发现收件箱是空的,但我们可以发现测试邮件在垃圾邮件箱里。

为什么我们可以在中国用Gmail发邮件0看看上面的发件人地址,形如 whoami@hostname.但是等等,为什么呢?开始的时候,我只是为了好玩用了 mail 命令,并没有实际的实现效果。我们提到过 Gmail 在中国访问不了吗?是什么堵塞了 HTTP 请求呢,没有 HTTP 我们怎么处理邮件和访问网页啊。

我想表达的是我并不知道 Google 的 IP 被屏蔽了。

HTTP 和网关

我们不会讨论太多关于 HTTP 已占领网络流量的问题。而多数的网络服务协议都是通过网关提供的,网关就像是不同协议之间的转换器一样。

通常这些组件在服务器上

+------+        +---------+        +--------------------------------------+
| HTTP | <----> | Gateway | <----> | other portocol(e.g. SMTP, FTP, etc.) |
+------+        +---------+        +--------------------------------------+

你可能会猜测,一个FTP网关将FTP转换为HTTP。 反之亦然,这同样适用于SMTP邮件传输协议。 得益于网关, 我们不需使用特定客户端来进行邮件操作(比如Thunderbird, Foxmail等客户端),仅仅使用一个浏览器就可以做所有事。

事实上,你甚至可以认为任何Web服务都是网关,因为它通过HTTP协议处理用户的请求并响应。顺便说一下, 邮件(即SMTP)比Web更古老(即HTTP). 很多Web技术是从邮件演变而来的(例如:Base64, 状态码, 动作模拟等等). 在网络的早期阶段,邮件是支配者!让我们专向SMTP。

SMTP

SMTP是邮件的信使(如果不将Http算入)。让我们快速说明,如果不介意的话可以跳过。

以下是使用TCP / IP协议SMTP的概述。

         +------------------+      +------------+      +- - - - - - -+      +-----+
sender   | user at terminal | ---> | user agent | ---> | mails queue | ---> | MTA | client
         +------------------+      +------------+      +- - - - - - -+      +-----+
                                                                               ↑   
                                                                               |  
                                                                           TCP | connection
                                                                               |  
                                                                               ↓  
                                                                            port 25
         +------------------+      +------------+      +- - - - - - -+      +-----+
receiver | user at terminal | <--- | user agent | <--- | mails queue | <--- | MTA | server
         +------------------+      +------------+      +- - - - - - -+      +-----+

用户使用网络代理, 有很多工具可以选择(我们像前面所述一样使用终端)。用TCP进行邮件交互是通过消息传输代理(MTA)。在前面的测试中MTA是邮件程序。在一个更实际的邮件交互中MTA是邮件服务提供商。好吧,我们对SMTP已经有了简单的了解。通过TCP连接,我们必须要知道目标IP地址才能发送TCP报文段。你可能已经知道,这是DNS的工作。

DNS

总的来说DNS记录着用户可读地址到数字地址的映射(域名到IP)。反之亦然.,因为我们只专注于邮件,我们可以在这一节中忽略其它类型的DNS记录。

MX 邮件交换记录主要用来传递邮件给 MTA 目的地。假设你的邮件接收者地址是 sb@somewhere,那么 MX 记录就会被转换成目标的 IP 地址。继续前面的例子,如果我们想发邮件给 sb@gmail.com, 我们需要知道 gmail.com 对应了什么 IP 地址,host 指令就可以用来干这事:

$ host -t mx gmail.com
gmail.com mail is handled by 5 gmail-smtp-in.l.google.com.
gmail.com mail is handled by 30 alt3.gmail-smtp-in.l.google.com.
gmail.com mail is handled by 40 alt4.gmail-smtp-in.l.google.com.
gmail.com mail is handled by 20 alt2.gmail-smtp-in.l.google.com.
gmail.com mail is handled by 10 alt1.gmail-smtp-in.l.google.com.

我们得到了 5 个 MX 记录,每一个都有一个数字,如果某一个失败后,将会尝试另外一个 MX 记录,而数字越低优先级越低。注意,所有的这些 MX 记录仍然是一些域名,会再执行一次 DNS 解析。假设首个记录尝试失败:

$ host gmail-smtp-in.l.google.com
gmail-smtp-in.l.google.com has address 173.194.72.26
gmail-smtp-in.l.google.com has IPv6 address 2404:6800:4008:c03::1a

假设我们的网络只支持 IPv4 (目前中国的确是这一个情况),上面的例子中 172.194.72.26 就是 MTA 的目标地址。

网络数据包分析

通过使用包过滤工具 tcpdump ,我们可以更深入的了解邮件是如何被发出的。如果你对这部分不感兴趣可以直接跳过。需要注意的是 DNS 数据包会被我们删除掉,因为它对这个讨论没有什么意义。

$ sudo tcpdump -ttt 'tcp and port 25'
1. 00:00:10.968900 IP 192.168.3.4.62782 > pa-in-f26.1e100.net.smtp: Flags [SEW], seq 970097501, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 683832749 ecr 0,sackOK,eol], length 0
2. 00:00:00.306718 IP pa-in-f26.1e100.net.smtp > 192.168.3.4.62782: Flags [S.], seq 4265338668, ack 970097502, win 42408, options [mss 1380,sackOK,TS val 317393941 ecr 683832749,nop,wscale 7], length 0
3. 00:00:00.000043 IP 192.168.3.4.62782 > pa-in-f26.1e100.net.smtp: Flags [.], ack 1, win 4104, options [nop,nop,TS val 683833055 ecr 317393941], length 0
4. 00:00:00.282773 IP pa-in-f26.1e100.net.smtp > 192.168.3.4.62782: Flags [S.], seq 4265338668, ack 970097502, win 42408, options [mss 1380,sackOK,TS val 317394241 ecr 683832749,nop,wscale 7], length 0
5. 00:00:00.000026 IP 192.168.3.4.62782 > pa-in-f26.1e100.net.smtp: Flags [.], ack 1, win 4104, options [nop,nop,TS val 683833337 ecr 317393941], length 0
6. 00:00:00.130656 IP pa-in-f26.1e100.net.smtp > 192.168.3.4.62782: Flags [P.], seq 1:56, ack 1, win 332, options [nop,nop,TS val 317394387 ecr 683833055], length 55: SMTP: 220 mx.google.com ESMTP h131si58727336pfc.282 - gsmtp
7. 00:00:00.000026 IP 192.168.3.4.62782 > pa-in-f26.1e100.net.smtp: Flags [.], ack 56, win 4102, options [nop,nop,TS val 683833467 ecr 317394387], length 0
8. 00:00:00.000074 IP 192.168.3.4.62782 > pa-in-f26.1e100.net.smtp: Flags [P.], seq 1:34, ack 56, win 4102, options [nop,nop,TS val 683833467 ecr 317394387], length 33: SMTP: EHLO longkais-MacBook-Pro.local
9. 00:00:00.307062 IP pa-in-f26.1e100.net.smtp > 192.168.3.4.62782: Flags [.], ack 34, win 332, options [nop,nop,TS val 317394659 ecr 683833467], length 0
10. 00:00:00.000003 IP pa-in-f26.1e100.net.smtp > 192.168.3.4.62782: Flags [.], ack 34, win 332, options [nop,nop,TS val 317394661 ecr 683833467], length 0
11. 00:00:00.000001 IP pa-in-f26.1e100.net.smtp > 192.168.3.4.62782: Flags [P.], seq 56:226, ack 34, win 332, options [nop,nop,TS val 317394662 ecr 683833467], length 170: SMTP: 250-mx.google.com at your service, [113.91.173.198]
12. 00:00:00.000044 IP 192.168.3.4.62782 > pa-in-f26.1e100.net.smtp: Flags [.], ack 226, win 4096, options [nop,nop,TS val 683833773 ecr 317394662], length 0
13. 00:00:00.000132 IP 192.168.3.4.62782 > pa-in-f26.1e100.net.smtp: Flags [P.], seq 34:129, ack 226, win 4096, options [nop,nop,TS val 683833773 ecr 317394662], length 95: SMTP: MAIL FROM:<longkai@longkais-MacBook-Pro.local> SIZE=380
14. 00:00:00.277097 IP pa-in-f26.1e100.net.smtp > 192.168.3.4.62782: Flags [P.], seq 226:270, ack 129, win 332, options [nop,nop,TS val 317394970 ecr 683833773], length 44: SMTP: 250 2.1.0 OK h131si58727336pfc.282 - gsmtp
15. 00:00:00.000046 IP 192.168.3.4.62782 > pa-in-f26.1e100.net.smtp: Flags [.], ack 270, win 4095, options [nop,nop,TS val 683834050 ecr 317394970], length 0
16. 00:00:00.166009 IP pa-in-f26.1e100.net.smtp > 192.168.3.4.62782: Flags [P.], seq 270:314, ack 129, win 332, options [nop,nop,TS val 317395136 ecr 683833773], length 44: SMTP: 250 2.1.5 OK h131si58727336pfc.282 - gsmtp
17. 00:00:00.000002 IP pa-in-f26.1e100.net.smtp > 192.168.3.4.62782: Flags [P.], seq 314:359, ack 129, win 332, options [nop,nop,TS val 317395136 ecr 683833773], length 45: SMTP: 354  Go ahead h131si58727336pfc.282 - gsmtp
18. 00:00:00.000044 IP 192.168.3.4.62782 > pa-in-f26.1e100.net.smtp: Flags [.], ack 314, win 4094, options [nop,nop,TS val 683834216 ecr 317395136], length 0
19. 00:00:00.000013 IP 192.168.3.4.62782 > pa-in-f26.1e100.net.smtp: Flags [.], ack 359, win 4094, options [nop,nop,TS val 683834216 ecr 317395136], length 0
20. 00:00:00.000102 IP 192.168.3.4.62782 > pa-in-f26.1e100.net.smtp: Flags [P.], seq 129:518, ack 359, win 4096, options [nop,nop,TS val 683834216 ecr 317395136], length 389: SMTP: Received: by longkais-MacBook-Pro.local (Postfix, from userid 501)
21. 00:00:00.375189 IP pa-in-f26.1e100.net.smtp > 192.168.3.4.62782: Flags [P.], seq 359:414, ack 518, win 340, options [nop,nop,TS val 317395434 ecr 683834216], length 55: SMTP: 250 2.0.0 OK 1474215814 h131si58727336pfc.282 - gsmtp
22. 00:00:00.000004 IP pa-in-f26.1e100.net.smtp > 192.168.3.4.62782: Flags [P.], seq 414:474, ack 518, win 340, options [nop,nop,TS val 317395436 ecr 683834216], length 60: SMTP: 221 2.0.0 closing connection h131si58727336pfc.282 - gsmtp
23. 00:00:00.000001 IP pa-in-f26.1e100.net.smtp > 192.168.3.4.62782: Flags [F.], seq 474, ack 518, win 340, options [nop,nop,TS val 317395436 ecr 683834216], length 0
24. 00:00:00.000041 IP 192.168.3.4.62782 > pa-in-f26.1e100.net.smtp: Flags [.], ack 414, win 4094, options [nop,nop,TS val 683834590 ecr 317395434], length 0
25. 00:00:00.000014 IP 192.168.3.4.62782 > pa-in-f26.1e100.net.smtp: Flags [.], ack 474, win 4092, options [nop,nop,TS val 683834590 ecr 317395436], length 0
26. 00:00:00.000007 IP 192.168.3.4.62782 > pa-in-f26.1e100.net.smtp: Flags [.], ack 475, win 4092, options [nop,nop,TS val 683834590 ecr 317395436], length 0
27. 00:00:00.020528 IP 192.168.3.4.62782 > pa-in-f26.1e100.net.smtp: Flags [F.], seq 518, ack 475, win 4096, options [nop,nop,TS val 683834610 ecr 317395436], length 0
28. 00:00:00.385736 IP pa-in-f26.1e100.net.smtp > 192.168.3.4.62782: Flags [.], ack 519, win 340, options [nop,nop,TS val 317395809 ecr 683834610], length 0

我们为每一行增加了行号以便阅读。192.168.3.4:62782pa-in-f26.1e100.net.smtp 是本地和远程的一对套接字。待会我们将看到远程域名所代表的意思。1 到 5 行是常规的 TCP 三次握手连接的建立,包含两个重发信息。第 6 行服务器响应码市 220 ,这是客户端需要的一个握手信息,第 7 行是客户端的应答信息。第 8 行客户端发起一个 EHLO 命令来标识自身为 longkais-MacBook-Pro.local, 第 9-10 行是 ACK(发生了一次重发)。紧接着第 11 行是服务器对第 8 行的回应,表明对客户端的兼容。

第 13 行客户端尝试使用其地址发送邮件,14 行服务器回应 250 2.1.0 Sender e-mail address ok.. 然后 15 行是客户端对 14 行的 ACK 确认。第 16 行服务器回应 250 2.1.5 Recipient e-mail address ok.。17 行服务器发送 354 Enter mail, end with CRLF.CRLF.遵循一些 ACK。20 行是客户端发送的邮件内容,服务器回应 250 2.0.0 Message accepted for delivery

最后 23-28 行是 TCP 连接的终止信息,注意这里没有重发的包。

这就是整个 SMTP 的工作流程。

什么是 1e100.net?

在前面使用 tcpdump 时我们并没有使用 -p 参数来显示数字地址,因此我们看到了服务器的主机和端口是 pa-in-f26.1e100.net.smtp.

SMTP 的默认端口是 25.比较有趣的是 1e100.net 域名,咋一看,这是一个正常的域名,但是在 Google 上搜索后发现:1e100.net 是 Google 公司的域名,用来标识其网络内部的服务器。遵 循标准的行业惯例,我们确保每个 IP 地址都有一个对应的主机名。2009年10月,我们开始使用一个单一的域名来识别所有 Google 产品的服务器,而不是使用不同的产品域名,例如 youtube.com、blogger.com 和 google.com 等。我们这样做有两个原因,首先是让事情保持简单,其二通过避免例如跨站点脚本攻击这种潜在的威胁来提升安全性。

多数典型的互联网用户不会访问 1e100.net 这个网站,但我们为其选择了一个 Google 风格的名字以防万一(1e100 是数字 1 的科学计数法)。你可以在 这里 找到。然后,为什么 1e100.net 会出现在 TCP 连接中呢,它在 DNS 记录中并不存在。我们通过 DNS 反向映射来找出答案:

$ host -t ptr 173.194.72.26
26.72.194.173.in-addr.arpa domain name pointer tf-in-f26.1e100.net.

看到 1e100.net 了吧? 尽管名字和 tcpdump 输出的不一样(如记录重试、DNS 负载均衡等),不过这已经可以完美解释上述问题了。

最后我们可以得出一个结论:由于 IP 和端口绕过了 GFW 防火墙,因此我们在中国可以发送邮件给 Gmail。

感谢

  • 很多网络相关的东西都可以通过 W. Richard Stevens 关于 TCP/IP 协议的经典文章来学习
  • 关于 SMTP 状态码信息请阅读 这里
  • Gmail 的背景图片是来自于官方 Gmail 网站

参考资料

感谢阅读。

本文文字及图片出自 coyee.com

余下全文(1/3)
分享这篇文章:

请关注我们:

共有 2 条讨论

  1. 请问 对这篇文章的反应是垃圾

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注