Node auto reload code on https - node.js

I'm looking for a tool which can auto reload my node.js code but also can run on https for local development.
Both forever and nodemon can reload my code but can't run on https.

To generate a self-signed certificate, run the following in your shell:
openssl genrsa -out key.pem
openssl req -new -key key.pem -out csr.pem
openssl x509 -req -days 9999 -in csr.pem -signkey key.pem -out cert.pem
rm csr.pem
This should leave you with two files, cert.pem (the certificate) and key.pem (the private key). This is all you need for a SSL connection. So now you set up a quick hello world example (the biggest difference between https and http is the options parameter):
var https = require('https');
var fs = require('fs');
var options = {
key: fs.readFileSync('key.pem'),
cert: fs.readFileSync('cert.pem')
};
var a = https.createServer(options, function (req, res) {
res.writeHead(200);
res.end("hello world\n");
}).listen(8000);
NODE PRO TIP: Note fs.readFileSync - unlike fs.readFile,
fs.readFileSync will block the entire process until it completes. In
situations like this - loading vital configuration data - the sync
functions are okay. In a busy server, however, using a synchronous
function during a request will force the server to deal with the
requests one by one!
Reference : https://docs.nodejitsu.com/articles/HTTP/servers/how-to-create-a-HTTPS-server/

Related

Node.js HTTPS Server Let's Encrypt Certificate Files Location on Windows Server

I have a windows server 2012 and wanted to run a node.js web server over https. I have SSL certificate from let's encrypt.
My server code is here:
const https = require("https"),
fs = require("fs");
const options = {
key: // not have,
cert: "C:\\ProgramData\\win-acme\\acme-v02.api.letsencrypt.org\\Certificates\\ichangedthispart-csr.pem"
};
const express = require('express')
const qs=require('qs')
const app = express()
const port = 3000
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})
https.createServer(options, app).listen(8080);
When I runned with just cert option there is
node:_tls_common:155
context.setCert(cert);
^
Error: error:0909006C:PEM routines:get_name:no start line
at setCerts (node:_tls_common:155:13)
at Object.createSecureContext (node:_tls_common:210:7)
at Server.setSecureContext (node:_tls_wrap:1336:27)
at Server (node:_tls_wrap:1191:8)
at new Server (node:https:67:14)
at Object.createServer (node:https:92:10)
at Object.<anonymous> (C:\inetpub\wwwroot\app\server.js:42:7)
at Module._compile (node:internal/modules/cjs/loader:1108:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1137:10)
at Module.load (node:internal/modules/cjs/loader:973:32) {
library: 'PEM routines',
function: 'get_name',
reason: 'no start line',
code: 'ERR_OSSL_PEM_NO_START_LINE'
}
I don't have the pem file for 'key' inside win-acme directory. In some examples also another pem file for 'ca'; i don't have that file too.
Could these other .pem files be generated with something using this single pem file on windows server? Do I need any other information? There are some examples using with openssl but it seems different.
I intented to have the key.pem file from let's encrypt certification. Now I solved the issue.
First I was using win-acme tool to generate certificate on windows server. To get key.pem file from certificate generation process, you need to change the PrivateKeyExportable to true in settings.json file of win-acme.
Secondly, you need to generate or renew certificate using win-acme with the PEM encoded files (Apache, nginx, etc.) for storing option. Pick the "How would you like to store the certificate?" question as PEM encoded files (Apache, nginx, etc.) option.
Finally you will have both key.pem and crt.pem files at the export directory. Then use them for the https options object as:
const options = {
key: fs.readFileSync('yourhomesite.com-key.pem', 'utf8'),
cert: fs.readFileSync('yourhomesite.com-crt.pem', 'utf8')
};

Creating a socket.io server for https connections

I have done instructions from this page: https://medium.com/#invingagan/an-express-https-server-with-a-self-signed-certificate-and-socket-io-42d1f02d4d1a
That is, I created a self signed certificate:
openssl req -nodes -new -x509 -keyout server.key -out server.cert
Then I use this server code:
var express = require('express');
var app = express();
var fs = require('fs');
app.use(express.static('public'));
const server = require('https').createServer({
key: fs.readFileSync('server.key'),
cert: fs.readFileSync('server.cert')
},
app);
var io = require('socket.io')(server);
server.listen(1437, function () {
console.log('https and websocket listening on *:1437');
});
However, when I try to connect using socket.io client, I got this error:
index.js:83 GET https://localhost:1437/socket.io/?framespersecond=15&audioBitrate=22050&EIO=3&transport=polling&t=NJLEHQL net::ERR_CERT_AUTHORITY_INVALID
If I just copy and paste the URL in the browser URL field, I received the same error, so this is not a problem of socket.io client but the server miss to configure something.
I tried by creating a CA file and specify it in the call to createServer but it did not work either.
Any help?
Jaime
It turned out there was a problem when generating the certificate using openssl.
I don't really know what happened, but since I have an already issued a self signed certificate (the one that is used by Visual Studio when developing sites to be debugged using IISEXPRESS), I have exported that certificate using Digicert utility and I could finally connect using socket.io.
Regards
Jaime

ERR_SSL_VERSION_OR_CIPHER_MISMATCH in node js

I recently purchased a personal ssl certificate from Positive ssl. After i got everything sorted out with activating it and the validation, I was finally able to download the certificate files.
The files i got were:
www.niknet.ddns.net.ca-bundle
www.niknet.ddns.net.crt
www.niknet.ddns.net.p7b
Before I only used .key and .crt
and it worked great but now i am using the .ca-bundle and the .crt file
this is the code i use to include those files into the ssl library in node js
var httpPort = process.env.PORT || 80;
var httpsPort = process.env.PORT || 443;
var server = http.createServer(app).listen(httpPort);
var server = https.createServer({
secureProtocol : 'TLSv1_2_server_method',
ciphers : "AES128-GCM-SHA256:RC4:HIGH:!MD5:!aNULL:!EDH",
honorCipherOrder : true,
ca: fs.readFileSync(__dirname + '/niknet_ddns_net.ca-bundle'),
cert: fs.readFileSync(__dirname + '/niknet_ddns_net.crt')
},app).listen(httpsPort);
var io = require('socket.io').listen(server);
but I can't for the life of me get the certificate to work properly.
I just get this error
ERR_SSL_VERSION_OR_CIPHER_MISMATCH
I've been reading other posts and have tried adding their code but nothing works.
I also read somewhere that the ssl or tls library for node.js is outdated and that my certificate could be too new. If that's true, are there any other third-party ssl libraries I could use?
run this command:
openssl req -nodes -new -x509 -keyout server.key -out server.cert
Just remember to set this to localhost:
Common Name (e.g. server FQDN or YOUR name) []: localhost
then
https.createServer({
key: fs.readFileSync('./ssl/server.key'),
cert: fs.readFileSync('./ssl/server.cert')
},app)
ERR_SSL_VERSION_OR_CIPHER_MISMATCH will appear if the added certificate are not indicated properly in the first argument of createServer().
tested key and crt with openssl using bellow command (try in browser https://hostname:8888).. and found the exact cipher missing.
openssl s_server -cert server.crt -key server.key -CAfile octopz.zende.sk.ca-bundle -accept 8888 -www
Then added to the nodejs code.
var server = https.createServer({
key: privateKey,
cert: certificate,
ca: certificateAuthority,
ciphers: [
"ECDHE-RSA-AES128-SHA256",
"DHE-RSA-AES128-SHA256",
"AES128-GCM-SHA256",
"RC4",
"HIGH",
"!MD5",
"!aNULL"
].join(':'),
}, app);
it worked!!
We have lots of dupes of this for other languages, but the closest I can find for nodejs is How to create an HTTPS server in Node.js? which is not specific or ERR_SSL_VERSION_OR_CIPHER_MISMATCH with node v7.9.0 https which is not answered. So:
SSL/TLS server including an HTTPS server needs a privatekey AND certificate/chain (with rare exceptions not applicable here). You can use a CA-issued cert (and chain) instead of a self-created (and usually self-signed) cert, as long as the CA-issued cert is for the same privatekey, but you must still provide the privatekey. You can use cert and key together, or you can combine the cert (and optionally chain) and key into a PKCS12-also-called-PFX file, and use pfx.
In addition to the Q you asked, and arguably offtopic for SO, don't use RC4. It's considered broken cryptographically, though still on average moderately difficult/costly in practice, and most standards for using SSL/TLS/HTTPS prohibit it for several years now, particularly rfc7465.

How to use HTTP/2 with Nest.js (Node)

I have read that Express 4.x is not compatible with Node.js native HTTP2 (from 8.4+), and I was hoping for more progess on Express 5.x than it has.
But as I started thinking that Express5.x will probably be released to late for my next Node.js project - I came over Nest.js.
Does anyone know if Nest.js can be used with native HTTP2 support ??
The only Node.js framework that I have heard of that supports this is Fastify.
Or are there any other out there ? Preferable one that support Express plugins.
You can use HTTP/2 (and SPDY) in NestJS using the node-spdy package:
Setup packages
yarn add spdy
yarn add -D #types/spdy
Generate certificate
H2 generally requires TLS, so generate a new key and certificate:
openssl req -x509 -newkey rsa:2048 -nodes -sha256 -keyout test.key -out test.crt
Modify startup
Next, modify main.ts:
// main.ts
async function bootstrap() {
const expressApp: Express = express();
const spdyOpts: ServerOptions = {
key: fs.readFileSync('./test.key'),
cert: fs.readFileSync('./test.crt'),
};
const server: Server = spdy.createServer(spdyOpts, expressApp);
const app: NestApplication = await NestFactory.create(
AppModule,
new ExpressAdapter(expressApp),
);
await app.init();
await server.listen(3000);
}
bootstrap();
Test client
$ curl -I -k https://localhost:3000/
HTTP/2 200
x-powered-by: Express
content-type: text/html; charset=utf-8
content-length: 12
etag: W/"c-Lve95gjOVATpfV8EL5X4nxwjKHE"
Notice HTTP/2 being sent in the response headers.
As Barry Pollard commented; using a webserver in front for static resources and the Webapp itself, and using Node.js for API purposes, is probably the best approach anyway.

Create HTTPS server with node js

I want to create a https server for my localhost.
Node JS documentation provides out of the box solution but I have some confusion with it.
Example
var https = require('https');
var fs = require('fs');
var options = {
key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),
cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem')
};
https.createServer(options, function (req, res) {
res.writeHead(200);
res.end("hello world\n");
}).listen(8000);
Or
var options = {
pfx: fs.readFileSync('server.pfx')
};
Here how would I get key, cert or pfx for my localhost?
For development purposes you can create a self-certified certificate.
Here's how to do it on a linux-based system:
First, generate a private key
openssl genrsa 1024 > key.pem
This will store a 1024 bit RSA key in the file key.pem
Then, generate an SSL certificate with that key:
openssl req -x509 -new -key key.pem > key-cert.pem
Now, you can use key.pem and key-cert.pem in the options you pass to createServer.
the .pfx file is a "bundle" maded of the key.pem , cert.pem and sometimes a (CA file) files.
You should get(pay) / make(testing etc) a https certificate.
This is called self-signed certificate, and you can generate it with one command by openssl. Just type:
openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout key.pem -out cert.pem
in the terminal.

Resources