SSL Certificates

Let's Encrypt

Generating Let's Encrypt private key and certificate.

sudo apt-get install certbot
certbot certonly --manual

This will ask to create a file in location ./.well-known/acmechallenge/FileNameString. The file has to be accessed over http to verify owner of the domain. To do so create a server in the root directory to access the file at required path.

const express = require('express');
 
// Configure & Run the http server
const app = express();
 
app.use(express.static(__dirname, { dotfiles: 'allow' } ));
 
app.listen(80, () => {
  console.log('HTTP server running on port 80');
});

After finishing with certbot the .key and .cert will be generated and can be used in a server. An example server (have to be run with sudo to access /etc/letsencrypt/…):

// 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');
});

In order to access privkey.pem and cert.pem without sudo one can copy the files and change the owner of the files. For example on AWS the user executing applications is typically bitnami. For node server one can use:

#!/bin/bash
 
domain=server.paperkeeper.org 
node_dir=/home/bitnami/paperkeeper-nest/secrets
node_user=bitnami
 
cp /etc/letsencrypt/live/$domain/{cert,privkey}.pem "$node_dir"/
chown $node_user "$node_dir"/*.pem