Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to automatically reload updated SSL certificates in Node.js Application

I created nodejs application and I'm using Lets Encrypt SSL certificates. Following is my Code

var express = require(‘express’);
var https = require(‘https’);
var fs = require(‘fs’);
var option = {
    key: fs.readFileSync(‘/etc/letsencrypt/live/$DOMAIN/privkey.pem’),
    cert: fs.readFileSync(‘/etc/letsencrypt/live/$DOMAIN/fullchain.pem’)
};
const app = express();
app.use((req, res) =>
{
    res.end(‘Hello World’);
});

https.createServer(option, app).listen(8000);

I have used pm2 to start this application using following command

sudo pm2 start app.js --watch

I am updating SSL certificates by using following cronjob

0 8 * * * sudo certbot renew

I want to reload SSL certificates automatically whenever certbot renews SSL certificates. How can I achieve this?

like image 200
Zain Ul Abideen Avatar asked Feb 17 '26 15:02

Zain Ul Abideen


2 Answers

For those of us who can't afford to or would rather not restart our servers to reload certs and that aren't comfortable with Dylan Landry's SNI-based approach, there has been a purpose-built way of doing this built into node for a while now, via server.setSecureContext (where server is a standard node https server instance). See snippet below:

const app = express();

function readCertsSync() {
    return {
        key: fs.readFileSync(sslKeyPath),
        cert: fs.readFileSync(sslCertPath) + fs.readFileSync(sslFullChainPath)
    }
}

let httpd = https.createServer(readCertsSync(), app).listen(port, onReady);

// Refresh httpd's certs when certs change on disk. The timeout stuff 
// "ensures" that all 3 relevant files are updated, and accounts for 
// sometimes trigger-happy fs.watch.
let waitForCertAndFullChainToGetUpdatedTooTimeout;
fs.watch(sslKeyPath, () => {
    clearTimeout(waitForCertAndFullChainToGetUpdatedTooTimeout);
    waitForCertAndFullChainToGetUpdatedTooTimeout = setTimeout(() => {
        httpd.setSecureContext(readCertsSync());
    }, 1000);
});

The fs.watch and timeout code is admittedly a bit clunky and can be improved using something like chokidar and some more expansive logic to monitor the state of all 3 relevant files. I chose to keep things simple to focus on the interesting bit: setSecureContext.

For reference, see https://nodejs.org/api/tls.html#tls_server_setsecurecontext_options

Also, credit goes to nolimitdev who came up with most of this before setSecureContext was even a thing.

like image 97
rmanna Avatar answered Feb 20 '26 05:02

rmanna


You can use the flag --post-hook to restart your application after every renewal.

certbot renew --post-hook "pm2 restart app_name"
Update #1

Please note that the command we are running is in crontab and any global program has to be referenced with the full path. You can use the which command to find the executable file path for the command.

like image 22
Raghav Garg Avatar answered Feb 20 '26 05:02

Raghav Garg



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!