http://www.ruanyifeng.com/blog/2017/06/smtp-protocol.html

作者: 阮一峰

日期: 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

七、参考链接

(正文完)

如何验证 Email 地址:SMTP 协议入门教程的更多相关文章

  1. javascript使用正则表达式验证Email地址

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  2. WCF入门教程(四)通过Host代码方式来承载服务 一个WCF使用TCP协议进行通协的例子 jquery ajax调用WCF,采用System.ServiceModel.WebHttpBinding System.ServiceModel.WSHttpBinding协议 学习WCF笔记之二 无废话WCF入门教程一[什么是WCF]

    WCF入门教程(四)通过Host代码方式来承载服务 Posted on 2014-05-15 13:03 停留的风 阅读(7681) 评论(0) 编辑 收藏 WCF入门教程(四)通过Host代码方式来 ...

  3. python3之模块SMTP协议客户端与email邮件MIME对象

    转载自https://www.cnblogs.com/zhangxinqi/p/9113859.html 阅读目录 1.smtplib模块的常用类与方法 2.处理邮件MIME 3.实例 (1)使用HT ...

  4. 用http.get()简单实现网络验证防止客户不给尾款_电脑计算机编程入门教程自学

    首发于:用http.get()简单实现网络验证防止客户不给尾款_电脑计算机编程入门教程自学 http://jianma123.com/viewthread.aardio?threadid=428 给软 ...

  5. 【OpenLayers】入门教程地址

    [OpenLayers]入门教程地址:  点击进入   http://anzhihun.coding.me/ol3-primer/index.html 简书地址 :  http://www.jians ...

  6. Email地址验证

    <script>function validateForm(){ var x=document.forms["myForm"]["email"].v ...

  7. php中的curl使用入门教程和常见用法实例

    摘要: [目录] php中的curl使用入门教程和常见用法实例 一.curl的优势 二.curl的简单使用步骤 三.错误处理 四.获取curl请求的具体信息 五.使用curl发送post请求 六.文件 ...

  8. 基于公网smtp协议实现邮件服务器

    刚开始做邮件服务器开发,一切都是茫然的.在书上网上都很难找到一套完整的邮件服务器开发教程.在个人的摸索中碰到了很多蛋疼得问题.现终于完成了,将我的开发经验分享给大家. 开发环境:vs2012 mfc ...

  9. 《JavaScript语言入门教程》记录整理:运算符、语法和标准库

    目录 运算符 算数运算符 比较运算符 布尔运算符 二进制位运算符 void和逗号运算符 运算顺序 语法 数据类型的转换 错误处理机制 编程风格 console对象和控制台 标准库 Object对象 属 ...

随机推荐

  1. [CentOS]使用Jenkins配置Git+Maven的自动化构建

    背景 最近安装Jenkins,参照网上的各种资料进行尝试,折腾了好久,但是查找了这么多资料,相似度在90%以上!!!,相同的安装过程,测试了几台机器,未曾成功,不得不感慨自己能力有限,最终慢慢摸索,形 ...

  2. EJB部署规则报错

    javax.naming.NameNotFoundException: Unable to resolve 'RuleDeployer'. Resolved ''; remaining name 'R ...

  3. ASP利用xhEditor编辑器实现图片上传的功能。

    本人这几天在做一个软件,无意中用到xhEditor在线编辑器,这个编辑器虽然看着比较简单,但功能非常强大,大家可以去官网上查看,废话不说了. 这篇文件主要是实现在ASP环境中利用xhEditor编辑器 ...

  4. [转]仿91助手的PC与android手机通讯

    仿91助手的PC与android手机通讯 原文 知道91助手和豌豆莢吧? 说到这两个东西,最让人好奇的应该是就是和手机的交互了.我之前有研究过电脑和安卓的交互,基本功能已经走通了,在这里我想分享一下. ...

  5. jquery获取表单数据方法$.serializeArray()获取不到disabled的值

    $.serializeArray()获取不到disabled的值 经实验,$.serializeArray()获取不到disabled的值,如果想要让input元素变为不可用,可以把input设为re ...

  6. express项目创建步骤

    安装nodejs 安装npm 安装express npm install -g express 安装express生成器 npm install -g express-generator 查看expr ...

  7. Win7下静态编译QT5.12源码

    官方参考文档:https://doc.qt.io/qt-5/build-sources.html CSDN博客:https://blog.csdn.net/GG_SiMiDa/article/deta ...

  8. Python打包-Pyinstaller

    我们知道,Python很优雅,很值得学习.但是Python是解释性语言,代码需要有Python解释器才能执行,相比较我们平时直接运行exe等可执行文件多了一步的麻烦. 于是,希望能将Python程序打 ...

  9. joda time, jackson 与 scala 反射

    1. scala 反射,获得所有 field name 可以直接从 case class 获得 field 而不必创建实例 (get fields of a class without an inst ...

  10. WPF依赖属性相关博客导航

    1.一站式WPF--依赖属性(DependencyProperty)一(什么是依赖属性,依赖属性的由来) 2.一站式WPF--依赖属性(DependencyProperty)二(涉及依赖属性的使用) ...