Setup Server-Server SSL communication using socket.io in node.js
Asked Answered
C

4

5

I'm trying to setup a server to server link using socket.io over ssl connection. This is my example:

/**
 * Server
 */


var app = require('express')();
var config = require('./config');
var https = require('https');
var http = require('http');
var fs = require('fs');
var server = https.createServer({key: fs.readFileSync(config.ssl.key), cert: fs.readFileSync(config.ssl.cert), passphrase: config.ssl.passphrase}, app);
//var server = http.createServer(app);
var io = require('socket.io').listen(server);

server.listen(config.port);

app.get('/', function (req, res) {
    res.send('Server');
  //res.sendfile(__dirname + '/index.html');
});

io.sockets.on('connection', function (socket) {
  socket.emit('news', { hello: 'world' });
  socket.on('my other event', function (data) {
    console.log(data);
  });
});



/**
 * Client
 */


var io = require('socket.io-client');
//var socket = io.connect('http://localhost', {port: 8088});
var socket = io.connect('https://localhost', {secure: true, port: 8088});
  socket.on('connect', function(){
    socket.on('event', function(data){});
    socket.on('disconnect', function(){});
  });

The code works fine when ran without SSL. I suspect it could be my self-signed certificate not being accepted, but I do not know how to make the client accept it.

Can I accept a self-signed SSL certificate, or is there another approach I can take?

Crimple answered 8/2, 2014 at 20:1 Comment(1)
After some more digging, I found that adding: require('https').globalAgent.options.rejectUnauthorized = false; before "var socket" in the client fixes the problemCrimple
C
10

After some more searching, adding this in the client makes it work:

require('https').globalAgent.options.rejectUnauthorized = false;

/**
 * Client
 */


var io = require('socket.io-client');
//var socket = io.connect('http://localhost', {port: 8088});

require('https').globalAgent.options.rejectUnauthorized = false; 

var socket = io.connect('https://localhost', {secure: true, port: 8088});
  socket.on('connect', function(){
    socket.on('event', function(data){});
    socket.on('disconnect', function(){});
  });
Crimple answered 8/2, 2014 at 20:24 Comment(1)
For new versions of node.js you will also have to add process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0;Gibeonite
P
15

I've had to do things a little differently on the client to get this to work, by manually telling socket.io to use that Agent as well (and the secure: true is implied by https:). Here it is:

// Client
var io = require('socket.io-client');
var https = require('https');
https.globalAgent.options.rejectUnauthorized = false;
var socket = io.connect('https://localhost:3210/', { agent: https.globalAgent });
socket.on('connect', function(){ console.log('connected'); });

This is using socket.io v1.0.2.

Alternatively, I've had success with the following as well, as pointed to here: Socket.io + SSL + self-signed CA certificate gives error when connecting

process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';
var io = require('socket.io-client');
var socket = io.connect('https://localhost:3210/');
socket.on('connect', function(){ console.log('connected'); });
Prosthodontist answered 16/6, 2014 at 0:51 Comment(2)
Worked perfect! I don't use self signed certs, but I want to be able to ignore my certification issues when doing local unit testing against my dev box. This did the trick! ThanksGael
After a whole day searching and trying, your first solution worked for me. The second one with didn't work. Thanks!Scoreboard
C
10

After some more searching, adding this in the client makes it work:

require('https').globalAgent.options.rejectUnauthorized = false;

/**
 * Client
 */


var io = require('socket.io-client');
//var socket = io.connect('http://localhost', {port: 8088});

require('https').globalAgent.options.rejectUnauthorized = false; 

var socket = io.connect('https://localhost', {secure: true, port: 8088});
  socket.on('connect', function(){
    socket.on('event', function(data){});
    socket.on('disconnect', function(){});
  });
Crimple answered 8/2, 2014 at 20:24 Comment(1)
For new versions of node.js you will also have to add process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0;Gibeonite
T
6

The previous answers didn't do it for me. require('https').globalAgent is always undefined.

Did some seaching and found the rejectUnauthorized parameter in the docs (https://nodejs.org/api/tls.html). Not sure if it's related to SocketIO, but it somehow seems to work with self-signed certificates:

var socket = io.connect('//yourhost:8000', {secure: true, rejectUnauthorized: false})

secure: true might be optional, but I like to enforce it anyhow.

Transpolar answered 29/4, 2016 at 9:34 Comment(0)
G
0

While all the above solutions focus on rejectUnauthorized=false, I'd like to suggest an alternative.

const https = require('https');
const rootCas = require('ssl-root-cas').create();
rootCas.addFile('cert/ca.crt');
https.globalAgent.options.ca = rootCas; // optional

const io = require("socket.io-client");
var socket = io.connect("https://...", { agent: https.globalAgent });
Gift answered 13/6, 2018 at 5:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.