在重启期间使用 https 站点将证书密码传递给 Nginx

Posted

技术标签:

【中文标题】在重启期间使用 https 站点将证书密码传递给 Nginx【英文标题】:Pass cert password to Nginx with https site during restart 【发布时间】:2016-01-10 02:56:18 【问题描述】:

我通过ansible 配置了 nginx 安装和配置(连同为https 站点设置 SSL 证书)。 SSL 证书在密码短语下。

我想写一个重启 nginx 的 ansilbe 任务。问题如下。

通常,带有 https 站点的 nginx 在重新启动期间会要求 PEM pass phrase。 Ansible 在 playbook 执行期间不会要求输入该密码。

solution 将解密的证书和密钥存储在某个私有目录中。但我真的不想将我的证书和密钥留在未加密的地方。

如何在重启期间通过ansible将密码传递给nginx(或openssl)?完美的场景如下:

    Ansible 要求提供 SSL 密码(通过 vars_promt)。另一种选择是使用 ansible vault。 Ansible 正在重启 nginx,当 nginx 请求 PEM pass phrase 时,ansible 正在向 nginx 传递密码。

有可能吗?

【问题讨论】:

【参考方案1】:

Nginx 有ssl_password_file 参数。

指定一个带有密码短语的文件,其中每个密码短语在单独的行中指定。加载密钥时会依次尝试密码短语。

例子:

http 
    ssl_password_file /etc/keys/global.pass;
    ...
    server 
        server_name www1.example.com;
        ssl_certificate_key /etc/keys/first.key;
    
    server 
        server_name www2.example.com;
        # named pipe can also be used instead of a file
        ssl_password_file /etc/keys/fifo;
        ssl_certificate_key /etc/keys/second.key;
    

你可以做的是将ssl_password_file 保存在 ansible-vault 中,复制它,重新启动 nginx,然后如果成功删除它。

我没有第一手经验,如果它真的有效,或者它可能有什么其他副作用(例如手动 service nginx restart 可能会失败),但对我来说这似乎是一种合乎逻辑的方法。

【讨论】:

将其复制到磁盘可能会破坏不将其存储在服务器上的全部意义...... 或者你可以生成一个不带密码短语的证书,通过在生成证书时添加-nodes到openssl命令 我认为这不是一个好的选择,因为从安全角度来看,密码文件非常危险 在密钥上设置密码的目的是防止证书在从存储(如 S3)泄漏时被使用。 Ansible 从本地 ansible-vault 之类的地方知道密码,并将证书/密钥组合仅部署到 Web 服务器。这将攻击因素限制为仅部署的 Web 服务器。【参考方案2】:

如果您对私钥有足够的权限限制(例如,只让 nginx 能够读取它),这可能就足够了。无论如何,Nginx 都必须将其加载到内存中;这对攻击者来说可能更难恢复,但如果他们对盒子有 root 访问权限,则无论如何都应该考虑密钥已被泄露。

或者,您可以将密码输入到正在重新启动的命令中(例如echo mypass | service nginx restart)。这将导致它以纯文本形式显示在进程列表中,不应被视为更安全。

我建议锁定文件的权限并且不设置密码。我不相信 Ansible 有任何方法可以指定对单个提示的响应,除了 sudo。

【讨论】:

以上是关于在重启期间使用 https 站点将证书密码传递给 Nginx的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Python 中以编程方式传递密码

将多个右值和左值传递给函数而不创建重载

Kubernetes - 如何将信任库路径和密码传递给 JVM 参数

HTTPS原理

利用腾讯云免费证书打造全https站

阿里云服务器给WordPress网站添加SSL证书,并且设置http自动跳转https