SMTP-драйвер Laravel с шифрованием TLS
Я пытаюсь отправить электронное письмо с этой конфигурацией:
return [
'driver' => 'smtp',
'host' => 'mail.mydomain.com',
'port' => 26,
'from' => ['address' => 'mailer@mydomain.com', 'name' => 'Mailer'],
'encryption' => 'tls',
'username' => env('MAIL_USERNAME'),
'password' => env('MAIL_PASSWORD'),
'sendmail' => '/usr/sbin/sendmail -bs',
'pretend' => false,
];
Когда я отправляю форму, я получаю этот erorr:
ErrorException in StreamBuffer.php line 95:
stream_socket_enable_crypto(): SSL operation failed with code 1.
OpenSSL Error messages:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
Я нашел это решение, когда люди, похоже, решили проблему с той же библиотекой, но мне не удалось решить ее в Laravel.
5 ответов
Хорошо, что в этой ссылке вы предоставили решение просто.
Правильное решение состоит в том, чтобы исправить вашу конфигурацию SSL - это не ошибка PHP!
Добавьте это внизу вашего config/mail.php
'stream' => [
'ssl' => [
'allow_self_signed' => true,
'verify_peer' => false,
'verify_peer_name' => false,
],
],
это решит вашу проблему.
Примечание редактора: отключение проверки SSL имеет последствия для безопасности. Без проверки подлинности соединений SSL/HTTPS злоумышленник может выдать себя за доверенную конечную точку (например, GitHub или какой-либо другой удаленный хост Git), и вы будете уязвимы для атаки типа "человек посередине". Убедитесь, что вы полностью понимаете проблемы безопасности, прежде чем использовать это в качестве решения.
Если вы используете Laravel 7.0, вы можете отключить проверку SSL в SwiftMailer следующим образом (обратите внимание, что отключение проверки SSL не рекомендуется!):
config/mail.php
'mailers' => [
'smtp' => [
'transport' => 'smtp',
'host' => env('MAIL_HOST', 'smtp.mailgun.org'),
'port' => env('MAIL_PORT', 587),
'encryption' => env('MAIL_ENCRYPTION', 'tls'),
'username' => env('MAIL_USERNAME'),
'password' => env('MAIL_PASSWORD'),
'timeout' => null,
'stream' => [
'ssl' => [
'allow_self_signed' => true,
'verify_peer' => false,
'verify_peer_name' => false,
],
],
],
],
В Laravel 9 определение параметров потока для транспорта SMTP больше не поддерживается. Вместо этого вы должны определить соответствующие параметры непосредственно в конфигурации, если они поддерживаются. Например, чтобы отключить одноранговую проверку TLS:
'smtp' => [
// Laravel 8.x...
'stream' => [
'ssl' => [
'verify_peer' => false,
],
],
// Laravel 9.x...
'verify_peer' => false,
],
В моем случае проблема была связана с SSL. Мой SMTP имеет самозаверяющий сертификат, и мой laravel работал поверх PHP 5.6, который отключает переменную контекста allow_self_signed в false и включает "verify_peer" и, следовательно, выдает ошибку при отправке электронного письма.
Поскольку я не хотел взламывать код swiftmailer, я добавил файл центра сертификации (CA) моего сервера в качестве доверенного CA для моей системы, выполняющей laravel.
Я сделал это, получив сертификат CA моего сервера SMTP, что-то вроде
-----BEGIN CERTIFICATE-----
MIIElTCCA32gAwIBAgIJAMZjjNg64RQwMA0GCSqGSIb3DQEBCwUAMIGNMQswCQYD
VQQGEwJVUzEMMAoGA1UECBMDTi9BMQwwCgYDVQQHEwNOL0ExJDAiBgNVBAoTG1pp
...
5a8a4QEwWmnAOgHetsOCvhfeGW3yAJPD8Q==
-----END CERTIFICATE-----
и запишите его на моей машине Laravel, которая имеет Ubuntu 14.04 в файл с именем /usr/local/share/ca-certificates/my_cert.crt
, Крайне важно завершить файл .crt
а также сделать его читаемым для всех.
Тогда позвони update-ca-certificates
и сертификат будет добавлен в список действительных центров сертификации вашего сервера.