Node.js and Socket.io - Certificate is invalid - node.js

I'm having trouble connecting my chat application to Node.js server running on Ubuntu 16.04. The problem seems to be the ssl certificate which have been generated using 'letsencrypt'.
I have successfully connected to my Node.js server using a openssl certificate - this however only works in my Chrome browser.
Here is my code for the Node.js part.:
let fs = require('fs');
let https = require('https');
var options = {
key: fs.readFileSync('./file.pem'),
cert: fs.readFileSync('./file.crt')
};
let server = https.createServer(options);
let io = require('socket.io')(server);
let Redis = require('ioredis');
let redis = new Redis();
redis.subscribe('all-chat');
redis.on('message', function (channel, message) {
message = JSON.parse(message);
io.emit(channel + ':' + message.event, message.data);
});
server.listen(3201);
The error code I'm getting from my browser is.:
net::ERR_INSECURE_RESPONSE
My guess is that for some odd reason the certificates I have obtained is not following a standard of some sorts, so the browser discards the response.
For what I can gather around the web about this problem - the solution should be using a certificate from 'letsencrypt' and/or multiple variations of.:
var options = { ... };
And I do believe I have tried every possible combination.
If I open my website in two windows, one in Edge and one in Chrome, I can succesfully send a message from Edge to Chrome - the message will however not be shown in Edge as it should.
Thanks in advance for any detail that may put me back on track!

The answer was rather simple. To be sure you can use your certificate you can use the diagnostic tool found on https://www.digicert.com/help/.
For the connection from client to my Node.js end I stated the IP on the client side - and that will not do when using a certificate which have been created with the public domain. So I changed the IP on the client side from the IP to the public domain and it worked!

Related

NodeJS Secure Websockets will not attach to https

I'm going insane trying to get a super basic wss:// functioning in NodeJS for the last 2 days. I've tried quite a few methods and libraries but I can't seem to get the websocket server attached to an https instance. I have no problem leveraging regular old http and attaching it to that instance. I don't get any errors in my debug console.
I've created both self-style type certs (Create Key + CA, create CSR,
sign it, use new server cert), and (Create Key + self-signed Cert,
use them).
I've tried disabling TLS verification via env var:
NODE_TLS_REJECT_UNAUTHORIZED="0"
I've tried both ws, and websocket libraries and many different combos
of basic ws creation vs server attaching methods.
I've built a VM of Ubuntu 21.04, installed dependencies and vscode
just to rule out my OS. Same issue here.
Tried using node versions 14 + 16.
:Package Deps:
"websocket": "^1.0.34",
"ws": "^8.0.0"
:server.js:
const fs = require('fs');
const WebSocket = require('ws');
//HTTPS
const https = require('https');
const server = new https.createServer({
key: fs.readFileSync('./config/certs/key.pem'),
cert: fs.readFileSync('./config/certs/cert.pem')
});
//HTTP
// const http = require('http');
// const server = new http.createServer();
const wss = new WebSocket.Server({server});
wss.on('connection', function connection(ws) {
ws.on('message', function incoming(message) {
console.log('received: %s', message);
ws.send('hello from server!, the time is: ' + timestamp());
});
});
//Helper function to create a timestamp
function timestamp() {
return (new Date)
.toISOString()
.replace(/z|t/gi, ' ')
.trim()
};
//Start the server
server.listen(3000);
I'm suspecting some underlying compatibility issues between node and dependencies or something...Any advice would be much appreciated. I'm not too familiar with debugging internal modules so if there are some command line switches I should add to node/nodemon please let me know. I have --inspect and --trace-warnings enabled at the very least.
I just figured it out and as usual it was something simple and overlooked. I've been using Firefox with the Weasel client add-on to test websockets. I had imported my self-signed cert along with the root CA cert I had created into Firefox. Even though it was imported, I still had to navigate to the HTTPS url and acknowledge the wonderful yellow border popup. As soon as I clicked on "Accept risk and continue" I tabbed over to Weasel and it established a connection to wss://localhost:3000 with no problems.
Even though the cert is whitelisted I still receive the warning page and have to acknowledge it. Next time I'll try a different client like one built in another language (Python, .NET...). Never would have thought it to be a browser issue but it makes sense with the way ssl/tls works.

Firebase hosting + custom server are incompatible?

My expressjs+Socket.io server runs on a Raspberry Pi. When trying to connect to the express, there is a http+https incompatibility that Firebase doesn't seem to like. Tells me to use Https instead. When using Https, I get Certificate errors. So I went and bought myself a brand new SSL certificate from my domain provider and... on my local machine, where I accidentally installed the certificate, everything works fine, but on my laptop or mobile, when I go to the website, it says "(net::ERR_CERT_COMMON_NAME_INVALID)". I am not sure what to do, since many resources online cover only how to bypass this problem on their machine, without fixing the problem for everyone.
Server.js
var app = require("express")();
var https = require("https");
var fs = require("fs");
var server = https.createServer(
{
key: fs.readFileSync('./sslkey.key'),
cert: fs.readFileSync('./sslcert.crt'),
ca: fs.readFileSync('./sslca.ca-bundle'),
},
app
);
var io = require("socket.io")(server);
io.on("connection", function(socket) {
console.log("User connected");
})
server.listen(4444, function() {
console.log("listening on *:4444");
});
I also use Socket.io with Angular and I couldn't find a way to disable "rejectUnauthorized", as many suggested to skip the SSL check.
Any help?

How do I utilize certificates/auth with web-grpc?

I am working with grpc-web, essentially trying to port a working server side vanilla grpc/node example to the browser. My existing node client example connects to the grpc service like so.
var services = require('./my_services_grpc_pb');
var grpc = require('grpc');
var secureClient = new services.MyServicesServiceClient(
(host + ":" + port),
grpc.credentials.createSsl(
fs.readFileSync(certFile)
)
);
That seems to do what I want. However, when I try to include the line
var grpc = require('grpc');
And then bundle my code with webpack, I get an error "cannot resolve child_process". I did a bit of googling and found that child_process does not work in the browser. I'm in a bit of a bind now, because the code examples that I saw on the web-grpc-tutorial do not seem show how to establish a secure connection. They look like this
var echoService = new EchoServiceClient('http://localhost:8080');
How would I go about passing certs to the call/establishing a secure channel?
There is an example of using grpc-web with TLS here: https://github.com/salrashid123/grpc_web_with_gke. There's a section on how to use certs. You do not have to use GKE if you don't need to.

Securing Node Redis

I'm trying to secure the Node Redis IPC server to use a private/public key. I've followed this tutorial which uses stunnel which wraps the tunnel used by Redis under a SSL layer.
The example is not for Node, but it does secure the connection, and I only can connect to the server if I include the certification in my config file, otherwise the connection is reseted.
However, I cannot replicate this with NodeJS. On my server computer, I have:
var redis = require('redis');
var client = redis.createClient();
client.auth('myPassword');
client.publish('instances', 'start');
And my on my client computer I have:
var redis = require('redis');
var client = redis.createClient();
client.auth('myPassword');
client.subscribe('instances');
client.on('message', function (channel, message) {
console.log("Got message " + message + " from channel " + channel);
})
But, the two devices communicate whether or not I include the certification in my stunnel config file. How can I secure this connection up?
Cheers
You can do this by passing in the tls configuration when creating the client like so
var redis = require("redis");
var client = redis.createClient(6380,'location.of.server', {auth_pass: 'password', tls: {servername: 'location.of.server'}});
I have also searched for this . But redis doesn't need any ssl since in runs only on verified private networks. The only way to provide security using stunnel. Since we can enable password by using AUTH command. In redis they have provided a password generator which is named as GPG key. Which generated a 2048 length key which will provide security. I think my answer is relevant.

Setting up Cloud9 SSL App with Node JS

I've been playing around with the Cloud9 IDE and am having a great time with it. However, I'm trying to setup a simple https server with node js and I can't seem to get it to work. When I run the page, Cloud9 says 'Running Node Process' but when I visit the url that the server is supposed to respond to: https://workspace.user.c9.io the page says
Service Temporarily Unavailable
The server you are trying to contact is down either because it was stopped or is unable to service your request due to maintenance downtime or capacity problems. Please try again later.
node-web-proxy/0.4 Server at project-livec9f70a01ca28.rhcloud.com Port 8000
I created a test certificate with OPENSSL and am using the following code to set up my server. I can confirm that the OPENSSL certificate was built correctly.
var https = require("https");
var fs = require("fs");
var url = require("url");
var options = {
key: fs.readFileSync('certs/cert.pem'),
cert: fs.readFileSync('certs/cert.pem')
};
// create a server
https.createServer(options, function(req, res) {
console.log("This works!");
res.writeHead(200);
res.end("Hello world from Cloud9! Url:"+req.url);
}).listen(process.env.PORT);
Thank you for your help!
you need .listen(process.env.PORT,process.env.IP);
It should say that when you start a program.

Resources