Express.js. How to generate a valid ssl certificate? - node.js

I have a production ready express server. And 2 webapps working with it.
The express server is in the port : 1111
I have created two letsencrypt ssl for my nginx server, and im using it with the frontend sites for app.domain.com and domain.com, it works fine.
The point is that the backend isnt reached because it must be ssl too. But... how do I setup a valid ssl for my backend? I mean I cant do it with letsencrypt because its a backend server and it doesn't have ssl.
I have tried using the same certificates that i generated for domain.com in the express server using basically this code taken from other site
// Dependencies
const fs = require('fs');
const http = require('http');
const https = require('https');
const express = require('express');
const app = express();
// Certificate
const privateKey = fs.readFileSync('/etc/letsencrypt/live/yourdomain.com/privkey.pem', 'utf8');
const certificate = fs.readFileSync('/etc/letsencrypt/live/yourdomain.com/cert.pem', 'utf8');
const ca = fs.readFileSync('/etc/letsencrypt/live/yourdomain.com/chain.pem', 'utf8');
const credentials = {
key: privateKey,
cert: certificate,
ca: ca
};
app.use((req, res) => {
res.send('Hello there !');
});
// Starting both http & https servers
const httpServer = http.createServer(app);
const httpsServer = https.createServer(credentials, app);
httpServer.listen(80, () => {
console.log('HTTP Server running on port 80');
});
httpsServer.listen(443, () => {
console.log('HTTPS Server running on port 443');
});
But it worked randomly, a lot of times the request timed out because it took forever, and other times it worked, it was weird.
But now it suddenly even stopped working, so I dont know what to do there.
What type of certificate do I have to use?
Self signed ones are rejected by chrome, and I donty know how else to generate a letsencrypt one, if the express node server is running in an ip not a domain

Okey, the problem was with my nginx virtualhosts. I created a virtualhost api.domain.com
server
{
listen 443;
listen [::]:443;
server_name api.domain.com;
location /
{
proxy_pass https://127.0.0.1:1111;
}
}
And then run
sudo certbot --nginx -d api.domain.com
Then it started to work

Related

Prevent http traffic, and allow https using Automated Certificate management

I am using express nodejs module to create the app server. The app is accessibile over both https and http
I want to prevent http endpoint.
I have enabled Automated certificate management. My question is, if I want to use the cert which is generated through acm, how can I use the key and the cert in my nodejs code.
You can create an HTTPS server and pass along a private key and certificate like so:
const fs = require('fs');
const https = require('https');
const express = require('express');
const app = express();
const options = {
key: fs.readFileSync('path/to/key', 'utf8'),
cert: fs.readFileSync('path/to/cert', 'utf8'),
};
const httpsServer = https.createServer(options, app);
httpsServer.listen(8443);
If you don't want to respond to HTTP requests at all, simply don't create an HTTP server. If you want to to forward users to HTTPS instead, you could add something like this:
const http = require('http');
app.use('*', (req, res, next) => {
if (!req.secure) {
const [ host ] = req.headers.host.split(':');
return res.redirect(`https://${host}:8443${req.url}`);
}
return next();
});
const httpServer = http.createServer(app);
httpServer.listen(8000);
Or you can handle this at reverse-proxy level. E.g. for Nginx:
server {
listen 80 default_server;
server_name _;
return 301 https://$host$request_uri;
}
}

Redirect non-www and HTTP to www and HTTPS

I am running an Express web server. I used Let's Encypt to create SSL certificates for both the www and non-www version of my domain. My DNS has these records:
CNAME | Host: # | Target: dynamicdns.example.com. | TTL: 60min
CNAME | Host: www | Target: dynamicdns.example.com. | TTL: 60min
I also have this node.js code to run the webserver:
// Dependencies
const express = require('express');
const fs = require('fs');
const http = require('http');
const https = require('https');
// Create express instance
const app = express();
// Get credentials from system
const privateKey = fs.readFileSync('/etc/letsencrypt/live/www.example.com/privkey.pem', 'utf8');
const certificate = fs.readFileSync('/etc/letsencrypt/live/www.example.com/cert.pem', 'utf8');
const ca = fs.readFileSync('/etc/letsencrypt/live/www.example.com/chain.pem', 'utf8');
const credentials = {
key: privateKey,
cert: certificate,
ca: ca
};
// Initalize server
app.use(express.static('public'));
const httpServer = http.createServer(app);
const httpsServer = https.createServer(credentials, app);
// Listen for HTTP
httpServer.listen(80, () => {
console.log('HTTP Server running on port 80');
});
// Listen for HTTPS
httpsServer.listen(443, () => {
console.log('HTTPS Server running on port 443');
});
This all works correctly, but it creates an issue with having multiple valid URLs for the same content. The following URLs are all valid right now:
http://example.com
http://www.example.com
https://example.com
https://www.example.com
I want to redirect all the wrong URLs to https://www.example.com, which is the correct URL. I'm not sure how I should go about doing this. Any help would be appreciated.
you could use a middleware like this one, to check all domains and redirect accordingly:
app.use((req, res, next) => {
if (!req.secure) {
return res.redirect('https://' + req.get('host') + req.url);
}
next()
})
Just make sure to use it just for production

Express HTTPS - unable to connect securely- SSLv3 broken protocol

Trying to make HTTPS server work on Express 4, however, there's an SSLv3 security error coming (please see the image). To my understanding SSLv3 protocol is not supported by browsers anymore due to POODLE attack.
How to make HTTPS server use the TLS1.2 protocol?
var express = require('express'),
app = express(),
fs = require('fs'),
https = require('https'),
key = fs.readFileSync('/usr/local/etc/ssl/key.pem'),
cert = fs.readFileSync('/usr/local/etc/ssl/cert.pem'),
https_options = {
key: key,
cert: cert
},
PORT = 8000,
HOST = 'localhost';
https.createServer(https_options.key, app).listen(PORT);
app.get('/', function(req, res) {
res.send('Hello');
});
module.exports = app;
The server is listening localhost:8000
The error
try to create server like that
it is working fine at my side,
var server = require('https').createServer(options, app),
server.listen(port);
or if like to add socket
var server = require('https').createServer(options, app),
io = require('socket.io').listen(server);
server.listen(port);

Cannot enable my own SSL certificate on heroku

I host my website at heroku using my own domain name using node.js & express 4.x.
I have purchased SSL certificate and I want to add it to my website.
I use the following code to enable HTTPS support:
var fs = require('fs');
var http = require('http');
var https = require('https');
var privateKey = fs.readFileSync('sec/private_server.key', 'utf8');
var certificate = fs.readFileSync('sec/server.crt', 'utf8');
var credentials = { key: privateKey, cert: certificate };
// launch http server
var httpServer = http.createServer(app).listen( process.env.PORT, process.env.IP || "0.0.0.0", function() {
console.log('Listening on port %d', process.env.PORT);
});
// launch https server
var httpsServer = https.createServer(credentials, app).listen( 8443, process.env.IP || "0.0.0.0", function() {
console.log('Listening HTTPS on port 8433' );
});
Launching the server and visiting it by https link shows that I this website still uses heroku certificate.
What do I do wrong?
You need to use the Heroku SSL endpoint add-on.
https://devcenter.heroku.com/articles/ssl-endpoint

Express 3.0 HTTPS

I have a Node.js Express 3.0 application which listens on port 3000 locally and 80 online, that's fine. What I need to do now however is introduce an SSL certificate.
I've looked at many sources online however they're all dated, or only work on port 443 or nothing. What I need to do however is listen on both 443 and 80 and re-direct any requests to 80 back to 443.
Are they any up to date examples of this?
I would do this with 2 distinct processes: an insecure proxy server and a secure server.
The insecure proxy listens on port 80 and responds to all requests with a 302 redirect to the secure server
Insecure Proxy
var http = require('http')
var port = 80
var server = http.createServer(function (req, res) {
// change this to your secure sever url
var redirectURL = 'https://www.google.com'
res.writeHead(302, {
Location: redirectURL
});
res.end();
}).listen(port, function () {
console.log('insecure proxy listening on port: ' + port)
})
Secure Server
var https = require('https')
var express = require('express')
var fs = require('fs')
var keyFilePath = '/path/to/key.pem'
var certFilePath = '/path/to/cert.pem'
var app = express()
// put your express app config here
// app.use(...) etc.
var port = 443 // standard https port
var options = {
key: fs.readFileSync(keyFilePath, 'utf8'),
cert: fs.readFileSync(certFilePath, 'utf8')
}
var server = https.createServer(options, app)
server.listen(port, function () {
console.log('secure server listening on port: ' + port)
})
Note that you could run both of these servers within a single process but it is more maintainable to separate the concerns into distinct processes.

Resources