Ошибка отправки почты на виртуальной машине (self-signed certificate)

Опубликовано:
Автор:

Статья для разработчиков, которые сталкиваются с проблемой отправки писем из гостевой операционной системы. Как часто бывает, на решение тривиальной задачи можно потратить много времени. Прямого ответа в Интернете я не нашёл, поэтому делюсь решением.

Контекст. Операционная система: Windows 10. Антивирус: Avast. Виртуальная машина: VMWare. Гостевая операционная система: Ubuntu 22.04.

Через PHPMailer разрабатываемый сайт пытается отправить письмо, но возникает ошибка:

Error sending e-mail:
SMTP Error: Could not connect to SMTP host. Failed to connect to serverSMTP server error: Failed to connect to server

Настройки SMTP для отправки через PHPMailer:

SMTP сервер: smtp.yandex.ru
Порт SMTP: 465
Протокол шифрования: SSL
Пользователь: name@domen.my
Пароль: Пароль от ящика или Пароль приложения (зависит от настроек в Яндексе).

Чтобы понять, что проблема не в Яндексе (не в настройках пароля и пароля приложения), в командной строке гостевой ОС (Ubuntu) нужно выполнить:

echo | openssl s_client -servername smtp.yandex.ru -connect smtp.yandex.ru:465 2>&1 | grep 'Verify return code'

Ответ должен быть:

Verify return code: 0 (ok)

Наш случай, если ответ:

Verify return code: 19 (self-signed certificate in certificate chain)

Смотрим подробнее:

echo | openssl s_client -servername smtp.yandex.ru -connect smtp.yandex.ru:465 2>&1

В результате, среди прочего, видим строки:

depth=1 OU = generated by Avast Antivirus for SSL/TLS scanning, O = Avast Web/Mail Shield, CN = Avast Web/Mail Shield Root
verify error:num=19:self-signed certificate in certificate chain

Становится понятно, что ошибка связана с антивирусом Avast (с его сертификатом). Можно отключить Avast полностью и убедиться, что ошибка этим устраняется. 

Решение 1. Отключаем сканирование исходящей почты антивирусом Avast

В хостовой ОС (Windows 10), в окне управления антивирусом Avast, отключаем сканирование исходящей почты.

Меню > Настройки > Защита > Основные компоненты защиты > Настройте параметры компонента защиты > Защита почты > Сканировать исходящую почту = FALSE

Такое решение не слишком хорошее, потому что мы отключаем часть защиты, но как временная мера, этого может быть достаточно.

Подробная инструкция от Avast: Managing HTTPS scanning in Web Shield in Avast Antivirus
https://support.avast.com/en-us/article/use-antivirus-https-scan/#pc

Решение 2. Установка сертификата Avast в хранилище доверенных сертификатов

1. Экспортировать Avast Mail Shield сертификат (в секретных настройках).

В хостовой ОС (Windows 10), в окне управления антивирусом Avast экспортируем сертификат.

Меню > Настройки > Через поиск ищем: geek:area

В секретной секции Для гиков Avast (здесь я обескуражен) прокручиваем до элемента Export certificate и нажимаем на кнопку Perform — сохраняем файл с расширением der (далее MailShield.der).

Этот файл обычно нужно импортировать в почтовый клиент, но нам нужно импортировать его в хранилище доверенных сертификатов гостевой ОС (Ubuntu).

2. Конвертируем сертификат из DER-формы в PEM-форму

В командной строке гостевой ОС (Ubuntu) нужно выполнить:

sudo openssl x509 -inform der -outform pem -in MailShield.der -out MailShield.crt
3. Устанавливаем сертификат в доверенное хранилище

В командной строке гостевой ОС (Ubuntu) нужно выполнить 3 команды:

sudo apt-get install -y ca-certificates
sudo cp MailShield.crt /usr/local/share/ca-certificates
sudo update-ca-certificates

Теперь команда:

echo | openssl s_client -servername smtp.yandex.ru -connect smtp.yandex.ru:465 2>&1 | grep 'Verify return code'

не приводит к ошибке:

Verify return code: 0 (ok)

Инструкция для 2 и 3 шага от Ubuntu: Installing a root CA certificate in the trust store
https://ubuntu.com/server/docs/security-trust-store