模块一 · 应用层
电子邮件与 SMTP
一封邮件从发件人到收件人经过哪些服务?先区分提交、服务器之间转送和收件人访问,再看SMTP与邮件访问协议分别做什么。
本章要解决的问题:一封邮件从发件人到收件人经过哪些服务?先区分提交、服务器之间转送和收件人访问,再看SMTP与邮件访问协议分别做什么。
本章的证据来源:概念讲法参考教材§2.3,纸书76–81页(PDF95–100页),具体出处见章末。旧稿的命令与数值属于历史转述,相关附件未随当前项目提供,本次没有重新采集或运行原实验;模型计算、协议规则与观察不能互相替代。
先从一个例子理解概念
你给朋友发一封邮件:邮件客户端把它交给发送侧服务器,服务器再把它送到接收侧,朋友最后取出阅读。先区分发送和读取,再看协议细节。
邮件客户端与邮件服务器
邮件客户端是你写信、读信的软件;邮件服务器处理收发和保存等服务。它们不是同一个角色,客户端之间通常不是直接用SMTP把信投给对方。
提交、转送与访问
提交是客户端把待发送邮件交给服务;转送是服务器之间传递邮件;访问是收件人读取自己的邮件。SMTP主要处理发送,读取可使用其他访问协议。
先看方向:邮件是「推」,网页是「拉」
《HTTP》中的基本请求/响应例子是客户端主动请求,服务器作答。这里比较消息的基本方向,不意味着HTTP服务不能在已建立的交互中持续发送事件等内容。
SMTP在服务器间传送邮件时采用发送方主动提交的方式;收件人访问邮件又是另一个环节,可以通过IMAP、POP3或Web界面等读取。不能说整个邮件系统没有“拉取”。
这个方向差别带来两个后果:
- 需要一套"投递"协议 —— 负责把邮件从一台服务器送到另一台。这就是 SMTP。
- 还需要一套"取回"协议 —— 因为你的电脑不是服务器,邮件到了服务器之后,你得把它取下来看。
所以邮件系统里有至少两套协议,分别管"投递"和"取回"。
一条邮件走过的路
发件人 发件人的邮件服务器 收件人的邮件服务器 收件人
(用户代理) (发送方) (接收方) (用户代理)
①写邮件并提交 ──→ ②SMTP 投递 ──────────────→ ③存进收件人的信箱
↓
④取回(POP3 / IMAP / 或网页界面) ←── 收件人主动拉取四步里有三套不同的协议:
| 步骤 | 协议 | 方向 |
|---|---|---|
| ① 用户代理 → 发送方服务器 | SMTP(或厂商私有接口) | 推送 |
| ② 发送方服务器 → 接收方服务器 | SMTP | 推送 |
| ③ 存入信箱 | 服务器内部操作 | — |
| ④ 接收方服务器 ← 用户代理 | POP3 / IMAP / HTTP | 拉取 |
注意 ① 和 ② 用的是同一套协议(SMTP) —— 也就是说,SMTP 既管"从你的电脑发到服务器",也管"从你的服务器发到对方服务器"。
而 ④ 一定要用另一套协议,因为 SMTP 只会"推",没法"取"。
收件人服务器怎么找到:MX 记录
回到第 1 模块那个问题:域名怎么变成地址? 网页用 A 记录,邮件用 MX 记录。
实测(本机查询,2026-10-13):
| 域名 | 优先级 | 邮件服务器 |
|---|---|---|
gmail.com | 20 | alt2.gmail-smtp-in.l.google.com |
gmail.com | 30 | alt3.gmail-smtp-in.l.google.com |
gmail.com | 40 | alt4.gmail-smtp-in.l.google.com |
qq.com | 10 | mx3.qq.com |
qq.com | 20 | mx2.qq.com |
qq.com | 30 | mx1.qq.com |
outlook.com | 5 | outlook-com.olc.protection.outlook.com |
这里有个容易搞反的地方:优先级的数字越小,越优先。
看 qq.com:mx3 的优先级是 10,mx2 是 20,mx1 是 30 —— 名字里的数字顺序和优先级顺序是反的,实际会先试 mx3。
为什么要配多个 MX? 冗余。第一个连不上就自动试第二个。这也是为什么大厂的 MX 记录里能一次看到好几台服务器(gmail 有三台 alt)。
实测:SMTP 会话在本机走不通,而这个"走不通"本身很有价值
SMTP 是基于文本的协议,会话过程可以直接用 socket 手工完成:
服务器 → 客户端:220 smtp.example.com ESMTP ready ← banner
客户端 → 服务器:EHLO myhost.local
服务器 → 客户端:250-smtp.example.com ... ← 表示支持的扩展
客户端 → 服务器:MAIL FROM:<a@b.com>
...先测端口可达性(本机实测):
smtp.qq.com:25 可达
smtp.qq.com:465 可达
smtp.qq.com:587 可达看起来三个端口都能连。但真做一次 SMTP 对话时:
=== smtp.qq.com:25 ===
banner: (空)
EHLO 回复首行: (空)
=== smtp.qq.com:587 ===
banner: (空)
=== smtp.163.com:25 ===
banner: (空)TCP 连接建立成功,但一个字节都没有收到。
这不是 SMTP 有问题,而是《封装与解封装》那一章讲过的旧现象在新场景里又出现了一次:本机流量由 TUN 代理接管,代理会在本地先替对端完成 TCP 握手。所以 Test-NetConnection 说"可达",但那个"可达"是代理给的,不是真的连上了邮件服务器。
实测:这个环境查不了 TXT 记录
SPF 和 DMARC 这两种邮件安全机制都是放在 TXT 记录里的。本机查询的结果:
Resolve-DnsName cloudflare.com -Type TXT
→ 异常: cloudflare.com : DNS server failure
nslookup -type=TXT cloudflare.com
→ *** UnKnown can't find cloudflare.com: Server failed
→ Server: UnKnown Address: 198.18.0.2A 记录和 MX 记录能查到,TXT 记录直接失败。
指定公共 DNS(-Server 8.8.8.8)也一样失败 —— 因为第 1 模块实测过:查询会被 TUN 截获,你以为换了 DNS 服务器,其实查询根本没出门。
邮件报文:比 HTTP 报文更老的一套格式
邮件正文的格式和 HTTP 报文结构相似:若干头部字段 + 空行 + 正文。
关键头部字段(这是邮件能被正确投递和显示的基础):
| 字段 | 作用 |
|---|---|
From | 发件人地址 |
To | 收件人地址 |
Subject | 主题 |
Date | 发送时间 |
Message-ID | 这封邮件的唯一编号 |
Content-Type | 正文是什么类型(纯文本 / HTML / 附件) |
注意 From 是可以随便写的。 这一点很重要:SMTP 本身没有任何发件人认证机制 —— 你可以声称自己是任何人。这就是垃圾邮件的根源。
针对这个问题的补救措施:
| 机制 | 原理 | 局限 |
|---|---|---|
| SPF | 域名在 DNS 里声明"哪些服务器有权用我的域名发信" | 接收方要主动去查 TXT,且转发会破坏它 |
| DKIM | 发信服务器用私钥给邮件签名,收信方用 DNS 里的公钥验证 | 需要发信方配置 |
| DMARC | 告诉接收方"SPF/DKIM 都不过时该怎么处理",并要求报告 | 部署率仍不完整 |
这三个机制都建立在"DNS 记录可信"这个前提上 —— 而 DNS 本身还有自己的安全问题(《网络安全》模块会讲 DNSSEC)。
收信:为什么需要 POP3 和 IMAP
邮件到了你的服务器,还要取回本地。两个老牌协议和一个现代做法:
| 方式 | 行为 | 特点 |
|---|---|---|
| POP3 | 把邮件下载下来,通常从服务器删除 | 简单;但换设备就看不到了 |
| IMAP | 邮件留在服务器,本地只是看一个副本 | 支持多设备同步、文件夹、已读状态 |
| 网页界面 / HTTP 接口 | 通过浏览器或 App 访问服务器上的信箱 | 现在的主流;本质还是"拉" |
IMAP 基本取代了 POP3,原因就是多设备:你现在可能同时用手机、电脑、网页看同一个邮箱,状态必须存在服务器上。
常见误解
误解一:「发邮件和收邮件用的是同一个协议」
不是。 发信用 SMTP(推),收信用 POP3/IMAP/网页接口(拉)。SMTP 只会推,不能用来取信 —— 这也是为什么邮件客户端要同时配置"发信服务器"和"收信服务器"两套地址。
误解二:「MX 记录里优先级数字大的更优先」
恰好相反:数字越小越优先。 本机实测的 qq.com 里 mx3 优先级 10、mx1 优先级 30,实际会先试 mx3。名字里的编号容易让人搞反。
误解三:「能连上邮件服务器的端口就说明能发信」
不成立,本机就是反例:Test-NetConnection 报三个端口全部"可达",但真做 SMTP 会话时连 banner 都收不到。原因是有代理在本地替对端握了手。判断协议通不通,必须把会话跑完一轮。
误解四:「邮件地址可以证明发件人是谁」
不能。 SMTP 没有认证机制,From 字段可以随便填。真正的身份验证要靠 SPF/DKIM/DMARC 这一套,而且它们也不是万无一失 —— 所以钓鱼邮件至今仍然有效。
误解五:「邮件是端到端直接送到对方电脑的」
不是。 邮件先到你自己的服务器,再到对方的服务器,在你和对方之间永远隔着至少两台服务器。而且这两台服务器会把邮件以明文存在磁盘上(除非用了端到端加密),这也意味着服务商在技术上能看到你的邮件内容。
本章小结
| 结论 | 类型 |
|---|---|
| 邮件是「推」模型,HTTP 是「拉」模型,方向差别决定了协议不同 | 标准 |
| 发信用 SMTP(推),收信用 POP3/IMAP/HTTP(拉) | 标准 |
| 邮件服务器靠 DNS 的 MX 记录定位 | 标准 |
| MX 优先级数字越小越优先;配多条用于冗余 | 标准 |
实测:gmail.com 三条 MX 优先级 20/30/40;qq.com 为 10/20/30 | 实测(历史观察,2026-10-13) |
实测:smtp.qq.com 的 25/465/587 端口 TCP 连接均成功 | 实测 |
| 实测:真做 SMTP 会话时收不到 banner,说明上面的"可达"是代理造成的假象 | 实测 |
| 实测:本机环境 TXT 记录查询失败(DNS server failure),指定 8.8.8.8 也无效 | 实测 |
| 由实测推断:该环境无法验证 SPF/DMARC,因为二者依赖 TXT | 判断 |
SMTP 没有发件人认证,From 可伪造,这是垃圾邮件的根源 | 标准 |
| SPF/DKIM/DMARC 是基于 DNS 的补救机制,各有局限 | 标准 |
自测题
6 题 · 先自己答,再展开对照
为什么邮件系统需要两套协议,而网页只需要一套?
因为方向不同。 网页是拉模型:客户端主动请求,服务器被动响应,一套 HTTP 就涵盖了。邮件是推模型:需要一套协议把邮件从一台服务器送到另一台(SMTP),而邮件到了你的服务器之后,还需要另一套协议让你把它取回本地(POP3/IMAP/HTTP)。SMTP 只能推不能取,所以必须有第二套。example.com的 MX 记录里有优先级 10 和 20 两台服务器。发信时会先试哪一台?先试优先级 10 的那一台(数字越小越优先)。失败再试 20。多个 MX 的作用就是冗余 —— 第一台连不上时自动切换。本机实测
smtp.qq.com:25显示"可达",但真发 SMTP 命令时收不到任何回应。可能是什么原因?因为本机有 TUN 代理,它在本地先替对端完成了 TCP 握手。 所以Test-NetConnection看到的是"代理接受了连接",而不是"邮件服务器接受了连接"。真做协议会话时,代理并没有真的连出去,于是拿不到任何数据。这正是"连接成功 ≠ 服务可用"的又一个实例。SPF 记录放在哪种 DNS 记录里?为什么本机查不到?
放在 TXT 记录里。 本机查不到是因为代理的 DNS 只支持部分记录类型 —— 实测 A 和 MX 能查到,TXT 直接返回DNS server failure,而且指定公共 DNS(8.8.8.8)也没用,因为查询会被 TUN 截获。所以在这个环境里 SPF/DMARC 无法验证。POP3 和 IMAP 的关键区别是什么?为什么现在 IMAP 更常用?
POP3 把邮件下载到本地(通常从服务器删除),IMAP 把邮件留在服务器上、本地只是副本。
IMAP 更常用的原因是多设备:现在你可能同时用手机、电脑和网页访问同一个邮箱,已读状态、文件夹、草稿都必须存在服务器上才能同步。POP3 那个"下载即删除"的模型在多设备场景下是灾难。收到一封邮件,
From是ceo@yourbank.com。能据此认为它真的来自那家银行吗?不能。 SMTP 协议没有任何发件人认证机制,From字段可以随便写。要判断真伪,得看:
- SPF:发信服务器的 IP 是否在该域名声明的授权列表里
- DKIM:邮件上的数字签名能否用 DNS 里的公钥验证通过
- DMARC:以上两者失败时,域名的策略是什么
而且即使这三个都通过,也只能说明"发信服务器有权用这个域名",不代表内容可信 —— 钓鱼邮件完全可以合法地从一个被入侵的授权服务器发出。
参考资料与适用范围
- 《计算机网络:自顶向下方法(原书第8版)》§2.3,纸书76–81页(PDF95–100页):本章概念与机制的对应教学章节,引用时需保留模型与版本条件。
- 教材作者配套教学资源入口:网站目前显示的教材版本与用户提供的第8版可能不同,页码以本章列出的中文第8版为准。
修订核对日期:2026-10-13。本次补充概念入口与教材出处;旧稿的具体数值为历史观察,未重新实测。相关脚本和完整日志未随当前项目提供,不能仅凭转述断言实验已复核,也不据此断言数据造假。