1

I have socket server made by laravel-websockets for laravel app, which through normal ws I can make connections to in both the web page and external node.js script using laravel-echo and everything is fine. The problem came with the ssl. The site is working with apache and in laravel-websockets documantation is missing this kind of ssl integration, but found some solutions with making of reverse proxy for apache. The reverse proxy still worked for the normal connection but not for the external node.js script - keep console loging unavailable.

Is something wrong with my configurations or need to do something else, too.

  • virtual host sub domain conf for the reverse proxy
<IfModule mod_ssl.c>
<VirtualHost *:443>
    ServerAdmin admin@admin.com
    ServerName socket.my-domain.com
    ServerAlias www.socket.my-domain.com

    SSLEngine on
    SSLProxyEngine on
    SSLProxyVerify none
    SSLProxyCheckPeerCN off
    SSLProxyCheckPeerName off
    SSLProxyCheckPeerExpire off

SSLCertificateFile /etc/letsencrypt/live/socket.my-domain.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/socket.my-domain.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf

  <Proxy *>
    Order deny,allow
    Allow from all
  </Proxy>

  <Location />
    RewriteEngine on
    RewriteCond %{HTTP:UPGRADE} ^WebSocket$ [NC]
    RewriteCond %{HTTP:CONNECTION} Upgrade$ [NC]
    RewriteRule .* ws://127.0.0.1:40126%{REQUEST_URI} [P,L]

    ProxyPass http://127.0.0.1:40126/
    ProxyPassReverse http://127.0.0.1:40126/
  </Location>


</VirtualHost>
</IfModule>

  • 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'),
                    'useTLS' => false,
                    'encrypted' => true,
                    'host' => env('WEBSOCKET_HOST'),
                    'port' => env('LARAVEL_WEBSOCKETS_PORT'),
                    'scheme' => 'http',
                    'curl_options' => [
                        CURLOPT_SSL_VERIFYHOST => 0,
                        CURLOPT_SSL_VERIFYPEER => 0,
                    ],
                ],
            ]
  • websockets.php
        [
            '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' => 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('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,
    ]

  • .env
BROADCAST_DRIVER=pusher
PUSHER_APP_ID=123456
PUSHER_APP_SECRET=ituc16ngcf
PUSHER_APP_KEY=zns8tgs6r91
PUSHER_APP_CLUSTER=mt1
WEBSOCKET_HOST=127.0.0.1
LARAVEL_WEBSOCKETS_PORT=40126
WEBSOCKETS_URL=socket.my-domain.com
  • external node.js script
global.Pusher = require('pusher-js');
global.Echo = require('laravel-echo');

global.broadcast_auth_path = 'some_auth_link';
global.token = "some authorized token";
global.broadcast_auth_headers = {
    headers: {
        Authorization: "Bearer " + token
    }
};

var echoConfig = {
    broadcaster: 'pusher',
    key: 'zns8tgs6r91',
    cluster: 'mt1',
    wsHost: 'socket.my-domain.com',
    wsPort: 80,
    wssPort = 443,
    authEndpoint: broadcast_auth_path,
    auth: { ... broadcast_auth_headers },
    forceTLS: true,
    encrypted: true,
    disableStats: true,
    enabledTransports: [ 'wss', 'ws'],
}
Pusher.logToConsole = true;

Echo = new Echo(echoConfig);

Echo.connector.pusher.connection.bind( 'error', function( err ) {
    console.log(err);
});

Echo.connector.pusher.connection.bind('connected', function( ) {
    console.log('connected');
});

Echo.connector.pusher.connection.bind('disconnected', function( ) {
    console.log('disconnected');
});

Echo.connector.pusher.connection.bind('connecting', function( ) {
    console.log('connecting');
});
Echo.connector.pusher.connection.bind('initialized', function( ) {
    console.log('initialized');
});
Echo.connector.pusher.connection.bind('unavailable', function() {
    console.log('unavailable');
});
Echo.connector.pusher.connection.bind('failed', function( ) {
    console.log('failed');
});
  • socket server start command php artisan websockets:serve --host=127.0.0.1 --port=40126
Marin I
  • 11
  • 3

1 Answers1

0

The problem was that pusher-js(for nodejs) websockets integration was making problem with pointed ip address from dns and this cause ssl altnames to point to only first subdomain alphabeticaly (which was wrong one in my case).

Simple solution was that to make new subdomain reverse proxy before the first alhabetically(aawss with double aa in front) and everything run smootly.

Dharman
  • 30,962
  • 25
  • 85
  • 135
Marin I
  • 11
  • 3