3

I'm having issues setting up a wss server (Secure Websocket Server) in node.js. When we run the server and test it using an online websocket tester and connect to wss://localhost:8888 it works. But when we connect to wss://my_ip:8888 (ip found with ifconfig) it results in the error index.js:15 WebSocket connection to 'wss://192.168.1.217:8888/' failed.

I've made a git repository for easy testing: https://github.com/DaanS8/wss_error

Possible useful info

We pinged the ip on the port 8888 with `telnet my_ip 8888` which was successful. Any other port fails, which means it is listening?

Chrome behaves differently then Firefox, in chrome localhost works but in Firefox localhost doesn't even work whilst using the same tests on the online websocket tester.

The code is running on a ubuntu vm on a windows machine. It seems the ubuntu vm doesn't have its own firwall (sudo ufw status results in error), just turning of the windows firewall doesn't change the errors.

The certificates were generated with the following commands:

openssl genrsa -des3 -out myCA.key 2048
openssl req -x509 -new -nodes -key myCA.key -sha256 -days 1825 -out myCA.pem
      Enter pass phrase for myCA.key:
      Country Name (2 letter code) [AU]:BE
      State or Province Name (full name) [Some-State]:Vlaams-Brabant
      Locality Name (eg, city) []:Leuven
      Organization Name (eg, company) [Internet Widgits Pty Ltd]:KU Leuven
      Organizational Unit Name (eg, section) []:Pno
      Common Name (e.g. server FQDN or YOUR name) []:Team x
      Email Address []:xxxx@xxxxxxxx.be

openssl rsa -in myCA.key -text > private.pem

My main sources:

Code

main.ts:

// Minimal amount of secure websocket server
var fs = require('fs');

// read ssl certificate
var privateKey = fs.readFileSync('certs/private.pem', 'utf8');
var certificate = fs.readFileSync('certs/myCA.pem', 'utf8');

var credentials = { key: privateKey, cert: certificate };
var https = require('https');

//pass in your credentials to create an https server
var httpsServer = https.createServer(credentials);
httpsServer.listen(8888);

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

wss.on('connection', function connection(ws) {
    ws.on('message', function incoming(message) {
        console.log('received: %s', message);
        ws.send('reply from server : ' + message)
    });

    ws.send('something');
}); 

See github for keys etc.

Daan Seuntjens
  • 880
  • 1
  • 18
  • 37
  • 1
    May I ask why you're using Typescript when you're not using Typescript? – code Mar 08 '22 at 21:53
  • @code this is a small sample of a bigger project which does use it :) – Daan Seuntjens Mar 08 '22 at 23:37
  • Where did the 6001 come from if you specified 8888? – 500 - Internal Server Error Mar 09 '22 at 01:23
  • @500-InternalServerError oh my bad! That was a remainder of a bugtest, I've tested it again and updated the error code. – Daan Seuntjens Mar 09 '22 at 09:29
  • @code you're right, for this code example typescript doesn't make sense, i've updated the post and repository to use node js instead of typescript. – Daan Seuntjens Mar 09 '22 at 09:38
  • Do you run this on Windows or Linux? Worth checking out firewall rules, if running on Windows you could just temporary turn it off to see if you can reach it through the IP. I know you tried to Telnet and got a response, but from experience it's always worth an extra check regarding the firewall. – Egil Hansen Mar 12 '22 at 12:18
  • @EgilHansen It's a bit complicated on that end, I'm running the program on ubuntu on a windows machine. I'm guessing my windows firewall can still block ports of my ubuntu vm? – Daan Seuntjens Mar 12 '22 at 12:26
  • I see, haven't had the same setup so not really sure about the routing from the VM, but i have lost count on how many times Windows firewall have played a trick on me ;) – Egil Hansen Mar 12 '22 at 12:28
  • It seems the ubuntu vm doesn't have a firewall itself (sudo ufw status isn't supported), just turning of the windows firewall doesn't seem to help :'( – Daan Seuntjens Mar 12 '22 at 12:44
  • Sorry, longshot from my side, but worth a try before spending many more hours bug hunting. Good luck getting to the bottom of this :) – Egil Hansen Mar 12 '22 at 12:53

2 Answers2

1

Your "online websocket tester" doesn't provide easily readible source code, so it is not clear what is failing. My guess: TLS cert validation is failing. (Browsers may have own rules for localhost, so it may be working for localhost in some browsers).

You are connecting to the IP, but cert is generated Common Name: Team x. Correct TLS client implementation should reject this kind of TLS connection, because server name is not matching TLS CN name ('IP'!='Team x').

Solutions:

1.) Generate proper TLS certificate, where Common Name is matching used IP. This is a proper secure solution for your use case (usually server FQDN is used, because domain is used for connection and not the server IP).

2.) Use websocket client, which provides option to disable cert verification.

3.) Open https://IP:8888 and add browser TLS exception for used cert. Exception should be applied also for wss protocol then.

Jan Garaj
  • 25,598
  • 3
  • 38
  • 59
  • That is not a secure context so if you create a self signed certificate you also need to install / trust it in your target device. instead cloudflair servers have a trusted certificate and you will save yourself a lot of hassle related to certificates. Also you cant trust your certificate on the wss tester that you specified –  Mar 18 '22 at 12:21
0

Try using cloudflaired
for download : Click here
tutorial : Click here
it may be the problem of firewall rules, and other factors

EDIT:
This program packs a lightweight server that acts as a bridge from your computer to cloudflair servers. This hosts the site on a temporary subdomain for free
if you are having a cloudflair account, it will help with setting and configuring static permanent urls instead of dynamically changing every time
Sorry I don't know about the pricing as I use the free plan for more info visit the docs
Because of this it can bypass many windows restrictions (like firewall) isp restrictions (like nat), etc. So you can focus on the project
Also this works even out of your lan. Just so you know it also works outside the lan. so to share a quick preview to others.

  • 1
    I can use cloudflared as a workaround. If I setup http (2400) and ws (8888) servers on my localhost and use `cloudflared tunnel --url localhost:2400` and `cloudflared tunnel --url localhost:8888` and connect to the generated urls I can use https and wss. I've no clue how and why this works, it feels like a workaround but it works so I'm thankfull for this option if nothing else works. But if anyone can explain how we can use wss on our local ip address it would be better. If not, I'll accept this answer at the end of this week. – Daan Seuntjens Mar 12 '22 at 14:54
  • 2
    if you could explaine why and how this works, it would be very much appreciated. Bonus: how could you use cloudflared with a static domain name and still use localhost? No obligation to add this, but it would greatly improve the quality of your answer :) – Daan Seuntjens Mar 12 '22 at 16:05
  • 1
    Thanks for your suggestion, i have improved the answer –  Mar 15 '22 at 12:30