Email 是最常用的用户识别手段。
开发者常常需要验证邮箱的真实性。一般的方法是,注册时向该邮箱发出一封验证邮件,要求用户点击邮件里面的链接。
但是很多时候(比如要搞邮件营销时),拿到的是成千上万现成的 Email 地址,不可能通过回复确认真实性,这时该怎么办呢?
答案就是使用 SMTP 协议。本文将介绍如何通过该协议验证邮箱的真假。
另外,结尾处还有一则移动端 H5 开发的培训消息,欢迎关注。
一、SMTP 协议简介
SMTP 是"简单邮件传输协议"(Simple Mail Transfer Protocol)的缩写,基于 TCP 协议,用来发送电子邮件。
只要运行了该协议的服务器端(daemon),当前服务器就变为邮件服务器,可以接收电子邮件。
验证 Email 邮箱的基本思路如下。
- 找到邮箱所在域名的 SMTP 服务器
- 连接该服务器
- 询问有没有该邮箱
- 如果服务器返回 250 或 251 状态码,邮箱就是真的;如果返回 5xx(500~599),就是假的。
注意,即使服务器确认邮箱是真的, 也不代表邮件一定会发送到该邮箱,更不代表用户一定会读到该邮件。
二、查找域名的 MX 记录
下面通过一个例子,演示如何验证[email protected]
这个邮箱。
首先,需要查找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
,也可以使用线上服务(1,2,3)。更多 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 协议规定,连接成功后,必须向邮件服务器提供连接的域名,也就是邮件将从哪台服务器发来。
假定从[email protected]
向[email protected]
发送邮件,这里要提供的域名就是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:<[email protected]>
上面代码表示,连接者将从[email protected]
向邮件服务器发送邮件。邮件服务器返回250
状态码,表示响应成功。
250 2.1.0 OK h10si3194349otb.59 - gsmtp
SMTP 是一个很简单的协议,本身没有规定如何验证邮件的来源,也就是说,不验证邮件是否真的从[email protected]
发来,所以导致了后来垃圾邮件泛滥。为了控制垃圾邮件,许多邮件服务器会用自己的方法验证邮件地址,下面就是其中的一些方法。
- example.com 是否有 MX 记录
- example.com 是否可以 Ping 通
- 是否存在 [email protected] 这个邮箱
- 发起连接的 IP 地址是否在黑名单之中
- IP 地址的反向 DNS 解析,是否指向一个邮件服务器
六、RCPT TO 命令
最后一步就是使用RCPT TO
命令,验证邮件地址是否存在。
RCPT TO:<[email protected]>
邮件服务器返回了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:<[email protected]> 250 2.1.5 OK p34si3372771otp.228 - gsmtp
一般来说,状态码 250 和 251 都表示邮箱存在,状态码 5xx 表示不存在,其他状态码(主要是 4xx)则代表无法确认。
RCPT TO:<[email protected]> 451 Temporary local problem - please try later
验证完成后,使用QUIT
命令关闭 TCP 连接。
QUIT 221 2.0.0 closing connection p34si3372771otp.228 - gsmtp
七、参考链接
(正文完)
==============================
下面是推广时间。移动端开发的市场广,就业潜力大,现在有一门移动端 H5 开发的课程推荐给大家。
海棠学院是一家专业的前端教育机构,一直与我有合作、受到很多学员好评。他们这次推出《移动端开发 + 职业技能》大型公开课,介绍 H5 开发,为期三周。
该课程将带领您一步一步学习移动端页面的开发,手把手教你做出下面的页面。
完整的课程大纲请参考这里。
除了技术课程,还会有一次《前端开发流程、求职、职场》的公开课,由海棠学院创始人张小河主讲,帮助你了解前端工程师的就业市场和职业规划。
- 前端新手如何进入喜欢的公司?
- 公司真实的开发流程是怎么样的?
- 为什么看了 100G 的视频/资料,你也没有学好?
- 如何成为高年薪的前端工程师?
这堂公开课是免费的,点击这里了解详情。
(完)
shooter 说:
`telent gmail-smtp-in.l.google.com 25`
阮神应该是 telnet ^_^
2017年6月26日 09:11 | # | 引用
ycy 说:
是telent还是telnet啊???
2017年6月26日 09:48 | # | 引用
elvi 说:
telnet, 应该是笔误
2017年6月26日 10:04 | # | 引用
Moo木 说:
命令错了 不是 `telent`,应该是 `telnet`
2017年6月26日 10:06 | # | 引用
阮一峰 说:
谢谢上面各位指出错误,已经改正了。
2017年6月26日 10:30 | # | 引用
fwin3000 说:
随便敲了个邮箱RCPT TO:
居然250 Ok
不信邪再敲一个RCPT TO:
终于550 Mailbox not found.
嗯我拿企鹅开刀了。。
2017年6月26日 16:47 | # | 引用
slamzhzm 说:
lvv2这是挂了么?一直显示 系统升级中
2017年6月26日 18:28 | # | 引用
胡鑫龙 说:
nc好评,我都是找了nc来替代telnet的
2017年6月27日 09:50 | # | 引用
yalei 说:
根据楼主的博客写的python函数: https://gist.github.com/badbye/41aa2025a2e0d048d42c086b9c2cbee2
2017年6月27日 16:36 | # | 引用
muziwang 说:
学习python中,无意中搜到这个网页,膜拜大师!阿里都是牛人!努力奋斗中!
2017年6月28日 10:11 | # | 引用
muziwang 说:
这个网页是拿什么做出来的?我如果想也自己做一个,该学习哪些知识?请指教
2017年6月28日 10:13 | # | 引用
_hhnj 说:
精確來說 reply code 550 才是不存在
Ref. : http://www.greenend.org.uk/rjk/tech/smtpreplies.html
2017年6月28日 17:45 | # | 引用
业余草 说:
说实话,现在的程序员越来越不关注底层了,底层协议一窍不通。面试要求的更多的是会用即可。
2017年6月29日 17:02 | # | 引用
Alex 说:
阮老师,啥时候给讲讲SOAPUI啊?
2017年7月 3日 10:53 | # | 引用
小筑 说:
买了大神的书,来膜拜的~~哈哈
2017年7月 8日 18:29 | # | 引用
Mazey 说:
原来,还可以这样。。。
2017年7月11日 09:06 | # | 引用
ken 说:
通过这种方式可以不需要用户主动验证,就可以知道邮箱是不是合法。很棒!
2017年8月 1日 13:55 | # | 引用
echo 说:
> telnet gmail-smtp-in.l.google.com 25
Server: 202.101.172.35
Address: 202.101.172.35#53
2017年8月 8日 11:14 | # | 引用
luming 说:
存在也不能证明邮箱所有者就是注册人的
2017年9月 2日 11:00 | # | 引用
xoxo 说:
HELO后的example拼错了……
2017年9月26日 11:30 | # | 引用
子龙 说:
为什么随便RCPT TO一个Email都是250
2018年1月 9日 13:52 | # | 引用
不懂 说:
想问问问什么要使用smtp协议或者pop3协议了?这些协议有什么优势吗?
2018年6月20日 21:04 | # | 引用
zkerhcy 说:
server can't find telnet: NXDOMAIN
2018年7月17日 10:21 | # | 引用
関木子 说:
邮箱真实性在线检测:https://shorttimemail.com/zh-Hans/mail-validator
2019年5月28日 16:28 | # | 引用
mrzhi 说:
rcpt to:
250 Ok
为什么这样也是OK的啊?
2020年7月 1日 10:32 | # | 引用
李永杰 说:
存在也不能证明邮箱所有者就是注册人的
2021年6月23日 04:29 | # | 引用
Sakarwei 说:
我拿腾讯(mx1.qq.com)实验了:
……
rcpt to:<[email protected]>
250 OK
(??)
rcpt to:<[email protected]>
250 OK
(????)
然后是网易的 163()
rcpt to:<[email protected]>
250 Accepted
所以……这个RCPT TO真的靠谱吗……?
(我替换了尖括号为全角字符,实际试验的时候用的是半角的)
2025年1月11日 22:43 | # | 引用