无法连接到SMTP主机。

14

SMTP错误:无法连接到SMTP主机。无法发送消息。

邮件程序错误:SMTP错误:无法连接到SMTP主机。

我似乎找不到在CentOS下使PHPMailer工作的方法。在Windows上使用XAMPP可以很好地发送电子邮件,但在Linux下始终出现此错误。SMTP服务器是运行在25端口上的Lotus Domino,CentOS机器完全没有防火墙,奇怪的是,即使是mail()也无法工作。它什么也没有返回(而在Windows上返回1)。如果我通过CentOS服务器通过telnet发送电子邮件,它可以正常工作,所以我认为这与PHP有关,但我不知道怎么处理。

<?php
require("class.phpmailer.php");
$mail = new PHPMailer();
$mail->IsSMTP();
$mail->Host = "192.168.x.x";
$mail->SMTPAuth = false;
$mail->From = "xxx@xxx.it";
$mail->FromName = "XXX";
$mail->AddAddress("xxx@xxx.it");
$mail->IsHTML(true);
$mail->Subject = "Test";
$mail->Body    = "Test";
if(!$mail->Send())
{
   echo "Message could not be sent. <p>";
   echo "Mailer Error: " . $mail->ErrorInfo;
   exit;
}
echo "Message has been sent";
?>

仅澄清一下,上面的代码适用于 XAMPP (Windows)。

我在 PHPMailer 上调试了错误,错误发生在这里(class.smtp.php 的 Connect() 方法):

$this->smtp_conn = @fsockopen($host,    // the host of the server
                             $port,    // the port to use
                             $errno,   // error number if any
                             $errstr,  // error message if any
                             $tval);   // give up after ? secs
// verify we connected properly
if(empty($this->smtp_conn)) {
  $this->error = array("error" => "Failed to connect to server",
                       "errno" => $errno,
                       "errstr" => $errstr);
  if($this->do_debug >= 1) {
    echo "SMTP -> ERROR: " . $this->error["error"] . ": $errstr ($errno)" . $this->CRLF . '<br />';
  }
  return false;
}

看起来它无法打开Socket...

更新:按照Alvaro的建议使用$mail->SMTPDebug = 2;,产生了以下输出:

SMTP -> 错误:无法连接到服务器:权限被拒绝(13)


2
您尝试过指定登录凭证吗? - Neil Knight
你能否粘贴你的php.ini文件或phpinfo()中的SMTP信息? - GBD
我在phpinfo()中只看到了两个与SMTP相关的变量,它们分别是SMTP (localhost)和smtp_port (25)。在Windows上它们的值也完全相同。我尝试根据我的实际IP更改SMTP,但没有任何变化。当我更改这些值时,我需要重新启动Apache吗? - raz3r
如果您尝试使用“telnet 192.168.x.x 25”会发生什么? - Barmar
它可以工作,已经说过了,我可以通过CentOS使用telnet发送电子邮件。 - raz3r
显示剩余2条评论
2个回答

43

操作系统 CentOS 6.3

无法发送电子邮件

经过一些调查后发现SELinux阻止了通信

SELinux默认启用和配置。因此,SELinux不允许Apache(httpd、phpmailer)使用sendmail功能并建立任何网络连接。

使用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

现在,您可以测试您的 PHP 代码,以查看 SendMail 是否正常工作。


今天你是我的英雄。 - Christopher Markieta
1
您真是救了我。我还想指出,在某些版本的CENTOS上,setsebool命令可能会运行得有点慢,所以在运行命令时请耐心等待。 - JoeMoe1984
您拯救了我的一天,并确认会进一步了解SELinux。谢谢。 - Manee.O.H
这个解决方案让我感到非常开心。我整整一个星期都在苦苦思索,毫无头绪。谢谢! - Nasir Ahmad
如果您使用外部SMTP服务器,则我认为不需要httpd_can_sendmail。此设置是用于使用sendmail程序的情况,即如果您在同一台计算机上运行邮件服务器。设置httpd_can_network_connect就足够了。只启用一个所需的设置更好(更安全)。但是,这可能不是最安全的选项,因为它允许httpd发起到任何计算机的任何传出连接。因此,这个解决方案比禁用SELinux更好,但不是最安全的解决方案。 - cazort

12

您可以使用 SMTPDebug 属性启用调试模式,例如:

$mail = new PHPMailer();
// 1 = errors and messages
// 2 = messages only
$mail->SMTPDebug  = 2;

错误信息将被显示在屏幕上。

更新:

使用 fsockopen() 函数产生“权限被拒绝”错误消息,这可能是因为PHP运行用户不允许打开套接字。如果您已经仔细检查了防火墙,并且仍然出现问题,很可能是SELinux问题 :-?


1
这里捕获得很好,现在它给出了这个错误 SMTP -> ERROR: Failed to connect to server: Permission denied (13)。这可能与Linux用户的权限有关吗? - raz3r
2
你很聪明,我使用了你在链接中找到的命令,它起作用了。所以毕竟是一个网络相关的问题。好吧,现在我知道如果将来遇到同样的错误该怎么做了!谢谢大家,感激你们的帮助 ;) - raz3r

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接