PHPMailer генерирует PHP Warning: stream_socket_enable_crypto(): сертификат партнера не соответствует ожидаемому
Я использую PHPMailer на PHP 5.6, повышенная безопасность вокруг сертифицированного в PHP 5.6, безусловно, забавная.
Я пытаюсь отправить тестовое сообщение в домен, размещенный на dreamhost, ошибка, возвращаемая PHPMailer, заключается в следующем: Не удалось подключиться к узлу SMTP.
Эта ошибка неверна, но я включил ведение журнала, и вот что происходит на самом деле.
Соединение: открытие в mx1.sub4.homie.mail.dreamhost.com:25, timeout = 30, options = array() Соединение: открыт S: 220 homiemail-mx32.g.dreamhost.com ESMTP
C: EHLO s81a.ikbb.com
S: 250-homiemail-mx32.g.dreamhost.com 250-PIPELINING 250-SIZE 40960000 250-ETRN 250-STARTTLS 250-ENHANCEDSTATUSCODES 250 8BITMIME
C: STARTTLS
S: 220 2.0.0 Готовность запуска TLS
C: QUIT
S: Ошибка SMTP ERROR: команда QUIT: соединение: закрыто
Я не мог понять, почему PHPMailer просто сдаётся, выдавая команду QUIT, когда она должна начать отправлять сообщение. Я получил еще один ключ из другого журнала:
Предупреждение PHP: stream_socket_enable_crypto(): сертификат peer CN = *.mail.dreamhost.com' did not match expected CN=
mx1.sub4.homie.mail.dreamhost.com 'в/home/ikbb/domains/dev.ikbb.com/public_html/includes/phpmailer/5.2 0,10/class.smtp.php
Если я использую некоторые настраиваемые параметры, чтобы предотвратить проверку сертификата, который они используют, я могу заставить его продолжить. Вот что я имею:
$mail->SMTPOptions = array (
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true));
Если я помещаю SMTPOptions туда и пропускаю проверку сверстников, сообщение идет в порядке - без предупреждения в PHP вообще.
Как я могу уловить эту ошибку, поэтому я знаю, что есть проблема, но все равно отправить сообщение?
Ответы
Ответ 1
У меня была та же проблема, и я нашел ответ в документации PHPMailer.
Ошибка проверки сертификата PHP 5.6
При изменении предыдущих версий PHP 5.6 проверяет сертификаты на соединениях SSL. Если конфигурация SSL сервера, к которому вы подключаетесь, неверна, вы получите такую ошибку:
Warning: stream_socket_enable_crypto(): SSL operation failed with code 1.
OpenSSL Error messages: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
Правильное исправление для этого - заменить неверный, неправильно сконфигурированный или самоподписанный сертификат с хорошим. В противном случае вы можете разрешить небезопасные подключения через свойство SMTPOptions, представленное в PHPMailer 5.2.10 (это можно сделать путем подклассификации класса SMTP в более ранних версиях), хотя это не рекомендуется:
$mail->SMTPOptions = array(
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
)
);
Вы также можете изменить эти настройки глобально в своем php.ini, но это действительно плохая идея; PHP 5.6 сделал это изменение по очень веским причинам.
Иногда такое поведение не так очевидно; иногда ошибки шифрования могут появляться как клиент, выдающий QUIT сразу после попытки сделать STARTTLS. Если вы видите, что это произойдет, вы должны проверить состояние своих сертификатов или параметры проверки.
Ответ 2
Для PHP 5.6 используйте следующее. Добавление "tls://" - это ключ.
$mail->Host = gethostbyname('tls://smtp.gmail.com');
Смотрите: http://php.net/manual/en/context.ssl.php
Ответ 3
Возможно, вы, возможно, уже решили свою проблему. Но поскольку другой разработчик может быть замешан в этом, я предложу что-то, что сработало для меня.
У меня была такая же проблема с Laravel 4.2 Swiftmailer вместо PHPMailer, но с учетной записью Dreamhost VPS. Я не хотел взламывать параметры SMTP verify_peer, allow_self_signed или устанавливать шифрование с ssl на null.
Я не хотел ни покупать про-сертификат для моего VPS, и я еще не готов к выпуску.
Что я пробовал, что не работал с mail.php:
<?php
return array(
'driver' => 'smtp',
'host' => 'mail.mywebsite-staging.com',
'port' => 25,
'from' => array('address' => '[email protected]', 'name' => 'MyWebsite Staging'),
'encryption' => 'tls',
'username' => '[email protected]',
'password' => 'myPASS',
'sendmail' => '/usr/sbin/sendmail -bs',
'pretend' => false
);
?>
Я нашел эту Dreamhost документацию о несоответствии сертификатов домена, в которой говорится, что наш сертификат почтового сервера уходит в отставку из поддомена (2 уровня) почты dreamhost (*.mail.dreamhost.com), где * - группа, содержащая несколько учетных записей электронной почты.
Вам нужно перейти к:
- Веб-панель Dreamhost > Поддержкa > Центры обработки данных
и вы увидите, к какой группе принадлежит ваш почтовый сервер, поэтому вы узнаете, какой хост должен использовать в mail.php.
- homiemail-sub3 = > sub3.mail.dreamhost.com
- homiemail-sub4 = > sub4.mail.dreamhost.com
- homiemail-sub5 = > sub5.mail.dreamhost.com
- homiemail-master = > homie.mail.dreamhost.com
Моя была homiemail-sub4, затем я использовал 'host' = > 'sub4.mail.dreamhost.com',
Тогда нет проблемы с сертификатом.
Если вы используете Mail Server от другого провайдера, попробуйте проверить, что это диктовка используется также для вашего почтового сертификата.