NodeJs - Secure Web Socket and Client Connection - node.js

I need to convert an application with websocket in a secure-websocket. (under windows)
Im using nodeJs as websocket server and a simple html page to connect to it.
Searching on google and here, I found this approach:
Create a certificate and a key for server. I've followed this tutorial:
https://www.cloudinsidr.com/content/how-to-install-the-most-recent-version-of-openssl-on-windows-10-in-64-bit/
After creating a .key and a .pem, I'have modified my nodejs websocket server to introduce the certificate:
const httpsOptions = {
key: fs.readFileSync('./api/security/cert.key'),
cert: fs.readFileSync('./api/security/cert.pem')
}
this._http = require('http');
this._server = this._http.createServer(httpsOptions , function(req, res) { this.closeCurrentConnections(req,res)}.bind(this));
var serverConfig = {
server: this._server,
autoAcceptConnections: false
}
this._wsServer = new WebSocketServer(serverConfig);
The Websocket server seems up when I start the nodejs
Now, in the client page I had this code:
var websocket_server = "ws://localhost:8128";
var echo_service = new WebSocket(websocket_server,"echo-protocol");
[...]
I changed it with the following code calling this page over HTTPS instead of simple HTTP:
var websocket_server = "wss://localhost:8128";
var echo_service = new WebSocket(websocket_server,"echo-protocol");
[...]
I got an error on client page:
testing_page.html:283 WebSocket connection to 'wss://localhost:8128/' failed: Error in connection establishment: net::ERR_SSL_PROTOCOL_ERROR
I think is due to missing certificate.
I've tried to import my previous create certificate on chrome but I cant import because chrome is especting a .crt and/or other format. I've tried to force .pem but it doens't work.
What Im missing?

Related

nodejs pem generated openssl self signed certificate generation for intranet CIPHER_MISMATCH

I am using the module "pem" for nodejs && express to generate openssl self signed certificates for a demo webserver run over a local intranet.
The issue I am having is that when I attempt to load pages off the webserver I am receiving the error: "The client and server don't support a common SSL protocol version or cipher suite."
How would I be able to utilize pem ( or other ) in a way to allow me run my webserver over https via my intranet?
I am running/testing this on a ubtuntu machine and also testing on a windows machine. Both are generating the same error - the accessible machine over the intranet would be from the linux box. I am using nodejs 10 and tested on firefox, chrome, edge and safari
...
pem.createCertificate({ days: 365, selfSigned: true }, this.start);
...
start(err, keys) {
if (err) {
throw err
}
let server = https.createServer(app,
{ key: keys.serviceKey, cert: keys.certificate });
server.listen(port,
() => console.log(`API/NG running on https://localhost:${port}`)
);
}
According to the documentation of the pem module, the order of arguments is in reverse order, like follows:
var serverOptions = {
key: keys.serviceKey,
cert: keys.certificate
};
var app = express();
var server = https.createServer(serverOptions, app);

HTTPS TLS Settings in Node

I was looking through my codebase today, the portion which sets up the server and found the following lines:
var https = require('https');
https.globalAgent.options.secureProtocol = 'TLSv1_2_method';
function createHttpsServer(app) {
var https = require('https');
var fs = require('fs');
const options = {
secureProtocol: 'TLSv1_2_method',
// ...
};
var server = https.createServer(options, app);
return server;
}
It looked like code duplication to me and I am not sure why these do different things (or do they?).
A colleague of mine told me that the top one is for controlling TLS in HTTPS requests made from NodeJS, which in turn, gives us access to the https.agent which is used for all things related to client HTTP requests.
This was also compared to the ServicePointManager in the .NET world.
So do these methods both do different things? At some point, our code does:
var server = protocol === 'https' ? createHttpsServer(app) : createHttpServer(app);
Wouldn't that be using the same server at the end of the day?
var server = protocol === 'https' ? createHttpsServer(app) : createHttpServer(app);
The above line creates the same server, the only difference is if the protocol is 'https' it will run on HTTPS server (this require SSL certificate) whereas if the protocol is http it will run on HTTP server.

Implementing wss (Secure WebSocket) in Nodejs server

I am trying to implement a secure websocket through a Nodejs server. The server is in the net of our university, and it works fine when I access it from inside the university net. However, I get a "net::ERR_CONNECTION_REFUSED" error when I try to connect from outside, and I made sure that the corresponding port is open.
Here is the code:
var ws_PORT = xxx;
var fs = require('fs');
var https = require('https');
var cert = fs.readFileSync('path/cert.pem', 'utf8');
var key = fs.readFileSync('path/privkey.pem', 'utf8');
var options = {key: key, cert: cert};
var server = https.createServer(options);
server.listen(ws_PORT);
var WebSocket = require('ws');
var wss = new WebSocket.Server({server: server});
wss.on('connection', function(ws) {
console.log('WS_SERV: Connected to port: '+ws_PORT);
// Manage ws
// ...
}
Any ideas...?
Thank you in advance,
If you are inside of a university network then the connection is going to be blocked by the university firewall. You would need to create some kind of port forwarding rule on the firewall but if you aren't an administrator than they aren't going to let you do that and if you are an administrator and already tried that and it is not working then double check the firewall rule and both the public and internal IP.
Or, if you are looking to make this publicly accessible, the easiest would just be to throw it on a VPS behind nginx on Digital Ocean, AWS, or linode

net::ERR_INSECURE_RESPONSE Angular 2 + Node.js + Socket.io

I am developing a web app with Angular 2, Node.js and socket.io. It is working perfectly fine with http, however I wanted to implement https protocol and I hit the wall.
I am getting net::ERR_INSECURE_RESPONSE on any http call from angular to my web api and also when trying to make a socket connection.
Here is what I did:
1) Generated my private key and csr.
2) Requested SSL certificate from Comodo using that csr.
3) Received 2 files from Comodo:
- domain.ca-bundle
- domain.crt
4) I copied those 2 files and my private key to a folder: /etc/apache2/ssl/
5) I modified default-ssl.conf in etc/apache2/sites-available to point to these files:
SSLCertificateFile /etc/apache2/ssl/domain.crt
SSLCertificateKeyFile /etc/apache2/ssl/mypriv.key
SSLCertificateChainFile /etc/apache2/ssl/domain.ca-bundle
plus added:
ServerName domain.io
ServerAlias www.domain.io
6) Enabled https and restarted apache. Verified using SSL analyzer (https://sslanalyzer.comodoca.com/) if my cert is properly set up. It confirmed that connection to my site is now secure, so I assume this part was done properly and now I needed to fix the app and the server to handle https.
7) This is how socket connection is created in angular:
this.socket = io.connect('https://server_ip' + ':3000', {
rejectUnauthorized: false });
This is gonna give me net::ERR_INSECURE_RESPONSE later on
8) Angular app is also making http requests to the server like this:
var headers = new Headers();
headers.append('Content-Type', 'application/json');
let options = new RequestOptions({ headers: headers });
return this.http.post('https://server_ip' + ':3000/register',
JSON.stringify(userModel), options)
.map(res => res.json())
This is gonna give me net::ERR_INSECURE_RESPONSE as well (in response to OPTIONS call)
9) Now on the server side, this is the relevant piece of code:
var https = require('https');
var options = {
ca: splitca('/etc/apache2/ssl/domain.ca-bundle'),
key: fs.readFileSync('/etc/apache2/ssl/mypriv.key'),
cert: fs.readFileSync('/etc/apache2/ssl/domain.crt')
};
var server = https.createServer(options, app);
let io = require('socket.io')(https);
server.listen(3000, () => {
logger.debug('server started on port');
})
Server starts up fine, but any call from angular results in net::ERR_INSECURE_RESPONSE response (tried chrome, mozilla and IE). Both server and angular app are running on the same IP.
Any idea what I might be doing wrong here? Thanks!

'wss://' NodeJS Connection

I am using BinaryJS to stream to a server. But at this moment I put my page in HTTPS (OPENSSL). This is why all create the connection in the client:
var client = new BinaryClient('wss://my_IP:9050');
If I use ws the browser will give error because this is not a protected connection and the page use https. But I am having an error anyway:
WebSocket connection to 'wss://my_IP:9050/' failed: Error in connection establishment: net::ERR_CONNECTION_CLOSED
And the server Code is:
var BinaryServer = require('binaryjs').BinaryServer;
binaryServer = BinaryServer({ port: 9050});
Should the binaryserver using some certificate? I cant understand the reason of the error.
The solution is here:
binaryServer = BinaryServer({
//port: 9000 //BinaryServer will share the same port of httpsServer
server: serverHTTPS, //Server previously defined
});
Based on this link

Resources