如何验证 Email 地址:SMTP 协议入门教程

作者: 阮一峰

日期: 2017年6月25日

珠峰培训

Email 是最常用的用户识别手段。

开发者常常需要验证邮箱的真实性。一般的方法是,注册时向该邮箱发出一封验证邮件,要求用户点击邮件里面的链接。

但是很多时候(比如要搞邮件营销时),拿到的是成千上万现成的 Email 地址,不可能通过回复确认真实性,这时该怎么办呢?

答案就是使用 SMTP 协议。本文将介绍如何通过该协议验证邮箱的真假。

另外,结尾处还有一则移动端 H5 开发的培训消息,欢迎关注。

一、SMTP 协议简介

SMTP 是"简单邮件传输协议"(Simple Mail Transfer Protocol)的缩写,基于 TCP 协议,用来发送电子邮件。

只要运行了该协议的服务器端(daemon),当前服务器就变为邮件服务器,可以接收电子邮件。

验证 Email 邮箱的基本思路如下。

  1. 找到邮箱所在域名的 SMTP 服务器
  2. 连接该服务器
  3. 询问有没有该邮箱
  4. 如果服务器返回 250 或 251 状态码,邮箱就是真的;如果返回 5xx(500~599),就是假的。

注意,即使服务器确认邮箱是真的, 也不代表邮件一定会发送到该邮箱,更不代表用户一定会读到该邮件。

二、查找域名的 MX 记录

下面通过一个例子,演示如何验证test@gmail.com这个邮箱。

首先,需要查找gmail.com 的 MX 记录。它指向真正处理邮件的那台服务器。


$ nslookup
> 

输入nslookup命令后,会提示一个大于号,表示等待用户进一步输入。


> set q=mx
> gmail.com

上面代码中,set q=mx设定查询的是 MX 记录,第二行输入要查找的域名,结果返回了5条 MX 记录。


Server:     192.168.1.1
Address:    192.168.1.1#53

Non-authoritative answer:
gmail.com   mail exchanger = 20 alt2.gmail-smtp-in.l.google.com.
gmail.com   mail exchanger = 30 alt3.gmail-smtp-in.l.google.com.
gmail.com   mail exchanger = 10 alt1.gmail-smtp-in.l.google.com.
gmail.com   mail exchanger = 5 gmail-smtp-in.l.google.com.
gmail.com   mail exchanger = 40 alt4.gmail-smtp-in.l.google.com.

gmail.com是很大的邮件服务商,所以会有多条记录,一般的域名只有一条。如果这一步查不到 MX 记录,该邮箱肯定是假的。

除了自己执行nslookup,也可以使用线上服务(123)。更多 DNS 的介绍,请参考《DNS 原理入门》

三、建立 TCP 连接

知道了邮件服务器的地址,就可以与它建立 TCP 连接了。SMTP 协议的默认端口是25。使用 Telnet 或 Netcat 命令,都可以连接该端口。


$ telnet gmail-smtp-in.l.google.com 25
# 或者
$ nc gmail-smtp-in.l.google.com 25

服务器返回220状态码,就表示连接成功。


220 mx.google.com ESMTP f14si7006176pln.607 - gsmtp

接下来,就可以使用 SMTP 协议的各种命令与邮件服务器交互了。

四、HELO 命令和 EHLO 命令

SMTP 协议规定,连接成功后,必须向邮件服务器提供连接的域名,也就是邮件将从哪台服务器发来。

假定从mail@example.comtest@gmail.com发送邮件,这里要提供的域名就是example.com


HELO exampl.com

邮件服务器返回状态码250,表示响应成功。


250 mx.google.com at your service

不过,HELO命令现在比较少用,一般都使用EHLO命令。


EHLO example.com

邮件服务器收到EHLO命令以后,不仅会返回250状态码,还会返回自己支持的各种扩展的列表。


250-mx.google.com at your service, [114.84.160.153]
250-SIZE 157286400
250-8BITMIME
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-CHUNKING
250 SMTPUTF8

五、MAIL FROM 命令

然后,连接者要使用MAIL FROM命令,向邮件服务器提供邮件的来源邮箱。


MAIL FROM:<mail@example.com>

上面代码表示,连接者将从mail@example.com向邮件服务器发送邮件。邮件服务器返回250状态码,表示响应成功。


250 2.1.0 OK h10si3194349otb.59 - gsmtp

SMTP 是一个很简单的协议,本身没有规定如何验证邮件的来源,也就是说,不验证邮件是否真的从mail@example.com发来,所以导致了后来垃圾邮件泛滥。为了控制垃圾邮件,许多邮件服务器会用自己的方法验证邮件地址,下面就是其中的一些方法。

  • example.com 是否有 MX 记录
  • example.com 是否可以 Ping 通
  • 是否存在 postmaster@example.com 这个邮箱
  • 发起连接的 IP 地址是否在黑名单之中
  • IP 地址的反向 DNS 解析,是否指向一个邮件服务器

六、RCPT TO 命令

最后一步就是使用RCPT TO命令,验证邮件地址是否存在。


RCPT TO:<test@gmail.com>

邮件服务器返回了550状态码,表示该 Email 地址不存在。


550-5.1.1 The email account that you tried to reach does not exist. Please try
550-5.1.1 double-checking the recipient's email address for typos or
550-5.1.1 unnecessary spaces. Learn more at
550 5.1.1  https://support.google.com/mail/?p=NoSuchUser p34si3372771otp.228 - gsmtp

如果查询的是一个真实的 Email 地址,邮件服务器就会返回250状态码。


RCPT TO:<yifeng.ruan@gmail.com>
250 2.1.5 OK p34si3372771otp.228 - gsmtp

一般来说,状态码 250 和 251 都表示邮箱存在,状态码 5xx 表示不存在,其他状态码(主要是 4xx)则代表无法确认。


RCPT TO:<xxx@censored.pl>
451 Temporary local problem - please try later

验证完成后,使用QUIT命令关闭 TCP 连接。


QUIT
221 2.0.0 closing connection p34si3372771otp.228 - gsmtp

七、参考链接

(正文完)

==============================

下面是推广时间。移动端开发的市场广,就业潜力大,现在有一门移动端 H5 开发的课程推荐给大家。

海棠学院是一家专业的前端教育机构,一直与我有合作、受到很多学员好评。他们这次推出《移动端开发 + 职业技能》大型公开课,介绍 H5 开发,为期三周。

该课程将带领您一步一步学习移动端页面的开发,手把手教你做出下面的页面。

完整的课程大纲请参考这里

除了技术课程,还会有一次《前端开发流程、求职、职场》的公开课,由海棠学院创始人张小河主讲,帮助你了解前端工程师的就业市场和职业规划。

  • 前端新手如何进入喜欢的公司?
  • 公司真实的开发流程是怎么样的?
  • 为什么看了 100G 的视频/资料,你也没有学好?
  • 如何成为高年薪的前端工程师?

这堂公开课是免费的,点击这里了解详情。

(完)

一灯学堂

优达学城

留言(20条)

`telent gmail-smtp-in.l.google.com 25`

阮神应该是 telnet ^_^

是telent还是telnet啊???

引用ycy的发言:

是telent还是telnet啊???

telnet, 应该是笔误

命令错了 不是 `telent`,应该是 `telnet`

谢谢上面各位指出错误,已经改正了。

随便敲了个邮箱RCPT TO:

居然250 Ok

不信邪再敲一个RCPT TO:

终于550 Mailbox not found.

嗯我拿企鹅开刀了。。

lvv2这是挂了么?一直显示 系统升级中

nc好评,我都是找了nc来替代telnet的

根据楼主的博客写的python函数: https://gist.github.com/badbye/41aa2025a2e0d048d42c086b9c2cbee2

学习python中,无意中搜到这个网页,膜拜大师!阿里都是牛人!努力奋斗中!

这个网页是拿什么做出来的?我如果想也自己做一个,该学习哪些知识?请指教

精確來說 reply code 550 才是不存在

Ref. : http://www.greenend.org.uk/rjk/tech/smtpreplies.html

说实话,现在的程序员越来越不关注底层了,底层协议一窍不通。面试要求的更多的是会用即可。

阮老师,啥时候给讲讲SOAPUI啊?

买了大神的书,来膜拜的~~哈哈

原来,还可以这样。。。

通过这种方式可以不需要用户主动验证,就可以知道邮箱是不是合法。很棒!

> telnet gmail-smtp-in.l.google.com 25
Server: 202.101.172.35
Address: 202.101.172.35#53

存在也不能证明邮箱所有者就是注册人的

HELO后的example拼错了……

我要发表看法

«-必填

«-必填,不公开

«-我信任你,不会填写广告链接