虽然自从 5 月份就没有更新博客了,但是中途还是让博客支持了 HTTPS,同时启用了 HTTP/2,只是没有强制启用。不过发现 Apache 2.4.27 以后就不再支持 perfork 模式下的 HTTP/2 了,就有段时间没有管了。

这不,宇宙最好的语言马上要推出 7.2.0 了,WordPress 也更新到 4.9 版本了,顺带解决上面的问题,于是更新了一波 Apache 和 PHP。

只是发现…为嘛我的邮件发不出去了…

 

不知道为什么,WP 内置的 PHPMailer 调用疼讯企业邮箱的 SMTP 就是无法发出邮件,总是提示 SMTP connect() failed.,让我一度以为服务器无法连接到 smtp.exmail.qq.com。然后经过 telnetping 发现连接是完全正常的,DNS 也能正常解析。

之后我开始怀疑是 DO block 了 SMTP 的连接,或者因为我的疼讯企业邮箱没有经过正常意义的实名认证,微信绑定,导致无法正常发送邮件。正在我打开了 DO 的 tickets,正要发个工单问情况,同时考虑着是不是要把域名邮箱迁移到 ZOHO 去时,我突然意识到好像还没打开 SMTP 的调试模式查看具体的失败原因,万一是我自己的问题呢…

我很庆幸打开调试看了看,不然就要被客服认为是煞笔了…

 

将 SMTP 的 debug level 调整到 2 后,SMTP 果然出现了更多的报错信息:SSL routines:ssl3_get_server_certificate:certificate verify failed

什么?!纳尼?!SSL 3?证书验证失败?不应该啊?

赶紧问问万能的 Google,在 PHP 的 composer 中发现一个 issue,表示是因为找不到默认的根证书才导致这个问题,同时给出的解决方案是下载 http://curl.haxx.se/ca/cacert.pem 的根证书列表放在 PHP 的 OpenSSL 中的默认位置。

 

前因后果且听我慢慢道来~

原来是因为之前为了支持 HTTP/2,OpenSSL 是自己编译安装的,OpenSSL 不会自带根证书(详情),需要自己搞定信任证书列表。下面附上博主觉得靠谱的方法:

1、安装依赖库

yum install -y yum-utils

安装依赖库 yum-utils 是为了使用其中的 repoquery 命令查看 ca-certificates 包中的文件列表。

2、查看 PHP 使用的 OpenSSL 的默认证书路径

php -r "print_r(openssl_get_cert_locations());"

# 输出
Array
(
    [default_cert_file] => /usr/local/openssl/cert.pem
    [default_cert_file_env] => SSL_CERT_FILE
    [default_cert_dir] => /usr/local/openssl/certs
    [default_cert_dir_env] => SSL_CERT_DIR
    [default_private_dir] => /usr/local/openssl/private
    [default_default_cert_area] => /usr/local/openssl
    [ini_cafile] => 
    [ini_capath] => 
)

注意 default_cert_file 一行,说明我的根证书列表在 /usr/local/openssl/cert.pem。过去一看,果然空空乳业。

3、查看 ca-certificates 的证书存放位置

repoquery -q -l ca-certificates

# 输出
...
/etc/pki/tls
/etc/pki/tls/cert.pem
/etc/pki/tls/certs
/etc/pki/tls/certs/ca-bundle.crt
/etc/pki/tls/certs/ca-bundle.trust.crt
...

注意关键的几行,可以发现根证书列表默认存放的地址是 /etc/pki/tls/cert.pemll 一下发现这个文件就是软链接的 /etc/pki/tls/certs/ca-bundle.crt 文件。

PS:/etc/pki/tls 这个路径就是 YUM 安装的 OpenSSL 的证书路径,使用系统的 OpenSSL 安装的 PHP 的 default_cert_file 也是指向这个路径下的 cert.pem 文件。

4、拷贝相关证书文件到新的 OpenSSL 目录

假设你的 OpenSSL 目录在 /usr/local/openssl

ln -s /etc/pki/tls/cert.pem /usr/local/openssl/cert.pem
ln -s /etc/pki/tls/certs/* /usr/local/openssl/certs

 

OK,然后你就发现邮件可以正常发送了…

花了我大半天时间,摔 (╯°口°)╯(┴—┴


原创文章,转载请以链接形式注明出处:http://blog.ttionya.com/article-1844.html