php - 如何以编程方式查找电子邮件服务器信息
问题描述
如果用户提供了一封电子邮件,比如说 hello.world@example.com,是否有一个公共数据库,我可以在其中以编程方式查找他们的邮件服务器的连接信息(我的服务将让用户提供一封电子邮件,然后允许我的软件从它发送自动电子邮件。)
如何以编程方式确定他们的服务器是 pop3、Imap 还是 smtp。端口和安全协议(tls 或 ssl)呢?
如何确定邮件服务器是否与电子邮件后缀不同。(即用户正在使用共享主机。)
这项服务是否只有付费选项?
注意:最好使用 PHP 解决方案,甚至更好的是 http REST 服务。
解决方案
是的,你可以这样做。至少对于 SMTP。而且......您可以轻松地以特定用户的身份发送电子邮件......
解释客户如何发送电子邮件
当电子邮件客户端发送电子邮件时,执行以下步骤:
它提取电子邮件的域部分,例如,给定“bob@gmail.com”的“gmail.com”
它检查是否有发布的 DNS 记录称为 Mail Exchange 或 MX 记录。MX 记录包含以下信息:
生存时间,即记录的有效期
权重,即客户端尝试连接的顺序。最低到最高
服务器 A 记录,或 IP 地址。
您可以使用dig
ornslookup
命令查询为域发布的 MX 记录。
例子:
root@dib:~# nslookup -querytype=mx gmail.com
Server: 172.31.0.2
Address: 172.31.0.2#53
Non-authoritative answer:
gmail.com mail exchanger = 10 alt1.gmail-smtp-in.l.google.com.
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 = 40 alt4.gmail-smtp-in.l.google.com.
gmail.com mail exchanger = 5 gmail-smtp-in.l.google.com.
Authoritative answers can be found from:
root@dib:~# dig +short MX gmail.com
40 alt4.gmail-smtp-in.l.google.com.
5 gmail-smtp-in.l.google.com.
10 alt1.gmail-smtp-in.l.google.com.
20 alt2.gmail-smtp-in.l.google.com.
30 alt3.gmail-smtp-in.l.google.com.
- 如果有 MX 记录,客户端会尝试与列出的服务器建立端口 25 连接。在这个例子中,我们将使用
gmail-smtp-in.l.google.com
. 一个快速测试是检查连接时是否显示横幅。
使用示例telnet
:
root@dib:~# telnet gmail-smtp-in.l.google.com 25
Trying 74.125.197.27...
Connected to gmail-smtp-in.l.google.com.
Escape character is '^]'.
220 mx.google.com ESMTP m8-v6si7680016plt.29 - gsmtp
quit
221 2.0.0 closing connection m8-v6si7680016plt.29 - gsmtp
Connection closed by foreign host.
横幅是220 mx.google.com ESMTP b8-v6si8705269pls.261 - gsmtp
一部分。
- 大多数电子邮件客户端使用机会性 TLS,即,如果服务器提供 TLS,它将使用它,否则它不使用。要确定服务器是否提供 TLS,我们需要发出 EHLO 命令。这是扩展的 SMTP Hello。我们正在寻找的是
STARTTLS
正在提供的命令。
例子:
root@dib:~# telnet gmail-smtp-in.l.google.com 25
Trying 74.125.197.27...
Connected to gmail-smtp-in.l.google.com.
Escape character is '^]'.
220 mx.google.com ESMTP s83-v6si8350062pfg.175 - gsmtp
ehlo stackoverflow.com
250-mx.google.com at your service, [123.123.123.123]
250-SIZE 157286400
250-8BITMIME
250-STARTTLS
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-CHUNKING
250 SMTPUTF8
quit
221 2.0.0 closing connection s83-v6si8350062pfg.175 - gsmtp
Connection closed by foreign host.
我们可以看到该域的 SMTP 服务器gmail.com
确实提供了 TLS。
- 我不打算解释 SMTP 对话的其余部分,但你可以谷歌它...... :)
用 PHP 回答这些问题的解决方案
“是否有一个公共数据库,我可以在其中以编程方式查找他们的邮件服务器的连接信息”
- 是的,数据库是
Domain Name System
. 有很多方法可以做到这一点;然而,PHP 有一个漂亮的内置函数。它是getmxrr()
。
- 是的,数据库是
例子:
root@dib:~# cat mxrecord.php
<?php
$email_addr = "bob@gmail.com";
list($local, $domain) = explode('@', $email_addr);
getmxrr($domain, $mxrecords); // http://php.net/manual/en/function.getmxrr.php
var_dump($mxrecords);
?>
root@dib:~# php mxrecord.php
array(5) {
[0]=>
string(26) "gmail-smtp-in.l.google.com"
[1]=>
string(31) "alt1.gmail-smtp-in.l.google.com"
[2]=>
string(31) "alt2.gmail-smtp-in.l.google.com"
[3]=>
string(31) "alt3.gmail-smtp-in.l.google.com"
[4]=>
string(31) "alt4.gmail-smtp-in.l.google.com"
}
您可以遍历结果并回答您的问题“我如何确定邮件服务器是否与电子邮件的后缀不同”。
- “端口和安全协议呢?” 端口总是 25。这就是我们有协议定义的原因。安全协议有点棘手......
基本上,如果你想知道这样的事情;协议、密码、证书颁发机构等……您需要使用 OpenSSL 库……或者只是解析开放openssl s_client
内容……如果我在这里也介绍了 TLS 位,这将是一个非常长的答案……但是...在 shell 中运行它并查看输出:
openssl s_client -connect gmail-smtp-in.l.google.com:25 -starttls smtp
这基本上只是处理与服务器的 TLS 握手并吐出您想要的所有信息。PHP 具有 OpenSSL 库,因此您可以在 PHP 中使用它们...
以其他用户身份发送电子邮件
基本上,除非电子邮件服务器实现类似的 SPF,否则您可以“欺骗”发件人,即将您想要的任何内容放入mail from
命令中。这是一种非常常见的做法,但是,一些电子邮件服务器会阻止欺骗。您可以采取一些措施来提高您的电子邮件被接收的可能性。
推荐阅读
- python-3.x - python:kivy动画计数执行
- mysql - 如何将父表中的数据更新或插入到子表中?
- c++ - 如何将二维数组中的元素索引存储到一维数组中,然后交换这些值
- javascript - 使用js控制台比较网页的两个数字
- android - snapshot.hasData 总是返回 false
- ansible - 如何在ansible中使用expect
- nosql - Couchbase 默认管理员密码更改
- html - 如何在网站上使用Icomoon图标,更改图标颜色以及将来添加更多图标?
- c# - 在 C# 中按 dateTime 对统一文件夹中的模型重新排序
- angular - 我有大约 30 个社交链接字段来获取每个我想使用 formArray 构建的 url