Where to look for 'cert' and 'key' to create https server? - node.js

I am trying to move my websocket server to wss, because github pages require https certificate, and to do so, I need to:
const server = https.createServer({
cert: fs.readFileSync('/path/to/cert.pem'),
key: fs.readFileSync('/path/to/key.pem')
});
const wss = new WebSocket.Server({ server });
My question is: where do I get this cert and key?
I don't know anything about how https works, to be honest, just looking for advice here.
By the way, I am using express, so I need to cope with it somehow. Currently the server in the localhost test, but It usually runs on aws linux ami

You need an https certificate with the accompanying key to run any https server. Use LetsEncrypt.com to get them. The LetsEncrypt site offers instructions about that. There are tutorials on the internet about how to do it, and an npm package called Greenlock to help you automate it. For LetsEncrypt to work, you need to be able to prove you control the domain in question, by putting some secret token string in your DNS or on your http version of your web site.
Or, if you work for an org that already has a certificate for its public web server, you can ask the person who runs that server to buy you a certificate from whatever Certificate Authority your org uses.
When you stand up a machine to run any sort of node-based https server, you ordinarily create a directory somewhere to hold your secrets. Your certificate and private key are such secrets.
You might use a directory named /usr/local/secrets for this purpose, and place your cert and key files there. It's also good for files that store various API keys and other secret stuff needed by your server.
So your code would say
const server = https.createServer({
cert: fs.readFileSync('/usr/local/secrets/cert.pem'),
key: fs.readFileSync('/usr/local/secrets/key.pem')
});
const wss = new WebSocket.Server({ server });
Don't commit your secrets to git or any other source control system. Always put them outside your application's directory hierarchy. Or they won't stay secret. You really don't want your https cert and key floating around the intertoobz.

Related

Why does an Insecure gRPC server still allow connections from secured clients

I can't seem to understand what's happening behind the scene, but any guidance will really be appreciated.
I have the following grpc server that is hosted on Google Cloud Run:
server.js
server.bindAsync(`0.0.0.0:${process.env.PORT}`, grpc.ServerCredentials.createInsecure(), () => { //Notice, this is insecure
server.start();
console.log('GRPC Service Started');
});
Then I was given a service url of the form:
https://test-service-abcdefghij-ue.a.run.app
Then below is a client that connects to the above server using the following code:
client.js
... new test_proto.TestAccount("test-service-abcdefghij-ue.a.run.app", grpc.credentials.createSsl()); //Notice I used createSsl instead of createInsecure()
As you can see from my client code, I used createSsl without passing a self signed certificate, yet the connection to the createInsecure server worked.
I always thought both server and client must provide same self-signed certificates.
So, why does this still work even though the server is configured to be insecure? Does it mean data will still be transmitted in plain text regardless?
Based on comments from #John Hanley posting the answer, Cloud Run does not support client SSL certificates. The client verifies the server's SSL certificate. If a client connects to a Cloud Run service using HTTP (insecure), Cloud Run will redirect the client to an HTTPS endpoint. That means the final connection is encrypted with symmetric encryption. However, encryption alone does not mean a connection is secure. Google Cloud Run also supports IAP to authorize a user's access. In other words, a secure connection requires encryption and authorization.
You can have a look at documentation.

Axios Returning "net::ERR_CERT_AUTHORITY_INVALID"

Currently I have two systems:
A Vultr Server running An Express.js Backend and a Discord Bot (Self Certified SSL)
A Firebase App Running my React App.
The current way the app is set up is the react app is sending a request to the backend (The Express App) using Axios. When I use axios to try to hit an API endpoint on my express app, it returns in the console:
Failed to load resource: net::ERR_CERT_AUTHORITY_INVALID
How do I go about fixing this so I can be able to get the information from my Vultr app using Firebase without getting the Cert Invalid error? Is it Possible? Can I do it using HTTP on my VPS' IP Address while having HTTPS on Firebase? I saw the following circulating but it has not worked:
const instance = axios.create({
httpsAgent: new https.Agent({
rejectUnauthorized: false
})
});
The error message is just telling you that your certificate is untrusted.
You've got two choices: trust or ignore
Blindly ignoring ssl errors is very very bad, makes you succetible to man in the middle attacks. The way certificates work is that they delegate their 'trust' to a parent until you reach a CA (Certificate Authority). Let's say you buy a certificate from godaddy, they sign your certificate, so when someone is trying to see if your certificate is valid, they go to godaddy's CA, get the public key and check if your is valid.
If you self sign a certificate there's no CA, hence, no way of trusting it. Unless you explicitly add it to the ca bundle file in your operating system.
Self signed certificates beat no certificates at all, and manually trusting it beats ignoring ssl errors. But, it's a bit of work to catch on with the concepts but it becomes easier with time. If your app is meant for a hobby, ignore away.
Trusting
To trust globally, you would have to get your certificate and add it to the ca trust bundle, which requires you to have access to the OS and admin privileges, which is the casa for your vultr app but not for firebase.
In firebase's case you'd have to fetch the certificates public key and pass it as an argument to axios
here's how
Ignoring
here's how

Creating TLS client in Electron desktop app

I am trying to create node server in TLS and create a TLS client in electron, to distribute as desktop application to users. I can add certificates to my TLS server and run it.
But how do I create the client which requires me to insert key and cert in options to create client.
tls.connect(8000, {
key: fs.readFileSync('client-key.pem'),
cert: fs.readFileSync('client-cert.pem')
})
Where do I store the key and cert files? Should it be bundled along with the downloaded electron app?
If the key and cert can be read unpacking the application, doesnt it makes security compromised?
If the key and cert are stored in electron bundle, its going to be same key and cert for every one downloading the application, doesnt it makes security compromised?
If the key and cert are stored in electron bundle, how do I update the certificate(when changed in the server) after user downloads the application?
I worked based on this link
https://github.com/nodejs/help/issues/253
It would be great if someone can point me in the right direction.
We are facing websocket blocked for some users, so we are trying to use TLS duplex socket.
It looks like I dont need client certificate after all in my case. Seems I can authenticate with auth token or username/password. This one way TLS will be offering the full socket encryption to prevent Man-in-the-middle attack.
Incase of using self signed certificates as in example above, supplying CA certificate alone can suffice to make it work for POC stage.
tls.connect(8000, {
ca: fs.readFileSync('ca.crt')
})
The following materials helped in arriving to my conclusion:
https://chat.stackoverflow.com/rooms/118168/discussion-between-castaglia-and-agm
https://stackoverflow.com/a/8230650/5384225
https://crypto.stackexchange.com/a/406/75660
Still I dont have answers for the original questions I had asked.

Running Node.js HTTPS server without providing SSL certificate?

We've got a setup, where SSL/HTTPS stuff is managed by Cloudflare.
What is the proper way to run Node.js HTTPS server in this case?
I've tried running it like this and it's working, but what are the downsides?
const app = express()
const httpsServer = https.createServer({}, app) //creating https server with an empty ssl certificate object
httpsServer.listen(443)
I've tried running it like this and it's working,
By this, I assume you're using Flexible mode?
When in Flexible mode, it gives you the illusion of security, but in actuality
client-server connection is only half-secured.
Cloudflare Universal SSL Certiticate
|
Client <----HTTPS-----> Cloudflare <------HTTP-----> Origin Server
Surely you've heard of MITM (man-in-the-middle) attacks or state-sponsored surveillance over insecure channel (read: HTTP)? These are the downsides when your connection is not fully encrypted end-to-end.
For you to secure the connection end-to-end, you'll need to use Full/Full(Strict) mode, and for this to work you'll need to specify the certificate on the origin server. Opening port 443 and put it on listening mode is not enough, HTTPS uses Public Key Infrastructure (PKI) and SSL certificates are fundamental part of it. In other words, you simply can't use HTTPS without SSL certificates in place!
Cloudflare Universal SSL Certiticate Origin Certificate
| |
Client <----HTTPS-----> Cloudflare <------HTTPS-----> Origin Server
Provisioning a self-signed certificate on the origin server will suffice for Full mode, but Full(Strict) mode requires a valid certificate. Good new is that you don't need to purchase Extended Validation (EV) certificates from retail Certificate Authority (CA), as nowadays there are free Domain Validation (DV) certificates such as Let's Encrypt/Certbot or Cloudflare Origin CA certificate which would work just as fine.

How to install rapid ssl certificate in nodejs express application

I have the SSL certificate from the rapid SSL and Rapid SSL issued the certificate to the server.
Now I have 4 files.
CACertificate-INTERMEDIATE-1.cer
CACertificate-ROOT-2.cer
PKCS7.p7b
CACertificate-INTERMEDIATE-1.cer
ServerCertificate.cer
Then how to configure the server to it.
If I understood you correctly, you want to setup HTTPS for you node.js web server.
If you are using plain node.js, then you will have to switch from http module to https module. Take a look at the docs: https://nodejs.org/dist/latest-v8.x/docs/api/https.html#https_https_createserver_options_requestlistener
If you are using some kind of a framework, you will need to consult its docs.
Usually you need a server certificate and a corresponding private key. The files that you were provided with look like a certificate chain (root CA cert -> intermediate CA cert -> your server cert). The files name ServerCertificate.cer conveys a feeling that it is a server certificate. But where is your private key file? You should consult certificate issuer to find this out.
ssl-root-cas module helps to use custom certifcates on your node.js server.
You can inject your custom certificate doing:
require('ssl-root-cas').addFile('my-cert.crt');
Have a look to this article that explains how to use ssl/tls certifcates on your node.js app:
https://www.sitepoint.com/how-to-use-ssltls-with-node-js/

Resources