assign HTTPS to node.js socket.io - node.js

i want to create HTTPS server to my node.js socket.io server,
did it with self sign certification, using this code
var fs = require( 'fs' );
var app = require('express')();
var https = require('https');
var server = https.createServer({
key: fs.readFileSync('C:/ssl/ia.key'),
cert: fs.readFileSync('C:/ssl/ia.crt'),
requestCert: false,
rejectUnauthorized: false
},app);
server.listen(8888);
but when purchasing real one i only get .crt file, how to secure my node app using it on windows server?

Short answer: no private key - no way.
You need a private key that was used to purchase the certificate.
Or you can use letsencrypt-express:
Free SSL and managed or automatic HTTPS for node.js with Express, Koa,
Connect, Hapi, and all other middleware systems.
https://www.npmjs.com/package/letsencrypt-express

Found the answer, i had to do a CSR from my server using OPENSSL batch, in that case it will create CSR and the private KEY, buying SSL using the CSR will give me the CRT
and i will use the generated key from the OPENSSL.

Related

Can't connect to websocket after switching to secured protocol

I have built a web application with NodeJS/Express as the backend. The frontent connects using the websocket protocol. Everything works fine.
Now, I'm switching to the wss:// protocol, which, to my knowledge and according to this blog post, should be as simple as
Generate self-signed certificate:
openssl req -nodes -new -x509 -keyout certificate.key -out certificate.cert
Backend:
// old
// import * as http from 'http';
// new
import * as https from 'https';
// ...
// old
// const server = http.createServer(app);
// new
const server = https.createServer({
key: fs.readFileSync('certificate.key'),
cert: fs.readFileSync('certificate.cert'),
}, app);
const wss = new WebSocket.Server({ server });
// ...
Frontend (Angular with RxJS):
// old
// private readonly backend$$ = webSocket<UpdateData<any>>('ws://localhost:8999');
// new
private readonly backend$$ = webSocket<UpdateData<any>>('wss://localhost:8999');
However, having made these changes, my Frontend is no longer able to connect to the websocket.
I get the following error (which I'm not able to fully copy from the console for some reason):
I need to know what the problem here is / could be, or any pointers as to what to check to figure it out.
The problem is related to the self-signed certificate, which browsers (at least Firefox, Chrome and Edge) silently disallow in this case.
I could circumvent this by visiting https://localhost:8999 directly, which displayed the well-known invalid certificate warning message. By clicking past that, the certificate is added as an exception (at least temporarily), and visiting my actual Angular application now also leads to a successful connection to the websocket.
Here is a description for how to add self-signed certificates permanently in Firefox. I expect other Browsers to work similarly.

NodeJS ssl for subdomain

I have a site, for example test.com, I need to make a copy of the same site with the address subdomain.test.com and change a couple of files on this subdomain for my purposes. The problem is that the categories of the site use NodeJS, and now running 9 NodeJS. Each server has registered SSL certificates of the following type (the settings are the same for everyone):
var fs = require('fs');
var sslOptions = {
key: fs.readFileSync('/etc/letsencrypt/live/test.com/privkey.pem'),
cert: fs.readFileSync('/etc/letsencrypt/live/test.com/fullchain.pem'),
requestCert: true,
rejectUnauthorized: false
};
var https = require('https'),
server = https.createServer(sslOptions, app),
io = require('socket.io')(server),
I made a subdomain for example subdomain.test.com, but when I visit the site, the console swears at the following error: ERR_CERT_COMMON_NAME_INVALID.
As I understand it, an error occurs because the certificate was issued for test.com, and I'm trying to use it additionally on subdomain.test.com. What can be done in this situation? Either in the NodeJS servers themselves when SSL certificates are connected, duplicate the settings by adding, for example, the number 1, or are there any other options?

SocketIO throws net::ERR_CERT_AUTHORITY_INVALID on self signed certificate

I am using socket io on client:
const socket = require('socket.io-client')('https://localhost:4200', {secure: true, rejectUnauthorized: false})
And on server:
let https = require('https')
let fs = require('fs')
let options = {
key: fs.readFileSync('cert/my.net.key'),
cert: fs.readFileSync('cert/my.net.cert'),
requestCert: false,
rejectUnauthorized: false,
};
const server = https.createServer(options, require('express')())
const io = require('socket.io')(server)
All services are started normally, but on client I am getting polling-xhr.js:263 GET https://localhost:4200/socket.io/?EIO=3&transport=polling&t=MPa6ZuL net::ERR_CERT_AUTHORITY_INVALID
Why? Whats is wrong?
Browsers don't like self-signed certificates for security reasons.
To get around this in your development environment, I see three options:
Use a certificate issued by a certification unit.
It could be something free, like https://letsencrypt.org/.
Create your server dynamically, based on the development environment, not to include certificates and work directly with HTTP and WS (and not HTTPS and WSS).
Change the configuration of your browser used in development so that it accepts self-signed certificates.
For Chrome, for example, just enable the Allow invalid certificates for resources loaded from localhost. (chrome://flags/#allow-insecure-localhost) setting.
But remember that you will not be able to use self-signed certificates in production environments.

Self signed cert NodeJS rejectUnauthorized

I created a structure certificates to authenticate client-> server, allowing only certificates recognized by the CA using this step by step: https://jamielinux.com/docs/openssl-certificate-authority/create-the-root-pair.html
I checked the authority with openssl, and it returns to me OK the certificate server and client, with the same CA. But by setting the parameter rejectUnauthorized to true on the server, the client can not connect.
Is there any extra parameter should I set up to allow authentication by a certificate that I generated?
---- Edit
On the client side I get the following error: ""ECONNRESET" socket hang up"
I spent a long time digging into a similar issue, and I wrote up this to talk about how to dig into various OpenSSL issues with node.js: http://www.thedreaming.org/2016/09/27/nodejs-ssl/
The short answer, though, is if you need to pass the ca parameter when creating you client connection. If you have the self-signed certificate stored in cert.pem, then the client code looks something like:
var https = require('https');
var fs = require('fs');
var certificate = fs.readFileSync('cert.pem');
var options = {
host: serverHost,
port: 443,
path: '/',
ca: [certificate]
};
https.request(options, function(res) {
res.pipe(process.stdout);
}).end();

how to configure https in sails.js

I am trying to setup a local HTTPS server for testing in Sails.js? I am not able to find any pointer how to do that in sails.js? For express,
var express = require('express');
var https = require('https');
var http = require('http');
var fs = require('fs');
// This line is from the Node.js HTTPS documentation.
var options = {
key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),
cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem')
};
// Create a service (the app object is just a callback).
var app = express();
// Create an HTTP service.
http.createServer(app).listen(80);
// Create an HTTPS service identical to the HTTP service.
https.createServer(options, app).listen(443);
Any idea about sails.js?
For sails.js version 0.10, include this in config/locals.js (if locals.js does not exist, create it):
var fs = require('fs');
module.exports = {
ssl : {
key: fs.readFileSync('path-to-key.key'),
cert: fs.readFileSync('path-to-crt.crt')
}
};
Source: https://stackoverflow.com/a/28565113/2459071
If you're using the latest v0.9 (and maybe some versions of v0.8) take look inside of config/bootstrap.js. You should be able to access your express app via the sails.express context. From there I think you should be able to do with it what you want to...
Also someone in the #sailsjs irc channel said this worked for them
module.exports.bootstrap = function (cb) {
var fs = require('fs');
sails.config.express.serverOptions = {
key: fs.readFileSync('ssl/key.pem'),
cert: fs.readFileSync('ssl/cert.pem')
};
cb();
};
Maybe it's just me but I could get either of the above working for sails v0.9.7, but I did get it working by editing the config/local.js file like so;
var fs = require('fs');
module.exports = {
port: process.env.PORT || 1337,
environment: process.env.NODE_ENV || 'development',
express: { serverOptions : {
key: fs.readFileSync('ssl/key.pem'),
cert: fs.readFileSync('ssl/cert.pem')
}
}
};
Now I'm not saying this is the 'correct' way to do this, however it works for me!
Shameless self promotion
More about this on my blog!
End shameless self promotion :D
This contribution enhances the solution for to support native mobile applications and old browsers.
This solution worked really well for me when when just using a modern web browser to access my SSL site. However when I attempted to make requests using the AFNetworking library it did not recognise the SSL certificate. This was due to the iPhone application requiring the intermediate SSL certificates (sometimes called the ca bundle).
You can add the intermediate certificate in using the following code.
express: {
serverOptions : {
key: fs.readFileSync('ssl/key.pem'),
cert: fs.readFileSync('ssl/cert.pem'),
ca: fs.readFileSync('ssl/intermediate.pem')
}
}
When creating you intermediate certificate (which can normally be downloaded from your SSL certificate provider) it is important to get the order of certificates right.
This linux command really helped with debugging.
openssl s_client -connect yoursite.com:443 -showcerts
The above does not work for sails v0.9.3. I ended up with the following workaround. (require fs first of course)
express : {serverOptions : {
key: fs.readFileSync('ssl/server-key.pem'),
cert: fs.readFileSync('ssl/server-cert.pem'),
}}
I have also faced this kind of issues in my production sails app (v0.11.x and v0.12.x). Android release version apk is not able to connect to sails app and some old version browsers do not accept SSL certificate with web app.
I got some intermediate certificate error like below
The certificate is not trusted in all web browsers. You may need to install an Intermediate/chain certificate to link it to a trusted root certificate.
Finally, I found a solution
ssl: {
ca: require('fs').readFileSync('ssl/intermediate.crt', 'utf8').toString(),
key: require('fs').readFileSync('ssl/example_com.key', 'utf8').toString(),
cert: require('fs').readFileSync('ssl/main.crt', 'utf8').toString()
}
I hope this will help someone.

Resources