”SMTP connect() failed“ 原因及解决办法

wordpress用SMTP的时候发送邮件总是报以下的错误:

代码如下:

Test Message Sent
The result was:
bool(false)
The full debugging output is shown below:
PHPMailer Object
(
    [Version] => 5.2.22
    [Priority] =>
    [CharSet] => UTF-8
    [ContentType] => text/plain
    [Encoding] => 7bit
    [ErrorInfo] => SMTP connect() failed. https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting
    [From] => fujieace@126.com
    [FromName] => 付杰博客
    [Sender] =>
    [ReturnPath] =>
    [Subject] => WP Mail SMTP: Test mail to 2508830500@qq.com
    [Body] => This is a test email generated by the WP Mail SMTP WordPress plugin.
    [AltBody] =>
    [Ical] =>
    [MIMEBody:protected] => This is a test email generated by the WP Mail SMTP WordPress plugin.
    [MIMEHeader:protected] => Date: Mon, 13 Nov 2017 07:23:03 +0000
To: 2508830500@qq.com
From: =?UTF-8?B?5LuY5p2w5Y2a5a6i?=
Subject: WP Mail SMTP: Test mail to 2508830500@qq.com
Message-ID: <39517ff24062b312158278ec28881e2b@www.fujieace.com>
X-Mailer: PHPMailer 5.2.22 (https://github.com/PHPMailer/PHPMailer)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8

其实,报以上的错误,特别是当有“SMTP connect() failed”这句话的时候,既不是wordpress本身的问题,也不是wordpress相关smtp插件的问题,更不是所谓PHP的问题。

而是“SMTP无法连接到SMTP主机(SMTP Error: Could not connect to SMTP host.)”的问题。

SMTP错误:无法连接到SMTP主机。
SMTP Error: Could not connect to SMTP host 中文可称“SMTP错误:无法连接到SMTP主机”。

这种错误也可以显示为 SMTP connect() failed 或 Called Mail() without being connected 输出在调试中。这通常被称为PHPMailer问题,但几乎总是由本地DNS故障,防火墙阻塞(例如GoDaddy)或本地网络上的其他问题导致。这意味着PHPMailer无法联系您在Host属性中指定的SMTP服务器,但并不确切地说明原因。也可能是由于没有openssl加载扩展程序引起的(请参阅下面的加密注意事项)。

一、服务器商的严格性,例如:GoDaddy
受欢迎的美国托管服务提供商GoDaddy对发送电子邮件施加了非常严格的限制(几乎变得无用)。他们阻止出站SMTP到端口25,465和587到除自己以外的所有服务器。

这个问题是堆栈溢出的许多令人沮丧的问题的主题。

如果您发现您的脚本在您的本地机器上运行,而不是在您将其上传到GoDaddy时,则会发生在您身上。GoDaddy的解决方案极其糟糕:您必须通过他们的服务器进行发送,并禁用所有的安全功能,用户名和密码(很好,呵呵?!),给你这个PHPMailer的配置:

$ mail - > isSMTP();
$ mail - > Host  =  ' relay-hosting.secureserver.net ' ;
$ mail - > Port  =  25 ;
$ mail - > SMTPAuth  =  false ;
$ mail - > SMTPSecure  =  false ;

GoDaddy也拒绝发送From属于任何aol,gmail,yahoo,hotmail,live,aim或者msn域名的地址(参见他们的文档)。这是因为所有这些域名部署SPF和DKIM防伪措施,伪造你的地址是伪造的。

您可能会发现切换到更开明的托管服务提供商更容易。

阅读SMTP转录
如果设置SMTPDebug = 2或更高,您将看到远程SMTP服务器说什么。很多时候,这会告诉你到底发生了什么错误,比如“不正确的密码”,或者有时候是页面的URL来帮助你诊断问题。读它说什么。谷歌做了很多 - 关于他们的“允许不太安全的应用程序”设置的信息见下面。

二、DNS失败
这些通常被视为连接超时,或“名称解析中的临时失败”,“无法解析主机”,“getaddrinfo失败”或类似的错误。通过使用该dig工具(从dnsutilsDebian / Ubuntu上的软件包)检查您的DNS是否正在工作:

dig +short smtp.gmail.com

如果你的DNS工作,你会得到这样的东西:

gmail-smtp-msa.l.google.com.
173.194.67.108
173.194.67.109

如果失败,PHPMailer将无法发送电子邮件,因为它无法获得正确的IP地址连接。如果也许你在DNS中没有名字,你可以直接使用IP地址作为主机名。要解决这个问题,你需要弄清楚为什么你的DNS不工作 - 也许你还没有设置你的解析器?

1、Ping:检查它在哪里?

即使服务器被禁用,所有的服务通常都会对简单的Ping做出响应,所以如果你知道你的DNS是好的,检查服务器是否真的存在:

ping smtp.gmail.com 

你应该看到这样的事情(按Ctrl + C停止它):

PING gmail-smtp-msa.l.google.com (74.125.133.108): 56 data bytes
64 bytes from 74.125.133.108: icmp_seq=0 ttl=43 time=72.636 ms
64 bytes from 74.125.133.108: icmp_seq=1 ttl=43 time=68.841 ms
64 bytes from 74.125.133.108: icmp_seq=2 ttl=43 time=68.500 ms

2、telnet:检查它是一个邮件服务器?

可能是某个其他服务正在您尝试连接的SMTP端口上运行。你可以使用这个telnet工具来检查这个(在提交服务端口上连接到gmail):

telnet smtp.gmail.com 587 

这应该给你这样的东西:

Trying 173.194.67.109...
Connected to gmail-smtp-msa.l.google.com.
Escape character is '^]'.
220 mx.google.com ESMTP ex2sm16805587wjd.30 - gsmtp

(输入quit摆脱)。如果端口587不起作用,您可以尝试使用端口465或端口25,并使用任何一个工作 - 但要记住,端口25通常不支持加密(请参阅加密说明)。

如果它没有输出或者没有输出220,那么你的服务器关闭了,或者你的服务器错了。

三、防火墙重定向
另外需要注意的是,邮件服务器响应的名称应与您请求的服务器相关,如上例中所示 - 我们要求smtp.gmail.com并得到gmail-smtp-msa.l.google.com,这看起来像是与谷歌有关 -如果相反,您看到类似您的ISP的名称,那么这可能意味着您的ISP的防火墙将您透明地重定向到他们自己的邮件服务器,并且您可能会看到身份验证失败,因为您登录到错误的服务器。这很可能发生在端口25上,但在端口465和587上不太可能发生,所以它是使用加密的另一个原因!

四、SELinux阻塞
如果您看到类似的错误SMTP -> ERROR: Failed to connect to server: Permission denied (13),您可能会遇到阻止PHP或Web服务器发送电子邮件的SELinux。这在RedHat / Fedora / Centos上尤其可能。使用该getsebool命令,我们可以检查httpd守护进程是否允许通过网络建立连接并发送电子邮件:

getsebool httpd_can_sendmail  
getsebool httpd_can_network_connect

这个命令将返回一个布尔值或关闭。如果关闭,我们可以打开它:

sudo setsebool -P httpd_can_sendmail 1
sudo setsebool -P httpd_can_network_connect 1

如果您通过fastcgi运行PHP-FPM,则可能需要将其应用于fpm守护进程而不是httpd。

五、IPv6阻塞
一些服务提供商(包括Digital Ocean)为服务器提供IPv6连接,但在允许IPv4使用的情况下阻止通过IPv6的出站SMTP。这可以通过Host显式地将属性设置为IPv4地址来解决(该gethostbyname功能仅执行IPv4查找):

$mail->Host = gethostbyname('smtp.gmail.com');

这种方法唯一的问题是,你最终要求连接一个明确的IPv4地址,这通常会导致你的证书名称检查失败。您可以禁用该功能(请参阅SMTPOptions本文档中的其他地方),但这应该被认为是一个糟糕的解决方法 - 正确的解决方案是修复您的网络。

注意:使用数字海洋服务时,请检查您的SMTP端口是否实际上已解锁,因为这是一家美国公司,它包含一系列不属于跨度的指令,所以您应该要求解锁并按照步骤进行确认海洋发送您的电子邮件与PhpMailer的目的。

六、认证失败
如果您的身份验证失败,有几个可能的原因:

你有错误的用户名或密码

您的连接正在被转移到不同的服务器(如上所述)

您指定了没有加密的身份验证

通常,您不想通过未加密的链接发送用户名或密码。某些SMTP身份验证方案会添加最低级别的安全性(发送较短的哈希而不是明文),但是这些方案只提供最低限度的保护,因此大多数服务器不允许没有加密的身份验证。通过设置解决这个问题SMTPSecure = 'tls',并Port = 587以及设置Username和Password属性。

Gmail,OAuth2和“允许不太安全的应用程序”

自2014年12月起,Google开始实施基于OAuth2的名为XOAUTH2的身份验证机制,以访问其应用(包括Gmail)。此更改可能会破坏SMTP和IMAP对Gmail的访问,并且可能会收到来自许多电子邮件客户端(包括PHPMailer,Apple Mail,Outlook,Outlook)的身份验证失败(通常为“5.7.14请通过Web浏览器登录,然后重试”雷鸟和其他人。错误输出可能包含指向https://support.google.com/mail/bin/answer.py?answer=78754的链接,其中列出了可能的补救措施。

在PHPMailer中有两个主要的解决方案:

1、Gmail不喜欢意外的客户端连接到Gmail帐户,因此它可能需要您登录到您的Gmail帐户在您的浏览器像往常一样(这将在错误输出中可见,如果你设置被提及SMTPDebug = 2),或访问解锁CAPTCHA页提到在他们的支持文件。

2、启用“ 允许不太安全的应用程序 ”通常可以解决PHPMailer的问题,而且这并不会使您的应用程序显着降低安全性。据了解,改变这个设置可能需要一个小时或更长时间才能生效,所以不要期望立即修复。
PHPMailer在版本5.2.11中添加了对XOAUTH2的支持,但是您必须运行PHP 5.5或更高版本才能使用它。

使用加密
毫无疑问,你应该在每一个机会使用加密,否则你正在邀请各种不愉快的可能性进行网络钓鱼,身份盗用等。

要使用任何类型的加密,您需要启用opensslPHP扩展。如果您没有安装,或者配置错误,则可能在STARTTLS连接阶段出现问题。通过查看phpinfo()or 的输出php -i(查找'openssl'部分),或者openssl输出结果php -m或者运行以下代码来检查:

<?php echo (extension_loaded('openssl')?'SSL loaded':'SSL not loaded')."\n"; ?>

至于什么样的使用,答案一般很简单:不要在端口465上使用SSL,它从1998年开始被弃用,只被没有得到备忘录的微软产品使用。改为在端口587上使用TLS:

$ mail - > SMTPSecure  =  ' tls ' ;
$ mail - > Host  =  ' smtp.gmail.com ' ;
$ mail - > Port  =  587 ;

或者更简洁:

$ mail - > Host  =  ' tls://smtp.gmail.com:587 ' ;

不要混淆这些模式; 有效的组合tls在端口587(或可能是25)和ssl端口465 ssl上。在端口587或tls端口465 上将不起作用。

Opportunistic TLS

PHPMailer 5.2.10引入了Opportunistic TLS - 如果它发现服务器正在广告TLS加密(在连接到服务器之后),即使没有设置,它也会自动启用加密SMTPSecure。这可能会导致问题,如果服务器广告与无效证书的TLS,但您可以关闭它$mail->SMTPAutoTLS = false;

最后修改:
赞赏支持
最大的开心,莫过于你请我吃辣条

发表评论