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.

https://github.com/PHPMailer/PHPMailer/issues/368

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 и сертификат будет добавлен в список действительных центров сертификации вашего сервера.

Другие вопросы по тегам