Firebase hosting + custom server are incompatible? - node.js

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?

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.

Socket.IO with HTTPS over apache present?

I have a domain name.
I have a Raspberry Pi as a web-server.
I've edited domain's A record to point it to my server's IP.
Via letsencrypt I got myself a certificate and now website works on https protocol (keeping http on for debug purposes)
I'm working on a messenger app that uses socket.io but using apache+php for low level stuff
So basically apache listens to 80 and 443 and nodejs listens to 3000
Obviously if I visit my site over http - everything works fine and both server and client register connections.
If I visit it over https - Chrome throws net::ERR_CONNECTION_CLOSED error (in console when trying to connect to socket.io over port 3000. Site itself loads normally).
Client:
var socket = new io(window.location.host+":3000", { secure: true });
socket.on("connect", function() {
console.log('success')
});
Server:
const io = require("socket.io");
const server = io.listen(3000);
console.log("Server started");
server.on("connection", function (socket) {
console.log("+USER");
socket.emit("hello", "Connected");
});
I really don't want to use express or anything else for that matter to keep everything as small as possible, especially since I already have a web-server running.
How to properly set it up so users could connect to my socket.io server on port 3000 when they visit the site via https protocol?
Update:
From what it seems I think it's a CORS-thing type of a problem. User visiting website over https is trying to connect to an unsecured port (this case 3000) even though it's the same domain? I'd think that would be a no-no for a lot if not all browsers.
A solution comes to mind to just move the whole thing from apache to a nodejs server module and assign manually port 3000 as a secure one via https module but I've no idea how to do it, and I'd really want to keep my apache as a web-server because at least I'm more familiar with it than anything else.
Well I ended up creating a separate https server that I assume socket.io listens to (?)
Good thing I still have my apache as a main server. I partially answered my question using this post
https://serverfault.com/questions/745248/socket-io-combined-with-apache-ssl-server
Server
const fs = require("fs");
const https = require("https");
var options = {
key: fs.readFileSync('/etc/letsencrypt/live/example.com/privkey.pem'),
cert: fs.readFileSync('/etc/letsencrypt/live/example.com/fullchain.pem')
};
var server = https.createServer(options);
server.listen(3000);
var io = require('socket.io').listen(server);
console.log("Server started");
io.on("connection", function (socket) {
console.log("+USER");
socket.emit("hello", "Connected");
socket.on("disconnect", () => {
console.log("-USER");
})
});
Client
var s = new io("https://example.com:3000", { secure: true } );
Hope this is the right way to do it

How to establish a secure websocket connection to a node server using self-signed certs?

I've got an HTTPS webpage that won't let me connect to an insecure websocket, which I was using to communicate with a node sever, so I'm trying to migrate my node server to https. The client-side https page was given to me to integrate my previously insecure page with, so I don't know anything about the certs it's using, if that matters.
To connect to it, on the client side I was using connection = new Websocket('ws://node_server_address') which worked fine for insecure connections. Now that the page uses https, I'm just using connection = new Websocket('wss://node_server_address'), which I hope is all I need to change on the client side. However, with self signed certs on the node server, I get this error when I try to connect with Chrome:
Websocket connection to 'wss://address' failed: Error in connection establishment: net::ERR_CERT_AUTHORITY_INVALID
On Firefox all it tells me is that it can't connect to the server. I've seen plenty of examples where they don't specify a CA at all and they supposedly work fine, so I'm hoping I don't have to mess with that. However, assuming the only solution is to specify some valid CA, how would I generate that for a self-signed certificate?
Node server:
const https = require('https');
const WebSocketServer = require('websocket').server;
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
let serverOptions = {
key: fs.readFileSync("./self-signed.key"),
cert: fs.readFileSync("./self-signed.cert"),
requestCert: false,
rejectUnauthorized: false
}
const server = https.createServer(serverOptions, (req, res) => { res.end('') });
server.listen(port, function() { /* Logging */ }
const wsServer = new WebSocketServer({
httpServer:server
});

valid ssl certificate is not working on specific port number

I have a website "https://m.abc.com", when I tried to open this website then my website is working fine and I am able to see green lock on address bar, but when I try to open "https://m.abc.com:9090" (where my node server application is running) then I am getting one warning "your connection is not private.. attackers might be trying to steal your information from m.abc.com. NET::ERR_CERT_AUTHORITY_INVALID " with red warning sign on address bar. How can I get rid of this warning? And one more thing this is happening randomly on few android mobile only not on iPhone. And on Desktop site I am not getting any warning.
here is the sample code that is writtten in nodejs for https server:
var appPort = 9090;
var fs = require('fs');
var https = require('https');
var options = {
key: fs.readFileSync('/etc/httpd/sslcert/abc.key'),
cert: fs.readFileSync('/etc/httpd/sslcert/abc_com.crt')
};
server = https.createServer(options, app).listen(appPort, function() {
console.log('HTTPS Server listening at port %d', appPort);
});

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