【问题标题】:How to automatically reload updated SSL certificates in Node.js Application如何在 Node.js 应用程序中自动重新加载更新的 SSL 证书
【发布时间】:2020-11-29 04:15:41
【问题描述】:

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

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);

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

sudo pm2 start app.js --watch

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

0 8 * * * sudo certbot renew

我想在 certbot 更新 SSL 证书时自动重新加载 SSL 证书。我怎样才能做到这一点?

【问题讨论】:

    标签: node.js express lets-encrypt


    【解决方案1】:

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

    certbot renew --post-hook "pm2 restart app_name"
    
    更新 #1

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

    【讨论】:

    • 我收到此错误:Unable to find post-hook command pm2 in the PATH. 正确的是 PM2 不在 PATH 中,但这并不意味着它不是全局可用的命令。我不知道这个错误是否会阻止钩子被执行
    • @fermmm 您能否分享一下您的 pm2 在全球范围内的可用性?程序的全局可用性通常由用户配置文件处理(通过在 .bashrc 或类似文件中设置 PATH )。 Cron 不使用任何用户配置文件,而是使用干净的环境,我们必须为其提供我们想要在其中使用的程序的完整路径。
    • 这对我有用(用你的用户替换 USER 2 次):certbot renew --pre-hook "sudo -u USER bash -c '. ~/.bashrc; pm2 stop app_name'" --post-hook "sudo -u USER bash -c '. ~/.bashrc; pm2 start app_name'" 看到这个:github.com/certbot/certbot/issues/8885 所以答案不起作用,应该编辑
    • @fermmm 答案以通用方式编写,因此用户可以了解后挂钩,而不是为复制粘贴而编写。您使用的是一种解决方法,而不是推荐的解决方案,因为您已经创建了与用户配置文件紧密耦合的解决方案,如果有人更改用户配置文件中的配置或配置文件被删除,您的 cron 作业也会受到影响。正确的解决方法是直接在命令中引用程序或者写一个新的可执行文件。
    【解决方案2】:

    您无需重新启动服务器即可重新加载新证书。

    根据问题Reload certificate files of https.createServer() without restarting node server #15115 ,特别是来自mscdex的this comment

    FWIW 你已经可以用 SNICallback() 做到这一点了:

    const https = require('https');
    const tls = require('tls');
    const fs = require('fs');
    var ctx = tls.createSecureContext({
      key: fs.readFileSync(config.sslKeyPath),
      cert: fs.readFileSync(config.sslCrtPath)
    });
    https.createServer({
      SNICallback: (servername, cb) => {
        // here you can even change up the `SecureContext`
        // based on `servername` if you want
        cb(null, ctx);
      }
    });
    

    这样,您所要做的就是重新分配 ctx​​,然后它将用于任何未来的请求。

    使用上面的示例,您只需在 SNICallback 内的证书路径上再次执行 fs.readFileSync 并将它们附加到 ctx 对象。但是,当你知道它们刚刚改变时,你只想这样做。您可以从 javascript 中查看文件以进行更改。您可以使用 fs.watch() 或来自 npm 的内容。

    【讨论】:

    • 这种方法安全吗?
    • 我不确定它的安全漏洞是什么,我还没有听说过,但我想我也不会是第一个知道的。
    • 我有另一个问题,当 SSL 自动更新时,我的站点无法连接到 node-express 服务器,但服务器正在运行。有什么办法解决这个问题吗?
    • 不是我的头顶。这是我不是从经验中找到的答案,而是通过我自己的谷歌搜索找到的。我建议掀起你自己的问题。有关如何无法连接的更多信息以及您当前以编程方式交换证书的实现的代码会有所帮助。抱歉,我无法提供更多帮助。
    猜你喜欢
    • 1970-01-01
    • 2022-12-15
    • 2016-10-20
    • 2020-10-07
    • 1970-01-01
    • 2021-12-26
    • 1970-01-01
    • 2017-11-28
    • 1970-01-01
    相关资源
    最近更新 更多