15

I'm trying to send an email with this configuration:

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,

];

When I submit the form I receive this 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

I found this solution where people seems to have solved the problem with the same library but I cant manage to solve it in Laravel.

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

Javier Arias
  • 2,329
  • 3
  • 15
  • 26
Alan
  • 2,559
  • 4
  • 32
  • 53

5 Answers5

26

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.

Add this at bottom of your config/mail.php

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

this will solve your problem.

miken32
  • 42,008
  • 16
  • 111
  • 154
M Arfan
  • 4,384
  • 4
  • 29
  • 46
  • 2
    People should be very aware that using this solution should be very aware that this is only slightly more secure than not using encryption at all while using proper SSL with peer verified certificates is much much more secure. Only use this if you 100% know you need to use a self signed certificate and you are 100% certain it's not been tampered with, and never use this in production. – apokryfos Aug 14 '18 at 08:53
13

In case you are using Laravel 7.0 you can disable SSL verification in SwiftMailer this way (please note that disabling SSL verification is not recommended!):

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,
            ],
        ],
    ],
],

EDIT: Since Laravel 9 depreciated SwiftMailer has been replaced with Symfony Mailer. According to update guide they way you disable TLS peer verification has changed as well.

'smtp' => [
    // Laravel 8.x...
    'stream' => [
        'ssl' => [
            'verify_peer' => false,
        ],
    ],
 
    // Laravel 9.x...
    'verify_peer' => false,
],
7

In Laravel 9 defining stream options for the SMTP transport is no longer supported. Instead, you must define the relevant options directly within the configuration if they are supported. For example, to disable TLS peer verification:

'smtp' => [
    // Laravel 8.x...
    'stream' => [
        'ssl' => [
            'verify_peer' => false,
        ],
    ],
 
    // Laravel 9.x...
    'verify_peer' => false,
],
Adam M.
  • 91
  • 2
  • 5
6

Well in that link you provided the solution is straight-forward.

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

how to fix it? in config/mail.php ,'driver' => env('MAIL_DRIVER', 'smtp'), should be 'driver' => env('MAIL_DRIVER', 'mail'), (credits: Danyal Sandeelo)

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
geggleto
  • 2,605
  • 1
  • 15
  • 18
4

In my case the problem was related to SSL. My SMTP has a self-signed certificate and my laravel was running on top of PHP 5.6 which disables the 'allow_self_signed' context variable to false and enables 'verify_peer' and hence poping the error when sending an email.

Since I didn't wanted to hack around swiftmailer code I added the Certificate Authority (CA) file of my server as trusted CA for my system executing laravel.

I did that getting the CA cert of my smtp server, something like

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

and write it in my laravel machine which has an ubuntu 14.04 to a file named /usr/local/share/ca-certificates/my_cert.crt. It is crucial to end the file with .crt and also make it readable for everyone.

Then call update-ca-certificates and the certificate will be added to the list of valid CAs of your server.

mosh442
  • 708
  • 2
  • 6
  • 15