PHP 5.6中的域验证与PHPMailer一起通过TLS发送邮件

时间:2017-05-23 07:45:11

标签: php ssl smtp phpmailer php-openssl

我正在尝试使用PHPMailer发送带有Let的加密证书的电子邮件,但在转换到PHP 5.6后,由于域验证失败,它无法正常工作。

  

连接失败。错误#2:stream_socket_enable_crypto():SSL操作>失败,代码为1. OpenSSL错误消息:错误:14090086:SSL例程:ssl3_get_server_certificate:证书验证失败

明显的解决方法是禁用域验证,但我不愿意这样做,因为我想知道它是如何工作的

以下

的输出
php -r "var_dump(openssl_get_cert_locations());"

array(8) {
  ["default_cert_file"]=>
  string(36) "/usr/local/apps/etc/openssl/cert.pem"
  ["default_cert_file_env"]=>
  string(13) "SSL_CERT_FILE"
  ["default_cert_dir"]=>
  string(33) "/usr/local/apps/etc/openssl/certs"
  ["default_cert_dir_env"]=>
  string(12) "SSL_CERT_DIR"
  ["default_private_dir"]=>
  string(35) "/usr/local/apps/etc/openssl/private"
  ["default_default_cert_area"]=>
  string(27) "/usr/local/apps/etc/openssl"
  ["ini_cafile"]=>
  string(0) ""
  ["ini_capath"]=>
  string(0) ""
}

我在上面提到的位置有cert.pem,但我的证书和私钥存在于 / etc / ssl 中,我甚至试图创建一个Sysmlink到那些文件夹但仍然验证失败。

所以任何人都可以解释验证是如何工作的,因为即使经过几天的谷歌搜索问题我也无法弄清楚,因为大多数解决方案都指向禁用域验证。

我错过了一些东西,因为我拥有与证书相关的所有正确文件以及我在我的网站上使用它的有效证书。

以下是PHPMailer的代码

require 'PHPMailer-master/PHPMailerAutoload.php';
$mail = new PHPMailer;
$mail->isSMTP();
$mail->SMTPDebug = 5;
$mail->Debugoutput = 'html';
$mail->Host = 'mydomin.com';
$mail->Port = 587;
$mail->SMTPSecure = 'tls';
$mail->SMTPAuth = true;
$mail->Username = "test@mydomain.com";
$mail->Password = "test";
$mail->setFrom('test@mydomain.com', 'Hii');
$mail->addAddress('test@gmail.com', 'John Doe');
$mail->Subject = 'PHPMailer GMail SMTP test';
$mail->msgHTML("<h2>Hello World</h2>");
$mail->AltBody = 'This is a plain-text message body';

$mail->SMTPOptions = array(
    'ssl' => array(
        'verify_peer' => true,
        'verify_peer_name' => true,
    )
);

if (!$mail->send()) {
    echo "Mailer Error: " . $mail->ErrorInfo;
} else {
    echo "Message sent!";
}

1 个答案:

答案 0 :(得分:0)

您的服务器未在其响应中提供letsencrypt X3中间证书,仅提供叶证书。这还不够,因为大多数CA商店都不包含letsencrypt CA证书,只包含他们签名的根证书,因此您需要中间人来桥接这两者。从here获取中间证书并将其附加到您的证书文件中。

以下是如何从客户端看到它的工作原理:

$ wget https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem.txt
$ openssl s_client -CAfile lets-encrypt-x3-cross-signed.pem.txt -connect example.com:465
depth=2 O = Digital Signature Trust Co., CN = DST Root CA X3
verify return:1
depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3
verify return:1
depth=0 CN = example.com
verify return:1
---
Certificate chain
 0 s:/CN=example.com
   i:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X3
...
Verify return code: 0 (ok)

如果您在服务器端捆绑该证书,它应该适用于没有本地中间证书的所有最新客户端。