用 telnet 进行 SMTP 检查

一份手动测试邮件服务器的实用指南。了解每一条 SMTP 命令的作用、服务器如何应答,以及如何使用 telnet 或 openssl 运行一次完整的验证会话。

SMTP(简单邮件传输协议)是一种纯文本、基于行的协议。这意味着你可以直接从终端与邮件服务器对话,并精确地读出它的每一句回复 — 无需任何专门的软件。这是检查邮箱是否存在、服务器是否可达以及它是如何配置的最透明的方式。

1. 连接到邮件服务器

首先找到该域名的邮件服务器(MX 主机),然后向它的 SMTP 端口打开一个 TCP 连接。经典端口是 25。提交端口 5872525 配合 STARTTLS 使用;端口 465 则是隐式 TLS(SMTPS)。

普通连接(端口 25):

telnet mail.example.com 25

STARTTLS 端口(587 或 25)— telnet 无法处理 TLS,请使用 openssl:

openssl s_client -connect mail.example.com:587 -starttls smtp -crlf

隐式 TLS 端口(465):

openssl s_client -connect mail.example.com:465 -crlf

注意:许多家庭和移动 ISP 会封锁出站端口 25 以打击垃圾邮件。如果 telnet ... 25 只是一直挂起,那通常是你的网络服务商所致,而非邮件服务器的问题。请从一台端口 25 开放的服务器/VPS 上进行测试,或改用提交端口。

2. SMTP 命令详解

你输入命令(不区分大小写);服务器以一个 3 位数代码加文本作答。每条命令都以回车(CRLF)结束。

命令作用
HELO domain旧式问候。按名称标识发起连接的主机。服务器回复 250
EHLO domain现代问候(扩展版 HELO)。与 HELO 相同,但服务器还会列出所支持的扩展功能(STARTTLS、AUTH、SIZE、PIPELINING…)。
MAIL FROM:<addr>开始一封新邮件并设置信封发件人(即“回信路径”)。若被接受则回复 250
RCPT TO:<addr>用于验证的关键命令。请求服务器接受一个收件人。250 = 该邮箱被接受;550 = 无此用户;4xx = 稍后重试(例如灰名单)。
DATA开始邮件正文。服务器回复 354;你发送邮件头 + 正文,并以单独一行上的一个点号 . 结束。(对于验证检查而言,你永远不会走到这一步。)
RSET重置当前事务(清除 MAIL FROM / RCPT TO),但不关闭连接。
VRFY user请求服务器核实某个用户名/地址。本就是为此设计的,但如今几乎总是被禁用(返回 252502),因为它会把有效地址泄露给垃圾邮件发送者。
EXPN list请求服务器将一个邮件列表展开为其各个成员。与 VRFY 一样,出于同样的隐私原因而几乎到处都被禁用
STARTTLS将普通连接升级为加密的 TLS(在端口 25/587 上)。仅当 EHLO 回复中列出它时才可用。
AUTH LOGIN / PLAIN对用户进行身份验证(通过提交端口发送邮件时所需,而非用于验证)。
NOOP什么也不做;服务器回复 250。可用于保持连接活跃或测试响应能力。
HELP请求服务器列出它所支持的命令。
QUIT礼貌地结束会话。服务器回复 221 并关闭连接。

3. 响应代码

第一位数字会告诉你类别,因此即便你不知道确切的代码,也能读懂任何一条回复:

  • 2xx — 成功(命令被接受)。
  • 3xx — 中间状态,服务器需要更多输入(例如 DATA 之后的 354)。
  • 4xx — 临时失败:稍后再试。该地址仍可能是有效的。
  • 5xx — 永久失败:命令或地址被拒绝。
代码含义
220服务就绪(问候横幅)。
221正在关闭连接(对 QUIT 的回复)。
250OK — 命令被接受(你在 RCPT TO 之后想要的答复)。
251 / 252用户非本地但将被转发 / 无法核实但将尝试投递。
354开始发送邮件正文(在 DATA 之后)。
421服务不可用,正在关闭 — 通常是速率限制。
450 / 451 / 452临时问题(邮箱繁忙、本地错误、存储空间不足)。灰名单经常出现在这里。
502命令未实现(对 VRFY / EXPN 的典型回复)。
550邮箱不可用 / 无此用户 — 该地址不存在。
551 / 552 / 553 / 554用户非本地 / 超出配额 / 邮箱名称无效 / 事务失败。

4. 一个完整的实例演示

检查 john@example.com 是否存在。你输入的行用 > 标记;其余内容均为服务器的回复:

$ telnet mail.example.com 25 220 mail.example.com ESMTP ready > EHLO checkemail.test 250-mail.example.com Hello checkemail.test 250-STARTTLS 250-SIZE 52428800 250 PIPELINING > MAIL FROM:<probe@checkemail.test> 250 2.1.0 Ok > RCPT TO:<john@example.com> 250 2.1.5 Ok ← 邮箱存在 > RSET 250 2.0.0 Ok > QUIT 221 2.0.0 Bye

反之,如果该收件人不存在,你会看到类似这样的内容:

> RCPT TO:<nosuchuser@example.com> 550 5.1.1 <nosuchuser@example.com>: Recipient address rejected: User unknown

5. 会让结果变得不确定的因素

  • 灰名单(Greylisting) — 服务器会在第一次尝试时有意返回一个临时的 4xx,要求你稍后再来。一个 4xx 并不意味着该地址无效。
  • 全收域名(Catch-all) — 一些服务器会用 250 接受每一个收件人,之后再去分拣。这时 RCPT TO 就无法证明某个具体邮箱是否存在。要检测全收,可以尝试一个明显随机的地址:如果它也被接受,那么该域名就是全收的。
  • 反滥用防护 — 服务器可能会延迟、隐藏真实状态,或封锁来自同一 IP 的反复探测。请礼貌地测试,不要对一台服务器狂轰滥炸。
  • VRFY / EXPN 被禁用 — 不要依赖它们;RCPT TO 才是实用的信号。

想让这一切自动完成,包括 MX 查询、全收检测以及一个清晰的结论?请在首页使用我们的邮箱验证工具