1

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

PHP info OpennSSL section enter image description here

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)

SuprMan
  • 350
  • 4
  • 16
  • Is `cwh5.canadianwebhosting.com` the mail server or the phpMailer server? Is it a shared host? I once had a similar problem and my issue was resolved but fixing the certificate chain, as mentioned here: https://stackoverflow.com/questions/46604114/python-requests-ssl-error-certificate-verify-failed – Altimus Prime Jan 05 '23 at 03:15
  • `cwh5.canadianwebhosting.com` is the mail server. And it is a shared host. Regarding that solution: based on https://www.ssllabs.com/ssltest/analyze.html?d=cwh5.canadianwebhosting.com it seem that the certificate chain for `cwh5.canadianwebhosting.com` is good so it doesn't seem like the solution would be the same — did I misunderstand? – SuprMan Jan 05 '23 at 03:38
  • 1
    This does look like a chain issue, so I would suggest at least trying to update your CA cert bundle. It's possible that a CA cert has been removed in your update, or they switched to signing with a new one that is not present in your bundle. – Synchro Jan 05 '23 at 08:52
  • Thank you @Synchro I think you're right. What is the correct way to 'update your CA cert bundle' on ubuntu 22.04? I tried `update-ca-certificates` – SuprMan Jan 05 '23 at 21:49

1 Answers1

0

The solution that finally worked for me was to reinstall the ca-certificates package with:

sudo apt-get install --reinstall ca-certificates

It seems pretty obvious now but it took me a long time to figure out. I hope this helps someone!

SuprMan
  • 350
  • 4
  • 16
  • It's covered in [the PHPMailer troubleshooting guide](https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting#certificate-verification-failure). – Synchro Jan 07 '23 at 01:11
  • The troubleshooting guide covers manually installing a ca-certificate, which as I mentioned in my question I was hoping to avoid, but it does not seem to cover repairing the distribution-supplied certificates package. Perhaps I'm wrong but this seems like a much preferable solution where possible because it will continue to be updated automatically by apt instead of needing to be kept up to date manually. – SuprMan Jan 09 '23 at 21:11
  • It's not PHPMailer's job to document how to manage every server OS, but the guide does say "To update your CA certificates, make sure your operating system is fully up to date - CA certs are usually updated via OS updates". It also suggests using Certainty, which is a PHP-based solution independent of the OS. – Synchro Jan 10 '23 at 09:10
  • @Synchro I agree entirely, this is not in anyway PHPMailer's responsibility. I just thought I should share this version of a solution in case it would help other PHPMailer users who ran into this issue on an Ubuntu server. – SuprMan Jan 12 '23 at 01:00