如何处理 Laravel 的 SMTP 驱动程序中的自签名 TLS 证书?

How to deal with self-signed TLS certificates in Laravel's SMTP driver?

我正在尝试使用此配置发送电子邮件:

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,

];

当我提交表单时收到此错误:

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

好吧,link 你提供的解决方案很简单。

The correct solution is to fix your SSL config - it's not PHP's fault!

如何解决?在 config/mail.php 中,'driver' => env('MAIL_DRIVER', 'smtp'), 应该是 'driver' => env('MAIL_DRIVER', 'mail'),(积分:Danyal Sandeelo

在我的案例中,问题与 SSL 有关。我的 SMTP 有一个自签名证书,我的 laravel 是 PHP 5.6 之上的 运行,它将 'allow_self_signed' 上下文变量禁用为 false 并启用 'verify_peer' 和因此在发送电子邮件时弹出错误。

因为我不想破解 swiftmailer 代码,所以我添加了我服务器的证书颁发机构 (CA) 文件作为我的系统执行 laravel 的可信 CA。

我这样做是为了获得我的 smtp 服务器的 CA 证书,例如

-----BEGIN CERTIFICATE-----
MIIElTCCA32gAwIBAgIJAMZjjNg64RQwMA0GCSqGSIb3DQEBCwUAMIGNMQswCQYD
VQQGEwJVUzEMMAoGA1UECBMDTi9BMQwwCgYDVQQHEwNOL0ExJDAiBgNVBAoTG1pp
...
5a8a4QEwWmnAOgHetsOCvhfeGW3yAJPD8Q==
-----END CERTIFICATE-----

并将其写入我的 laravel 机器中,该机器有一个 ubuntu 14.04 到一个名为 /usr/local/share/ca-certificates/my_cert.crt 的文件中。以 .crt 结束文件并使其对每个人都可读是至关重要的。

然后调用update-ca-certificates,证书将添加到服务器的有效 CA 列表中。

Editor's note: disabling SSL verification has security implications. Without verification of the authenticity of SSL/HTTPS connections, a malicious attacker can impersonate a trusted endpoint (such as GitHub or some other remote Git host), and you'll be vulnerable to a Man-in-the-Middle Attack.

Be sure you fully understand the security issues before using this as a solution.

将此添加到 config/mail 的底部。php

'stream' => [
   'ssl' => [
       'allow_self_signed' => true,
       'verify_peer' => false,
       'verify_peer_name' => false,
   ],
],

这将解决您的问题。

如果您正在使用 Laravel 7.0,您可以通过这种方式在 SwiftMailer 中禁用 SSL 验证(请注意,不建议禁用 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,
],