如何在 Node.js 应用程序中自动重新加载更新的 SSL 证书

Zai*_*een 9 node.js express lets-encrypt

我创建了 nodejs 应用程序,并且正在使用Lets EncryptSSL 证书。以下是我的代码

\n
var express = require(\xe2\x80\x98express\xe2\x80\x99);\nvar https = require(\xe2\x80\x98https\xe2\x80\x99);\nvar fs = require(\xe2\x80\x98fs\xe2\x80\x99);\nvar option = {\n    key: fs.readFileSync(\xe2\x80\x98/etc/letsencrypt/live/$DOMAIN/privkey.pem\xe2\x80\x99),\n    cert: fs.readFileSync(\xe2\x80\x98/etc/letsencrypt/live/$DOMAIN/fullchain.pem\xe2\x80\x99)\n};\nconst app = express();\napp.use((req, res) =>\n{\n    res.end(\xe2\x80\x98Hello World\xe2\x80\x99);\n});\n\nhttps.createServer(option, app).listen(8000);\n\n
Run Code Online (Sandbox Code Playgroud)\n

我已使用 pm2 使用以下命令启动此应用程序

\n

sudo pm2 start app.js --watch

\n

我正在使用以下 cronjob 更新 SSL 证书

\n

0 8 * * * sudo certbot renew

\n

我希望每当 certbot 更新 SSL 证书时自动重新加载 SSL 证书。我怎样才能实现这个目标?

\n

rma*_*nna 14

对于我们这些无力承担或不愿意重新启动服务器来重新加载证书并且对Dylan Landry基于 SNI 的方法不满意的人来说,有一种内置于节点中的专用方法可以实现此目的有一段时间,via server.setSecureContext(其中服务器是标准节点https服务器实例)。请参阅下面的片段:

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);
});
Run Code Online (Sandbox Code Playgroud)

无可否认,fs.watch超时代码有点笨拙,可以使用chokidar之类的东西和一些更广泛的逻辑来改进,以监视所有 3 个相关文件的状态。我选择让事情变得简单,以专注于有趣的部分:setSecureContext

有关参考,请参阅 https://nodejs.org/api/tls.html#tls_server_setsecurecontext_options

另外,这要归功于nolimitdev ,他在之前就想出了其中的大部分setSecureContext内容。


Rag*_*arg 7

您可以使用该标志--post-hook在每次续订后重新启动您的应用程序。

certbot renew --post-hook "pm2 restart app_name"
Run Code Online (Sandbox Code Playgroud)
更新#1

请注意,我们正在运行的命令位于 crontab 中,任何全局程序都必须使用完整路径引用。您可以使用该which命令查找该命令的可执行文件路径。