The following error suddenly started occuring when trying to send email using phpMailer on a production server that had been working correctly:
EMAIL ERROR: phpmailer error:SMTP Error: Could not connect to SMTP host. Connection failed. stream_socket_enable_crypto(): SSL operation failed with code 1. OpenSSL Error messages: error:0A000086:SSL routines::certificate verify failed
Using the same mail server and the same phpMailer setup from my local development machine (which has matching versions of Ubuntu, Apache, OpenSSL, and php) as well as from a different server both work fine.
Here is the result of echo QUIT | openssl s_client -crlf -starttls smtp -connect cwh5.canadianwebhosting.com:587
from the (not) sending server:
depth=2 C = GB, ST = Greater Manchester, L = Salford, O = COMODO CA Limited, CN = COMODO RSA Certification Authority
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=1 C = US, ST = TX, L = Houston, O = "cPanel, Inc.", CN = "cPanel, Inc. Certification Authority"
verify return:1
depth=0 CN = cwh5.canadianwebhosting.com
verify return:1
---
Certificate chain
0 s:CN = cwh5.canadianwebhosting.com
i:C = US, ST = TX, L = Houston, O = "cPanel, Inc.", CN = "cPanel, Inc. Certification Authority"
a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA256
v:NotBefore: Feb 4 00:00:00 2022 GMT; NotAfter: Feb 4 23:59:59 2023 GMT
1 s:C = US, ST = TX, L = Houston, O = "cPanel, Inc.", CN = "cPanel, Inc. Certification Authority"
i:C = GB, ST = Greater Manchester, L = Salford, O = COMODO CA Limited, CN = COMODO RSA Certification Authority
a:PKEY: rsaEncryption, 2048 (bit); sigalg: RSA-SHA384
v:NotBefore: May 18 00:00:00 2015 GMT; NotAfter: May 17 23:59:59 2025 GMT
2 s:C = GB, ST = Greater Manchester, L = Salford, O = COMODO CA Limited, CN = COMODO RSA Certification Authority
i:C = GB, ST = Greater Manchester, L = Salford, O = Comodo CA Limited, CN = AAA Certificate Services
a:PKEY: rsaEncryption, 4096 (bit); sigalg: RSA-SHA384
v:NotBefore: Jan 1 00:00:00 2004 GMT; NotAfter: Dec 31 23:59:59 2028 GMT
---
Server certificate
-----BEGIN CERTIFICATE-----
PHPMailer test code that I'm using:
$phpmailer->isSMTP();
$phpmailer->SMTPDebug = 2;
$phpmailer->SMTPAuth = true;
$phpmailer->SMTPSecure = "tls";
$phpmailer->Port = 587;
$phpmailer->Host = "cwh5.canadianwebhosting.com";
$phpmailer->Username = config::get('email_user');
$phpmailer->Password = config::get('email_pass');
$phpmailer->setFrom("info@mydomain.com", $_SERVER['SERVER_NAME']);
$phpmailer->addAddress("info@mydomain.com", "me");
$phpmailer->Body = "test email from $_SERVER[SERVER_NAME]";
$phpmailer->Subject = "phpmailer test";
$phpmailer->send();
The issue also exists with phplist which uses PHPMailer.
Details of the (not) sending server
Ubuntu 22.04
Apache 2.4.52
OpenSSL 3.0.2
PHP 8.1.2
phpMailer 6.7.1
Using the following workaround works, but since this is a production environment that's not a solution.
$phpmailer->SMTPOptions = array(
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true,
)
);
I tried modifying PHPMailer's stream_socket_enable_crypto to use STREAM_CRYPTO_METHOD_TLS_CLIENT
, STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT
, STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT
, and STREAM_CRYPTO_METHOD_ANY_CLIENT
without success.
One thing I haven't tried is manually downloading a certificate and adding an openssl.cafile
or openssl.capath
value to php.ini. I'm hesitant to do this because it was working well without it (simply using Openssl default config
/usr/lib/ssl/openssl.cnf) and it seems to add an undesirable layer of complexity.
One interesting correlation is that this started on the same day that the server ran out of disk space and crashed. I also ran apt update
on the server after restarting it and I believe there may have been a minor version php update included.
The problem seems very similar to the one outlined in Certificate verify failed SSL Error messages: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE but what appeared to be the solution(s) there (an expired certificate and/or identifies as different domain)