Gabotronix's avatar

soketi exec_curl error: "OpenSSL/1.1.1u: error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure"

when I try to broadcast an event through laravel and my soketi server, I used certbot to get my SSL certificates to use on my soketi connections, however I'm getting the following error:

[2024-01-22 23:38:51] development.ERROR: exec_curl error: {error} {"error":"OpenSSL/1.1.1u: error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure"} 
[2024-01-22 23:38:51] development.INFO: exec_curl response: {response} {"response":"Array
(
    [body] => 
    [status] => 0
)
"} 
[2024-01-22 23:38:51] development.ERROR: Pusher error: . 

I run soketi through a supervisor daemon that is always running(notice my enviroment variables):

[program:soketi]
process_name=%(program_name)s_%(process_num)02d
command=soketi start 
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
user=Gabotron
numprocs=1
redirect_stderr=true
stderr_logfile=/home/Gabotron/logs/soketi.err.log
stdout_logfile=/home/Gabotron/logs/soketi.out.log
stopwaitsecs=60
stopsignal=sigint
minfds=10240
environment=SOKETI_SSL_CERT="/etc/letsencrypt/live/laraapp.com/fullchain.pem",SOKETI_SSL_KEY="/etc/letsencrypt/live/laraapp.com/privkey.pem",SOKETI_DEFAULT_APP_ID="XXXX",SOKETI_DEFAULT_APP_KEY="XXXX",SOKETI_DEFAULT_APP_SECRET="XXXX", PATH="/home/Gabotron/.nvm/versions/node/v14.21.3/bin:%(ENV_PATH)s",NODE_ENV="production"

My client connection:

let options = {
            key: env.PUSHER_APP_KEY,
            wsHost:'laraapp.com',
            wsPort: 6001,
            wssPort: 6001,
            cluster:'eu',
            enableStats: true,
            logToConsole: true,
            encrypted: true,
            forceTLS: false,
            enabledTransports: ['ws', 'wss'],
        };

        let PusherClient = new Pusher(options.key, options);
        PusherClient.connection.bind('error', () => console.log('PusherClient::error', arguments));

        const echo = new Echo({
            broadcaster: 'pusher',
            client: PusherClient,
            ...options
        });

My nginx larapp.com file:

server {
    server_name laraapp.com www.laraapp.com;


        root /var/www/laraapp.com/public;
    index index.php index.html;

    access_log /var/log/laraapp.com/access.log;
    error_log /var/log/laraapp.com/error.log;


    # serve static files directly
        location ~* \.(jpg|jpeg|gif|css|png|js|ico|html)$ {
                access_log off;
                expires max;
                log_not_found off;
        }

        # removes trailing slashes (prevents SEO duplicate content issues)
        if (!-d $request_filename)
        {
                rewrite ^/(.+)/$ / permanent;
        }

        # enforce NO www
        if ($host ~* ^www\.(.*))
        {
                set $host_without_www ;
                rewrite ^/(.*)$ $scheme://$host_without_www/ permanent;
        }

        # unless the request is for a valid file (image, js, css, etc.), send to bootstrap
        if (!-e $request_filename)
        {
                rewrite ^/(.*)$ /index.php?/ last;
                break;
        }

        location / {
                try_files $uri $uri/ /index.php?$query_string;
        }

        location ~* \.php$ {
        try_files $uri = 404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php/php7.3-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.ht {
                deny all;
        }

    location /ws/ {
        proxy_pass http://127.0.0.1:6001; # Point to the Soketi port
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
    }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/laraapp.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/laraapp.com/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot


}

server {
    if ($host = www.laraapp.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    if ($host = laraapp.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    listen 80;
    server_name laraapp.com www.laraapp.com;
    return 404; # managed by Certbot




}


My broadcasting file:

'pusher' => [
            'driver' => 'pusher',
            'key' => env('PUSHER_APP_KEY'),
            'secret' => env('PUSHER_APP_SECRET'),
            'app_id' => env('PUSHER_APP_ID'),
            'log' => true,
            'options' => [
                'host' => env('PUSHER_HOST', '127.0.0.1'),
                //'port' => env('PUSHER_PORT', 6001),
                'port' => 443,
                'scheme' => env('PUSHER_SCHEME', 'http'),
                'encrypted' => true,
                'useTLS' => env('PUSHER_SCHEME') === 'https',
                'cluster' => env('PUSHER_APP_CLUSTER'),
                'curl_options' => [
                    CURLOPT_SSL_VERIFYHOST => 0,
                    CURLOPT_SSL_VERIFYPEER => 0,
                ],
            ],
        ],

My .env file

PUSHER_APP_KEY="XXXX"
PUSHER_APP_SECRET="XXXX"
PUSHER_APP_ID="XXXX"
PUSHER_APP_CLUSTER="eu"
SOKETI_DEBUG=1
PUSHER_HOST=127.0.0.1
PUSHER_PORT=6001
PUSHER_SCHEME=https

Package versions: "pusher/pusher-php-server": "^5.0", "pusher-js": "^7.0.3", "laravel-echo": "^1.11.3",

Please help, I have been stuck for a while

0 likes
1 reply
kiwi0134's avatar

Where exactly do you get the first error? I assume it's inside your Laravel log as curl_exec is also a function in PHP. If this is the case, the following might be the problem:

  1. You start soketi with a certificate for a hostname.
  2. You instruct Laravel to connect to it over HTTPS by IP.
  3. Curl somehow fails with the mysterious error message. I assume that it cannot verify your certificate or doesn't know about the CA for some reason. This is just speculation.

If you're not transmitting any really sensitive data that requires encryption in local transport, I'd suggest to let Laravel and nginx connect to soketi without a TLS connection, which also prevents some overhead by TLS. For external access, you'd use nginx to terminate the TLS connection and reverse proxy to your local soketi instance.

If you're running your application spread across multiple servers or networks that you don't control, encryption should be in place even for internal traffic to prevent anyone from sniffing. In this case you could easily use self-signed certificates to encrypt your local traffic. Make sure that your servers and applications know about your own CA.

Please or to participate in this conversation.