首页 > 解决方案 > 如何以编程方式查找电子邮件服务器信息

问题描述

如果用户提供了一封电子邮件,比如说 hello.world@example.com,是否有一个公共数据库,我可以在其中以编程方式查找他们的邮件服务器的连接信息(我的服务将让用户提供一封电子邮件,然后允许我的软件从它发送自动电子邮件。)

如何以编程方式确定他们的服务器是 pop3、Imap 还是 smtp。端口和安全协议(tls 或 ssl)呢?

如何确定邮件服务器是否与电子邮件后缀不同。(即用户正在使用共享主机。)

这项服务是否只有付费选项?

注意:最好使用 PHP 解决方案,甚至更好的是 http REST 服务。

标签: phpemail

解决方案


是的,你可以这样做。至少对于 SMTP。而且......您可以轻松地以特定用户的身份发送电子邮件......

解释客户如何发送电子邮件

当电子邮件客户端发送电子邮件时,执行以下步骤:

  1. 它提取电子邮件的域部分,例如,给定“bob@gmail.com”的“gmail.com”

  2. 它检查是否有发布的 DNS 记录称为 Mail Exchange 或 MX 记录。MX 记录包含以下信息:

    • 生存时间,即记录的有效期

    • 权重,即客户端尝试连接的顺序。最低到最高

    • 服务器 A 记录,或 IP 地址。

您可以使用digornslookup命令查询为域发布的 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.
  1. 如果有 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一部分。

  1. 大多数电子邮件客户端使用机会性 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。

  1. 我不打算解释 SMTP 对话的其余部分,但你可以谷歌它...... :)

用 PHP 回答这些问题的解决方案

  1. “是否有一个公共数据库,我可以在其中以编程方式查找他们的邮件服务器的连接信息”

    • 是的,数据库是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"
}

您可以遍历结果并回答您的问题“我如何确定邮件服务器是否与电子邮件的后缀不同”。

  1. “端口和安全协议呢?” 端口总是 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命令中。这是一种非常常见的做法,但是,一些电子邮件服务器会阻止欺骗。您可以采取一些措施来提高您的电子邮件被接收的可能性。


推荐阅读