15
votes

System: Windows 7

NodeJS version: 0.10.2

WS module: ws, last version

Error:

events.js:72
        throw er; // Unhandled 'error' event
              ^
Error: UNABLE_TO_VERIFY_LEAF_SIGNATURE
    at SecurePair. (tls.js:1283:32)
    at SecurePair.EventEmitter.emit (events.js:92:17)
    at SecurePair.maybeInitFinished (tls.js:896:10)
    at CleartextStream.read [as _read] (tls.js:430:15)
    at CleartextStream.Readable.read (_stream_readable.js:294:10)
    at EncryptedStream.write [as _write] (tls.js:344:25)
    at doWrite (_stream_writable.js:211:10)
    at writeOrBuffer (_stream_writable.js:201:5)
    at EncryptedStream.Writable.write (_stream_writable.js:172:11)
    at write (_stream_readable.js:547:24)

Server:

(function(){

    "use strict";

    var fs = require('fs');

    // you'll probably load configuration from config
    var cfg = {
        ssl: true,
        port: 8080,
        ssl_key: 'crt/server1.key',
        ssl_cert: 'crt/server1.crt'
    };

    var httpServ = require('https') 

    var WebSocketServer   = require('ws').Server;

    var app      = null;

    // dummy request processing
    var processRequest = function( req, res ) {

        res.writeHead(200);
        res.end("All glory to WebSockets!\n");
    };

    if ( cfg.ssl ) {

        app = httpServ.createServer({

            // providing server with  SSL key/cert
            key: fs.readFileSync( cfg.ssl_key ),
            cert: fs.readFileSync( cfg.ssl_cert ),
            //requestCert: true,
            //rejectUnauthorized: false

        }, processRequest ).listen( cfg.port );

    } else {

        app = httpServ.createServer( processRequest ).listen( cfg.port );
    }

    // passing or reference to web server so WS would knew port and SSL capabilities
    var wss = new WebSocketServer( { server: app } );


    wss.on( 'connection', function ( wsConnect ) {

        wsConnect.on( 'message', function ( message ) {

            console.log( message );

        });

    });


}());

Client:

var WebSocket = require('ws');
var ws = new WebSocket('wss://localhost:8080');
ws.on('open', function() {
    ws.send('something');
});

The certificate confirmed.

Help> please!

5

5 Answers

20
votes

I'm using a package called "superagent" and getting the same error. After trying several potential fixes, I came across this one that works for me 100% of the time:

process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";

There's no need to do any requires or whatever : just add this to your code before your network calls and you're good to go.

11
votes

The SSL certificate used by the server in your example is probably not fully trusted by the WebSocket client so NodeJS is throwing an error in its network library on the client-side.

You need to set rejectUnauthorized to false (this is an option that most high-level network libraries will allow you to set via an option that gets passed to the lower level NodeJS networking library).

I skimmed the ws module source code and looks like you should try this:

var ws = new WebSocket('wss://localhost:8080', null, {rejectUnauthorized: false});

NOTE: rejectUnauthorized should only be false during testing/development. Production applications should always use rejectUnauthorized: true for full security.

2
votes

If you do not want to disable your security. Add ca: [cert] option in http /socket client options. Where cert is Certificate of server you are connecting to or CA of the server you are connecting to.

0
votes

I've encountered a similar problem before, you may try to use https.globalAgent.options.secureProtocol = 'SSLv3_method' to set SSLv3 connection for https.

0
votes

As per the nginx official website, they clearly mentioned certificate should be the combination of The server certificate and chained certificates.MoreInfo

enter image description here