how to solve ssl3_get_server_certificate error [duplicate] - php

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

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.

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

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)

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

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.

Related

Laravel beyondcode websockets - doesn't work if verify_peer is true

I'm using the package beyondcode/laravel-websockets.
My problem here is when I set the 'verify_peer' => true the websocket is not working, but when the value is false it is working. Is there anyone here managed to make this to work?
For production website, I want set the verify_peer to true to prevent man-in-the-middle attack.
I have a website, lets say aceraven777.com, it already has SSL installed (in the cPanel it has autoSSL enabled).
In the websockets config I entered the same path (the one that cPanel generated) for the certificate and private key.
The chrome throws an error:
WebSocket connection to 'wss://aceraven777.com:6001/app/asdfswerqwsafasfd?protocol=7&client=js&version=4.3.1&flash=false' failed:
createWebSocket # pusher.min.js:8
This is the error in firefox:
Firefox can’t establish a connection to the server at wss://aceraven777.com:6001/app/asdfswerqwsafasfd?protocol=7&client=js&version=4.3.1&flash=false. pusher.min.js:8:6335
Below are the settings I used:
config/websockets.php
'ssl' => [
/*
* Path to local certificate file on filesystem. It must be a PEM encoded file which
* contains your certificate and private key. It can optionally contain the
* certificate chain of issuers. The private key also may be contained
* in a separate file specified by local_pk.
*/
'local_cert' => env('LARAVEL_WEBSOCKETS_SSL_LOCAL_CERT', null),
/*
* Path to local private key file on filesystem in case of separate files for
* certificate (local_cert) and private key.
*/
'local_pk' => env('LARAVEL_WEBSOCKETS_SSL_LOCAL_PK', null),
/*
* Passphrase for your local_cert file.
*/
'passphrase' => env('LARAVEL_WEBSOCKETS_SSL_PASSPHRASE', null),
'verify_peer' => true,
],
config/broadcasting.php
'pusher' => [
'driver' => 'pusher',
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => [
'cluster' => env('PUSHER_APP_CLUSTER'),
'host' => env('PUSHER_APP_HOST'),
'port' => env('PUSHER_APP_PORT'),
'useTLS' => true,
'scheme' => 'https',
'curl_options' => [
CURLOPT_SSL_VERIFYHOST => 1,
CURLOPT_SSL_VERIFYPEER => 1,
],
],
// Configuration for laravel mix JS
'mix' => [
'host' => env('MIX_PUSHER_APP_HOST'),
'key' => env('MIX_PUSHER_APP_KEY'),
'cluster' => env('MIX_PUSHER_APP_CLUSTER'),
'port' => env('MIX_PUSHER_APP_PORT'),
],
],
You probably need to specify a Certificate Authority file on the local filesystem.
This is the source of 95% of these errors on production servers.
The other 4% are caused by self-signed certificates, which I doubt you have in a production environment.
You will need to modify your config/websockets.php
'ssl' => [
// ...
'capath' => env('LARAVEL_WEBSOCKETS_SSL_CA', null),
],
The CA path typically a directory similar to /etc/ssl/certs/.
If this does not work try allowing self-signed certs:
'ssl' => [
// ...
'allow_self_signed' => true,
],
For more information, you should look at the PHP specification for SSL verify peer.
This article helped me a lot some time ago implementing websockets especially with SSL certificate:
https://christoph-rumpel.com/2020/11/laravel-real-time-notifications
You also have git repositories telling you how to implement with and without SSL.
To me it seems, you are not connecting to the correct port.
PusherJs uses default web ports 80 and 443, as described here: https://pusher.com/docs/channels/library_auth_reference/pusher-websockets-protocol
Change the port inside your .env file

Swift_TransportException:Laravel Swift Mail

I have a Laravel 5 project, and it is having trouble sending mail from our mail server. This mail server is working for another Laravel project with the almost identical setup.
I get the following error:
(1/1) Swift_TransportException
Expected response code 250 but got code "", with message ""
I have my mail.php file setup as such:
<?php
return [
'driver' => env('MAIL_DRIVER', 'smtp'),
'host' => env('MAIL_HOST', 'smtp.mailgun.org'),
'port' => env('MAIL_PORT', 587),
'from' => [
'address' => env('MAIL_FROM_ADDRESS', 'no-reply#xtreme.com.au'),
'name' => env('MAIL_FROM_NAME', 'Xtreme IT'),
],
'encryption' => env('MAIL_ENCRYPTION', 'tls'),
'username' => env('MAIL_USERNAME'),
'password' => env('MAIL_PASSWORD'),
And the .env file that is overwriting those settings:
MAIL_DRIVER=smtp
MAIL_HOST=mail.ourdomain.com.au
MAIL_PORT=25
MAIL_USERNAME=username#ourdomain.com.au
MAIL_PASSWORD=OURPASSWORD
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=no-reply#clientdomain.com.au
MAIL_FROM_NAME="Client"
Is there an easy way to check that my .env file is being used?
I can't work out why the mail will send on one site but not another.
Answering to the question: "Is there an easy way to check that my .env file is being used?"
You can use the env and config helpers doing:
dd(env($var_name), config($var_name));
Using it, you'll can see if they're the same.
If not, is possible that config cache is outdated, so you can try:
php artisan config:clear
and then
php artisan config:cache
Good look!

SSL error in Laravel 5.2 [duplicate]

This question already has answers here:
Laravel certificate verification errors when sending TLS email
(2 answers)
Closed 1 year ago.
I was unable to send an email in laravel 5,when I click send it return this message
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
Here is my .env file
MAIL_DRIVER=smtp
MAIL_HOST=smtp-relay.gmail.com
MAIL_PORT=587
MAIL_USERNAME=**********#gmail.com
MAIL_PASSWORD=*********
MAIL_ENCRYPTION=ssl
file mail.php
return [
'driver' => env('MAIL_DRIVER', 'smtp'),
'host' => env('MAIL_HOST', 'smtp-relay.gmail.comt'),
'port' => env('MAIL_PORT', 587),
'from' => ['address' => null, 'name' => null],
'encryption' => env('MAIL_ENCRYPTION', 'ssl'),
'username' => env('MAIL_USERNAME'),
'password' => env('MAIL_PASSWORD'),
'sendmail' => '/usr/sbin/sendmail -bs',
];
I researched for hours but couldn't resolve this, any advice ?
P/S: I use Windows 10 and XAMPP for Webserver
Change in .env file:
MAIL_DRIVER=smtp to MAIL_DRIVER=mail
Here are two possible solutions:
1) Get rid of "tls" and leave MAIL_ENCRYPTION as blank.
2) If you are on MacOS Sierra and want to keep your 'tls' setting, type these two lines in your terminal/shall:
$ sudo mkdir -p /usr/local/libressl/etc/ssl/certs
$ sudo curl -o /usr/local/libressl/etc/ssl/cert.pem https://curl.haxx.se/ca/cacert.pem
The two lines basically help you create the default folder and import the latest certificate store from curl.haxx.se.
Here is the source article I got if interested: https://andrewyager.com/2016/10/04/php-on-macos-sierra-cant-access-ssl-data/comment-page-1/#comment-52
Hope it helps.
In your config file
the host should be smtp.gmail.com
From and name should not be null
change your mail encryption from ssl to tsl
dont forget to turn on less secure app in your google accout setting
Go to location \vendor\swiftmailer\lib\classes\Swift\Transport\StreamBuffer.php
at line 259 and comment the following:
//$options = array();
and add.
$options['ssl'] = array('verify_peer' => false, 'verify_peer_name' => false, 'allow_self_signed' => true);

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

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

I'm not able to send mail via mailgun using Laravel

I'm facing an issue to send email. I have my website built with Laravel. I have the files set up properly. That happens in 2 files.
The first one contains "driver" which of course is mailgun, "host" (smtp.mailgun.org), "port" (587 and according to my provider it's opened), "encryption" (tls), "username" and "password" (both with the right values).
The second one contains "domain" and "secret" (also both with the right values).
The domain is not the mailgun domain but my own domain, which is ACTIVE after set the Domain Verification and DNS.
The mailgun domain is still there ACTIVE. I don't know if I have to remove it or something. I really don't know what I'm missing here.
IMPORTANT UPDATE
Class 'GuzzleHttp\Client' not found
I'm receiving that message
mail.php
return array(
'driver' => 'mailgun',
'host' => 'smtp.mailgun.org',
'port' => 587,
'from' => array('address' => 'not-reply#xxxxxxxxx.com', 'name' => 'xxxxxxx'),
'encryption' => 'tls',
'username' => "xxxxxxxxxxxxxx",
'password' => "xxxxxxxxxxxxxx",
'sendmail' => '/usr/sbin/sendmail -bs',
'pretend' => false,
);
Obviously, the xxxxxxxxxx are my personal data. I can assure I'm setting the right values. It should work, indeed. :(
services.php
return array(
'mailgun' => array(
'domain' => 'domain-here',
'secret' => 'key-here',
),
'mandrill' => array(
'secret' => '',
),
'stripe' => array(
'model' => 'User',
'secret' => '',
),
);
domain and secret are populated with the right values too.
The #manix suggestion it seems to be the right approach but the version suggested 3.9 is deprecated. So it should be:
"guzzlehttp/guzzle": "~4.0"
As I have the project built with Laravel 4.2.
It should be 5.0 for Laravel 5.0.
Try to require guzzle dependency directly.
Add "guzzle/guzzle": "~3.9#dev" to composer.json like, example:
"require": {
"laravel/framework": "5.0.*",
"guzzle/guzzle": "~4.0"
},
Update your project. The command below shoul be executed in a terminal/console. For example, if your laravel application is hosted in a windows machine, you do:
> cd project/folder/path // change the working path
> composer update // this command update the proyect and dependencies
If you laravel is hosteed in a linux machine the you do:
$ cd /path/a/mi/folder // change the working path
$ composer update // this command update the proyect and dependencies
Test again your application

Categories