is there any example about secure inter-server communication in node.js?
Is socket.io necessary to realize this or I may use express too?
I would like to realize mutual authentication between two servers.
Thanks to all!!!
This is an example of what i've done; unfortunately it doesn't work...
Server 1
...
var ioc = require('socket.io-client');
var socketc = ioc.connect("https://127.0.0.1:5000", {'force new connection':true, 'secure':true});
...
Server 2
var fs = require('fs');
var https = require('https');
var io = require('socket.io');
var crypto = require('crypto');
// path to private key and certificate
var pathSSH = 'C:\\cert\\';
//array containing private key and certificate
var options = {
key: fs.readFileSync(pathSSH + 'keySatellite.pem'),
cert: fs.readFileSync(pathSSH + 'keySatellite-cert.pem')
};
var port = 5000;
var server = https.createServer(options, function(req, res) {
console.log('Connection with satellite node');
});
var sio = io.listen(server);
// ...listening at port XXXXX
server.listen(port, function(){
console.log("HTTPS server listening on port " + port);
});
sio.sockets.on('connection', function(socket) {
console.log('connected');
socket.disconnect();
});
UPDATE 1
I've noticed that server to server communication works fine if I set a http connection instead of https.
Related
Server side code:
var io = require('socket.io').listen(8150);
io.sockets.on('connection', function (socket){
});
Client side code:
var socketIO = io('*.*.*.*:8150');
socketIO.once('connect', function(){
});
On http it's worked on https in same page it not connected.
Searched many examples, but all example for express. I dont create any http server in node.js need only to socket.io work.
When running the client over HTTPS, socket.io is attempting to connect to your server over HTTPS as well. Currently your server is only accepting HTTP connections, the listen(port) function does not support HTTPS.
You'll need to create an HTTPS server and then attach socket.io to it, something like this.
var fs = require('fs');
var options = {
key: fs.readFileSync('certs/privkey.pem'),
cert: fs.readFileSync('certs/fullchain.pem')
};
var app = require('https').createServer(options);
var io = require('socket.io').listen(app);
app.listen(8150);
io.sockets.on('connection', function (socket) {
});
And if you need both HTTP and HTTPS, you can start two servers and attach socket.io to both.
var fs = require('fs');
var options = {
key: fs.readFileSync('certs/privkey.pem'),
cert: fs.readFileSync('certs/fullchain.pem')
};
var httpServer = require('http').createServer();
var httpsServer = require('https').createServer(options);
var ioServer = require('socket.io');
var io = new ioServer();
io.attach(httpServer);
io.attach(httpsServer);
httpServer.listen(8150);
httpsServer.listen(8151);
io.sockets.on('connection', function (socket) {
});
Then on the client side you can determine which port to connect to based on whether the page was accessed over HTTP or HTTPS.
var port = location.protocol === 'https:' ? 8151 : 8150;
var socketIO = io('*.*.*.*:' + port);
socketIO.once('connect', function() {
});
Use letsencrypt with Plesk for a valid SSL certificat.
options = {
key: fs.readFileSync('/usr/local/psa/var/modules/letsencrypt/etc/live/mydomain.com/privkey.pem'),
cert: fs.readFileSync('/usr/local/psa/var/modules/letsencrypt/etc/live/mydomain.com/cert.pem'),
ca: fs.readFileSync('/usr/local/psa/var/modules/letsencrypt/etc/live/mydomain.com/chain.pem'),
rejectUnauthorized: false,
requestCert: true,
agent: false
}
I have set up a node.js-server for running a chat service used by our site. It works. However some customers are NOT able to connect (is done automatically via javascript). They never pop up in the list of connected users (in ie 7,8,9).
My site is running on https (port 443) and therefore my node.js-server is also running on SSL (port 8443) (with the same certificate).
I am using Node 0.6.20 (have tried numerous other versions). I have the following package-setup:
{
"name":"My Chat",
"description":"Chat app using socket.io",
"version":"0.0.1",
"dependencies":{
"express":"3.x.x",
"socket.io":"~0.8.7"
},
"engines":{"node":"0.6.20"}
}
and my node server looks like this:
var fs = require('fs');
var express = require('express');
var https = require('https');
var sio = require('socket.io');
var https_options = {
pfx: fs.readFileSync('cert/certificate.pfx'),
passphrase: "password"
};
var PORT = 8443;
var HOST = '0.0.0.0';
var myArray = new Object();
var userArray = {};
var nicknames = {};
app = express();
app.use(app.router);
server = https.createServer(https_options, app).listen(PORT, HOST);
console.log('HTTPS Server listening on %s:%s', HOST, PORT);
var io = sio.listen(server);
io.set("transports", [ 'websocket'
, 'flashsocket'
, 'htmlfile'
, 'polling'
, 'xhr-polling'
, 'jsonp-polling']);
// routes
app.get('/hey', function(req, res) {
res.send('HEY!');
});
app.post('/ho', function(req, res) {
res.send('HO!');
});
io.sockets.on('connection', function (socket) {
});
I tried debugging using http server, and socket.io worked, however when I try to use https socket.io stopped working
// create server for http and https
//var httpserver = http.createServer(app).listen('3000', '127.0.0.1');
var https_server = https.createServer(options, app).listen('4000', '127.0.0.1');
// let the backend listens to this server
UserServer.listen(https_server);
//UserServer.listen(httpserver);
exports.listen = function(server){
io = socketio.listen(server);
io.sockets.on('connection', function(socket){
console.log("Socket is connected, sweet ");
});
}
When
var httpserver = http.createServer(app).listen('3000', '127.0.0.1');
UserServer.listen(httpserver);
Print out
Socket is connected, sweet "
When
var https_server = https.createServer(options, app).listen('4000', '127.0.0.1');
UserServer.listen(https_server);
There are no output
Here are my set up for https
var express = require('express'),
https = require('https'),
fs = require('fs');
var options = {
key: fs.readFileSync('./key.pem', 'utf8'),
cert: fs.readFileSync('./cert.pem', 'utf8')
};
I was able to display the https page, so I am guessing https setup was not the problem
Any advice would be appreciated, thanks
First of all, you need to run Node.js Server with SSL.
Server.js
var fs = require('fs');
var options = {
key: fs.readFileSync('ssl/private/domain.com.key'),
cert: fs.readFileSync('ssl/certs/domain.com.crt'),
ca: fs.readFileSync('ssl/certs/domain.com.cabundle')
};
// You can do this easily if you are on windows
// var options = { pfx: fs.readFileSync('/home/mydir/secure.pfx'); };
var app = require('https').createServer(options, handler),
io = require('socket.io').listen(app);
//Recommended Production settings
io.enable('browser client minification'); // send minified client
io.enable('browser client etag'); // apply etag caching logic based on version number
io.enable('browser client gzip'); // gzip the file
io.set('log level', 1); // reduce logging
io.set('flash policy port', 3300); //==> override Flash Policy Port
io.set('transports', [ // enable all transports (optional if you want flashsocket)
'websocket'
, 'flashsocket'
, 'htmlfile'
, 'xhr-polling'
, 'jsonp-polling'
]);
function handler(req, res) {
res.writeHead(200);
res.end("welcome sir!");
};
io.sockets.on('connection', function (socket) {
socket.on('message', function (data) {
socket.broadcast.emit('message', data);
});
});
app.listen(3300);
Client.js
//socketAddress is server uri ex. https://www.domain.com:3300
var socket = io.connect(socketAddress, {'flash policy port':3300} );
socket.on('connect', function (data) {
//....
});
socket.on('message', function (data) {
//....
});
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?
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'); });
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(){});
});
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.
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 });
Server:
// Load libraries
var https = require('https');
var fs = require('fs');
var socketio = require('socket.io');
// The server options
var srvAddress = '123.123.123.123';
var srvPort = 8888;
var srvOptions = {
key: fs.readFileSync('ssl/cert.key'),
cert: fs.readFileSync('ssl/cert.crt'),
ca: fs.readFileSync('ssl/cert-ca.crt')
};
// Create a Basic server and response
var app = https.createServer(srvOptions, function(req, res) {
res.writeHead(200);
res.end('Online...');
});
// Create the Socket.io Server over the HTTPS Server
var io = socketio.listen(app, srvAddress);
// Now listen in the specified Port
app.listen(srvPort, srvAddress);
Client:
var socket = require("socket.io-client").connect('https://123.123.123.123:8888', {secure: true});
But client don't connect to server. I tried http instead of https, but the same result.
Server works fine. Without ssl certificate connection works. When try to open via web, then all works too.