使用PHPMailer时SMTP连接在STARTTLS阶段失败的排查求助
结合你的环境(Ubuntu 18.04、OpenSSL 1.1.1、PHP 7.2、PHPMailer 5.2.8)和日志信息,核心问题大概率是TLS协议/套件兼容性导致的——多数邮件服务商在2025年陆续淘汰了TLS 1.0/1.1,而旧版本的PHPMailer和PHP默认加密配置不支持TLS 1.2+,最终引发加密后连接异常。以下是具体排查步骤:
1. 验证目标SMTP服务器的TLS支持
用OpenSSL命令直接测试服务器支持的TLS版本:
openssl s_client -connect smtp.yourserver.com:587 -starttls smtp
查看输出中的Protocol字段,如果显示只有TLSv1.2或TLSv1.3,说明你的环境默认加密方法不匹配,这就是问题根源。
2. 强制指定TLS 1.2/1.3加密
修改PHPMailer的SMTP加密配置,或者直接调整class.smtp.php中的加密逻辑:
- 方法一(推荐,无需修改核心文件):在业务代码中添加SMTPOptions配置:
$mail->SMTPOptions = array( 'ssl' => array( 'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT | STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT, 'verify_peer' => true, 'verify_peer_name' => true ) ); - 方法二(修改SMTP类):把
class.smtp.php第298行的STREAM_CRYPTO_METHOD_TLS_CLIENT替换为:
PHP 7.2+和OpenSSL 1.1.1已支持TLS 1.3,这样可以强制使用高版本协议。STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT | STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT
3. 测试Cipher套件兼容性
部分服务器会限制仅支持现代Cipher套件,用以下命令测试是否能正常握手:
openssl s_client -connect smtp.yourserver.com:587 -starttls smtp -cipher ECDHE-ECDSA-AES256-GCM-SHA384
如果能成功连接,说明你的系统默认Cipher列表缺少该套件,可以在php.ini中更新openssl.ciphers配置,或者在SMTPOptions中指定ciphers参数。
4. 升级PHPMailer到5.2分支最新版
PHPMailer 5.2.8非常陈旧,5.2分支的最后一个版本是5.2.27,其中修复了多个TLS相关的兼容性问题,且无需修改业务代码——直接替换class.phpmailer.php和class.smtp.php即可,不会破坏现有逻辑。
5. 排除证书验证问题(测试用)
虽然日志显示SSL: Success,但仍可临时关闭证书验证排查:
$mail->SMTPOptions = array( 'ssl' => array( 'verify_peer' => false, 'verify_peer_name' => false, 'allow_self_signed' => true ) );
如果问题解决,说明服务器证书链存在问题(比如根证书过期),但这种概率较低,建议测试后恢复验证。
补充说明
你提到手动telnet能正常登录,是因为telnet走明文连接,没有触发TLS加密环节;换SMTP服务器仍报错,说明问题出在你的客户端环境,而非目标服务器。
内容的提问来源于stack exchange,提问作者Ben Holness

