laravel-websockets
laravel-websockets copied to clipboard
Problem with config wss, certs, etc
First of all, many thanks to the team for making this package possible. I will detail the exact steps I take to try to configure the wss.
My configuration
- Laravel 5.7
- beyondcode/laravel-websockets 1.3.0
- pusher/pusher-php-server 4.1.5
Nginx with proxy reverse
location /app {
proxy_pass http://127.0.0.1:6001;
proxy_read_timeout 60;
proxy_connect_timeout 60;
proxy_redirect off;
# Allow the use of websockets
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
STEP
- I have created a domain without https.
- Config websockets.php and broadcasting.php (simple config)
- I have uploaded the project and it works without problem, I can enter the panel and see the statistics.
- Seeing that everything works perfectly.
NOW, ACTIVATE WSS
STEP I should mention that I have read and tested many tutorials and issues here.
- I have created some certificates on my server with this command.
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/websockets-selfsigned.key -out /etc/ssl/certs/websockets-selfsigned.crt - Open file config/websockets.php and the configuration
....
....
'apps' => [
[
'id' => env('PUSHER_APP_ID'),
'name' => env('APP_NAME'),
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'enable_client_messages' => true,
'enable_statistics' => true,
],
],
....
....
'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('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('LOCAL_KEY', null),
/*
* Passphrase with which your local_cert file was encoded.
*/
'passphrase' => null,
'verify_peer' => false,
'allow_self_signed' => true,
],
My .ENV
PUSHER_APP_ID=666666
PUSHER_APP_KEY='AAbLk31NuAA'
PUSHER_APP_SECRET='VV6dfnj6K32aCNuFa'
PUSHER_APP_CLUSTER=mt1
PUSHER_SCHEME='https'
LOCAL_CERT='/etc/ssl/certs/websockets-selfsigned.crt'
LOCAL_KEY='/etc/ssl/private/websockets-selfsigned.key'
LOCAL_PEM='/etc/ssl/certs/websockets-selfsigned.pem'
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
- Open file config/brodcasting.php and the configuration
'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'),
'encrypted' => true,
'useTLS' => true,
'host' => '127.0.0.1',
'port' => 6001,
'scheme' => env('PUSHER_SCHEME'),
'curl_options' => [
CURLOPT_SSL_VERIFYHOST => 0,
CURLOPT_SSL_VERIFYPEER => 0,
],
],
],
- Add config for nginx.ssl.conf (Port 443)
location /app {
proxy_pass https://127.0.0.1:6001;
proxy_read_timeout 60;
proxy_connect_timeout 60;
proxy_redirect off;
# Allow the use of websockets
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
- Restart nginx
- Now Testing laravel-websockets panel and fail.
WebSocket connection to 'wss://websockets.ubublog.com:80/app/ygbLk87NuyN?protocol=7&client=js&version=4.3.1&flash=false' failed:

I have followed all the steps as per various tutorials and reviews here and I get this error. If anyone has managed to get wss working, can you tell me where I am going wrong. The steps are simple but there is something wrong with setting it up.
I'm facing the same issue:
beyondcode/laravel-websockets": "^1.13",
"laravel/framework": "^7.24",
"pusher/pusher-php-server": "~4.0"
I don't understand why something so "EASY" to configure is so difficult.
Try port 443, port 80 won't be using the SSL config so is likely what is causing the WSS connection to fail
Try port 443, port 80 won't be using the SSL config so is likely what is causing the WSS connection to fail
I try with port 443 some error.
It is really so "COMPLICATED" to install it or give support, I do not believe that anyone does not work the WSS, it is impossible, I ask the community who has it configured can help us with this.
We use WSS successfully for thousands of clients though we do it in a slightly different way as we use V2 of laravel-websockets behind a load balancer. One thing I can see is you are using a self-signed certificate so it may be best to replace that with one issued by letsencrypt instead as it could also be your browser not liking the self-signed cert
As you are using nginx to proxy the connections, you can remove the SSL config from the socket application instead and purely handle SSL within nginx, then let nginx proxy to the websocket service without SSL as its handled locally on the machine so will be safe
We use WSS successfully for thousands of clients though we do it in a slightly different way as we use V2 of laravel-websockets behind a load balancer. One thing I can see is you are using a self-signed certificate so it may be best to replace that with one issued by letsencrypt instead as it could also be your browser not liking the self-signed cert
As you are using nginx to proxy the connections, you can remove the SSL config from the socket application instead and purely handle SSL within nginx, then let nginx proxy to the websocket service without SSL as its handled locally on the machine so will be safe
I currently have my site: www.demo.com with let'sEncrypt. Now from what I understood you say that inside the proxy stop using wss and instead ws.
What I don't understand is how if from a client X I make the call to ws from outside, that is insecure. That's the part I don't understand how to do that, can't you provide a practical example of how to do it by having a domain with HTTPS but calling ws?
Translated with www.DeepL.com/Translator (free version)
We have it so our clients use wss://domain.com which runs nginx to accept SSL on port 443. This then uses nginx to proxy to the laravel-websockets application under the hood
Within the websockets application we don't configure SSL at all
For our laravel echo clients we use this config
window.Echo = new Echo({ broadcaster: 'pusher', key: process.env.MIX_PUSHER_APP_KEY, wsHost: 'domain.tld', wsPort: 443, authEndpoint: "https://domain.tld/broadcasting/auth", disableStats: true, forceTLS: true });
We have it so our clients use wss://domain.com which runs nginx to accept SSL on port 443. This then uses nginx to proxy to the laravel-websockets application under the hood
Within the websockets application we don't configure SSL at all
For our laravel echo clients we use this config
window.Echo = new Echo({ broadcaster: 'pusher', key: process.env.MIX_PUSHER_APP_KEY, wsHost: 'domain.tld', wsPort: 443, authEndpoint: "https://domain.tld/broadcasting/auth", disableStats: true, forceTLS: true });
What you say makes more sense, I will try to do what you say, this information is very valuable.
Hi, @lukehebb I have tried to make the changes but it has been impossible to make it work, I have tried to follow the steps more or less as you say but I have not succeeded. Can you please add an example of the configuration of nginx, websockets.php and brodcasting.php. I can't think what else to do and although you say you have installed in many clients the wss option, I would appreciate if you could share how you do it. Thanks
Hello, @lukehebb
I've also been struggling to deploy Laravel WebSockets on live server.
After a lot of research I managed to get it to work over WSS successfully
but each time that I try to use it's dashboard, I need to open the link for wss connection in a new tab and access it by changing to https which means sending a GET request to the socket server.
I learned this from a tutorial video on Youtube but I'm not using a self signed certificate instead my laravel application is being served over apache with letsencrypt ssl certificate.
I also use CURLOPT_SSL_VERIFYHOST => 0 and CURLOPT_SSL_VERIFYPEER => 0, and when I remove it it doesn't work.
Why do I need to send a get request in order to activate wss ??????
Please tell me how to solve this issue.
If someone could make a video (youtube) using their own certificate or with letsencrypt, it would be ideal to get out of these doubts and avoid opening so many issues on this topic.
I didn't open any issue on this topic, I just commented there with hope to find solutions for my problem or get some answer from someone regarding the issue.
I would appreciate if you could guide me, to understand the problem and debug the issue.
On Tue, Jul 5, 2022 at 4:59 PM Eduardo @.***> wrote:
If someone could make a video (youtube) using their own certificate or with letsencrypt, it would be ideal to get out of these doubts and avoid opening so many issues on this topic.
— Reply to this email directly, view it on GitHub https://github.com/beyondcode/laravel-websockets/issues/986#issuecomment-1175095034, or unsubscribe https://github.com/notifications/unsubscribe-auth/AM3RE5HBU3QQEDX2ZUUSYB3VSQ5TPANCNFSM5WIGORFQ . You are receiving this because you commented.Message ID: @.***>
I didn't open any issue on this topic, I just commented there with hope to find solutions for my problem or get some answer from someone regarding the issue. I would appreciate if you could guide me, to understand the problem and debug the issue. … On Tue, Jul 5, 2022 at 4:59 PM Eduardo @.> wrote: If someone could make a video (youtube) using their own certificate or with letsencrypt, it would be ideal to get out of these doubts and avoid opening so many issues on this topic. — Reply to this email directly, view it on GitHub <#986 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/AM3RE5HBU3QQEDX2ZUUSYB3VSQ5TPANCNFSM5WIGORFQ . You are receiving this because you commented.Message ID: @.>
I mean that it would be good that some of the people who have managed to run the wss in production with certificates either letsencrypt or other, make a video on youtube with the steps to follow, so we would not be opening issues with this problem.
Yes, It would be great if there was such video available. I tried many things and managed to do it without proxypass or any additional config. I just had to recheck all config files did what was mentioned in the following links: issue #994 the comment from @booladsudan
I am using self-signed cert (with CA cert added into browser) and in my case I had to add following lines: 'ssl' => [ ... 'verify_peer' => false, 'verify_peer_name'=>false, 'allow_self_signed'=>true, ], into websockets.php to make it work.
You could follow the configuration below this settings works for me both development and production:
In your broadcasting.php config file under the pusher object:
'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('LARAVEL_WEBSOCKETS_HOST' , '127.0.0.1'),
'port' => env('LARAVEL_WEBSOCKETS_PORT' , '6001'),
'scheme' => env('LARAVEL_WEBSOCKETS_SCHEME' , 'http'),
'encrypted' => env('LARAVEL_WEBSOCKETS_SECURE' , 'false'),
],
],
Next, in your websockets.php config file try this:
'apps' => [
[
'id' => env('PUSHER_APP_ID'),
'name' => env('APP_NAME'),
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
//'path' => env('PUSHER_APP_PATH'),
'capacity' => null,
'enable_client_messages' => false,
'enable_statistics' => true,
],
],
.....
'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' => false,
],
And finally in your bootstrap.js (if you are using larave echo): This way you can dynamically use your websocket for development and production
let echoConfig = {
broadcaster: 'pusher',
key: process.env.MIX_PUSHER_APP_KEY,
wsHost: window.location.hostname,
wsPort: 6001,
disableStats: true,
forceTLS: false,
};
if(process.env.MIX_APP_ENV == 'production')
{
echoConfig.enabledTransports = ['ws', 'wss'];
echoConfig.wssPort = 6001;
echoConfig.forceTLS = true;
}
Now of course let not forget to add the variables in the .env file:
for development just add these:
MIX_APP_ENV=local
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
for production add these:
LARAVEL_WEBSOCKETS_HOST="yourdomain.com"
LARAVEL_WEBSOCKETS_SCHEME=https
LARAVEL_WEBSOCKETS_SECURE=true
LARAVEL_WEBSOCKETS_PORT=6001
LARAVEL_WEBSOCKETS_SSL_LOCAL_CERT=/etc/letsencrypt/live/yourdomain.com/fullchain.pem # if you are using letsencrypt
LARAVEL_WEBSOCKETS_SSL_LOCAL_PK=/etc/letsencrypt/live/yourdomain.com/privkey.pem # if you are using letsencrypt
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
MIX_APP_ENV=production
Be sure to clear cache and restart websocket
@gkia999 sorry I am not that good explain in videos but try to follow the above. Hope this helps.