How to Create Secure(TLS/SSL) Websocket Server
Asked Answered
T

3

61

I am using WS websocket library of node.js. Currently I'm running ws server. Now I want to secure this connection by using secure connections i.e by implementing wss protocol and also library support TLS connection. I searched a little and found this plain to secure: wss and this wss with self signed certificate .

Both are not very detailed and the article on the second link describes wss with self signed certificate. What i want to know is if it is enough to just create the self signed certificate and deploy to my production environment or do I need to buy a certificate as we need to do while creating HTTPS servers?

Tarnation answered 10/7, 2015 at 10:50 Comment(1)
Thank you for that second link. The answer I posted is based on it.Susurrus
C
85

Your question #1

How to Create Secure(TLS/SSL) Websocket Server?

I found your question while searching online for a guide on how to make websockets work over a secured connection. Since this came up in search results, there is a chance I'm not the only one who ended up on this page. To save everyone (including future me) some time, here goes.

The Problem

I had a simple node.js websocket server, powered by einaros/ws, listening on port 80 over an unsecured connection. Had to switch it to secure connection.

The Solution

Basically, the second link you provided covers pretty much everything I needed to know. Here are few things that took me some time to figure out though:

  • I needed the .pem files for this, but all I got from the cert provider was a simple .crt/.cert file, and I also had a private .key I got after generating the initial .csr request. So here's how to convert (credit to slf):

     openssl rsa -in server.key -text > private.pem
     openssl x509 -inform PEM -in server.crt > public.pem
    
  • It was unclear to me how to make ws use the secured connection. Since I was trying to add SSL to an existing application, I wanted to avoid having to re-do things. Turns out, all I had to do was replace the {port:80} parameter with a reference to the https instance (see the links for more info on how to initialise it).

     var ws = require('ws').Server;
     var wss = new ws({
         server: httpsServer
     });
    

References

Your question #2

What i want to know is if it is enough to just create the self signed certificate and deploy to my production environment, or do I need to buy a certificate as we need to do while creating HTTPS servers?

For a public server, you will need a certificate from a widely trusted CA. Use the free Let's Encrypt, or any paid certificate from a known issuer. This will ensure your users won't be getting any browser security warnings, or just leaving without even knowing what went wrong.

For your local development environment, or where all connecting clients are known and under your control, you can create your own CA, see deliciousbrains.com/ssl-certificate-authority-for-local-https-development.

Chad answered 25/3, 2016 at 1:12 Comment(8)
A free certificate from Let's Encrypt will certainly to the job. [ letsencrypt.org ]Corncrib
Do you know if it is possible to reuse the same https server for access from both wss:// and https://?Corody
@shaikmoeed replaced with a web archive copy, thanks for the heads upSusurrus
@Corody yes, the closest I got was 1). var httpsServer = https.createServer({key: fs.readFileSync('./privkey.pem', 'utf8'), cert: fs.readFileSync('./fullchain.pem', 'utf8') }, function( req, res ) {res.writeHead(200);res.end('<b>Hello World!</b>');}).listen(443); followed by 2). var wss = new ws({server: httpsServer});httpsServer = null;Susurrus
If this doesn't work, and you "know" your cert is valid, make sure it's actually loading the right one by decoding the cert with a tool like this one. I thought I was loading my actual Letsencrypt cert. But somehow I got file paths mixed up and was loading a self-signed one I had nearby.Veasey
Certbot generated the pem files needed, and remember to listen on port 443Quarantine
This answer, while good, is extremely datedNofretete
@Corody if you're still there, I've fully explained how to do it in modern systems in my answerNofretete
S
16

to use secure web socket in nodejs use this code sample:

const WebSocket = require("ws").Server;
const HttpsServer = require('https').createServer;
const fs = require("fs");

server = HttpsServer({
    cert: fs.readFileSync(config.ssl_cert_path),
    key: fs.readFileSync(config.ssl_key_path)
})
socket = new WebSocket({
    server: server
});

socket.on(...);
server.listen(config.port);

in case you don't have ssl certificate yet - you can get one for free from letsencrypt.org

Sulphurate answered 23/3, 2021 at 18:15 Comment(0)
N
0

Huge tip: you need a separate http server for the wss server

For years I struggled to launch both a https web server (on port 443) and a wss socket server (on say port 2345) opn the same node.js script.

The solution is simple, you just add (one line of code) a https server specifically for the wss server.

(Indeed, you just make one for each wss server you are operating.)

Hence,

get a letscreate cert:

On the shell create your certs. Stop your webserver for a minute and:
% certbot certonly --standalone

In node.js

const cts = {
    cert: fs.readFileSync("/etc/letsencrypt/-blah-/fullchain.pem"),
    key: fs.readFileSync("/etc/letsencrypt/-blah-/privkey.pem")
}

// create https (443)
app = express()
app.use .. etc etc
app.get .. etc etc
https.createServer(cts, app).listen(443)

// bounce http (80)
const bounce = express()
bounce.get("*", (req, res, next) => {res.status(403)})
appHttpBounce.listen(80)

// create https SPECIFICALLY FOR wss (2345)
let for_2345 = https.createServer(options).listen(2345)
let wss = new WSServer({
    server: for_2345,
    perMessageDeflate: false
})
wss.on( etc etc )

// create https SPECIFICALLY FOR wss (2666)
let for_2666 = https.createServer(options).listen(2666)
let wss_admin = new WSServer({
    server: for_2666,
    perMessageDeflate: false
})
wss_admin.on( etc etc )

And that's how it's done.

Nofretete answered 27/2 at 16:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.