【问题标题】:Certificate Discovery Service证书发现服务
【发布时间】:2018-05-19 15:54:30
【问题描述】:


我正在设计一个微服务架构,并且已经使用Let's Encrypt and certbot 生成的 SSL 证书设置了 https 保护。

提供的证书会定期重新生成,然后我必须将新证书重新导入我所有服务的密钥库中。

为了避免这种情况,我正在尝试实现一组 REST API,以允许服务以编程方式自动检索新证书并导入它们到他们自己的密钥库中,或者只是以编程方式使用它。

正如标题所说:一种“证书发现服务”,或者,如果您愿意,也可以是“远程证书存储库”

我知道有 java.security.* 包可以让我处理这类事情,但我有两个问题要问大家:

  1. 您认为从架构的角度来看,这是解决我的问题的最佳方法吗?
  2. 您推荐哪个序列化/反序列化进程之王?是否已经有任何库/框架/工具可以做类似的事情,我可以利用?

谢谢。 再见

【问题讨论】:

  • 我不会把这个基础设施的责任交给微服务。相反,我会创建一个专用服务来更新证书并在必要时重新启动微服务。
  • 谢谢康斯坦丁。我想“服务”是指系统服务。好的,我明白你的意思了,但是如果我的微服务分布在多个虚拟机上呢?
  • 视情况而定。例如,如果您使用 Docker Swarm,您可以将证书放入 Docker 机密中,然后 Swarm 负责复制。您也可以使用rsyncscp 复制证书。
  • 在特定情况下,docker secret 是最好的解决方案。谢谢

标签: rest ssl ssl-certificate microservices keystore


【解决方案1】:

仅供参考,这是一个“意见问题”,有些人在 StackOverflow 上对此表示不满,但我不是其中之一,所以我会给你 2 美分。

集成解决方案与复合解决方案

您所描述的场景是我创建 Greenlock.js(ACME 套件 / Let's Encrypt 客户端库、cli 和 Web 服务器的套件)的原因之一。

我想要一个完全集成的解决方案,它可以自动提供证书而无需人工干预(此外,当时 certbot 很难安装并且使用了太多 RAM,以至于我无法在我正在使用的 IoT 设备上使用它) .

在我的例子中,我创建了一个插件系统来支持不同的存储机制(fs、redis、sql、aws s3、azure 存储等),然后其他作者提供了其中的大部分机制。

听起来 certbot 可能会作为一个复合解决方案(包装它)为您工作,但如果您要经历创建证书存储等的麻烦,您可能还想与 Java ACME 集成库(只要确保它支持 ACME 草案 11 / Let's Encrypt v02)。

另一种想法是使用像 Greenlock 这样的东西作为反向代理到您的应用程序的 https 前端(尽管 Greenlock 可能无法满足您的需求 - java 或 go 解决方案,如果存在的话,可能更适合您从它的声音)。

(对我来说,围绕 Greenlock 创建一些 REST API 以使其能够充当证书分发的微服务对我来说听起来也很有趣,而且这样做并不需要太多工作 - 但我必须了解更多信息更好地了解您的项目)

回顾:

  • 在每个服务上使用(包装)certbot 并将文件作为微服务同步到远程存储
  • 集成原生 ACME / Let's Encrypt 解决方案并与存储插件同步,以允许各种类型的现有存储服务
  • 创建一个单独的服务来处理证书颁发,在每个服务上使用一个 rest api

它们都是有效的,并且取决于已经可用的代码,它们都很容易做到。

在每个实例上运行 certbot 的唯一问题是,它可能很难连接到它用来检查证书的系统以让它使用远程服务。

最佳选择?

我个人认为第二种选择(将 ACME 代码集成到服务中并使用插件架构进行存储)是最好的,因为在处理 ACME 证书的微服务失败的情况下,您的其他服务仍然能够获得它们的拥有(查找失败,他们获得证书而不是使用现有证书)。这是一个渐进的增强。这也是 Greenlock 的插件架构非常适合的地方。

格式和捆绑

有些人可能会说您希望使用 P12 拥有一个带有密码短语等的密钥库,我认为这是有效的。

但是,这将在传输过程中进行加密,并且几乎可以肯定的是,如果您的网络服务器遭到入侵,密码也将被泄露,因此我倾向于使用简单的 PEM 和 JWK。

在您的用例中,听起来您可能不需要 JWK,所以这意味着只需要 PEM。

PEM 只需要剥离空白和 cmets,然后从标准 Base64 解码,如果出于某种原因需要手动将其解码为 DER。同样,可以通过删除 cmets 和空格,然后将 - 替换为 _ 和将 / 替换为 +,将其转换为 Base64URLSafe。

另外,我真的很喜欢这些作品的存储和分发模式:

  • cert.pem
  • chain.pem
  • privkey.pem

因为您可以轻松地将它们以您需要的任何方式组合起来,以便将它们传送到任何类型的网络服务器。

  • fullchain.pem (cert.pem + chain.pem) 用于 Apache、Nginx、Node 等
  • bundle.pem (fullchain.pem + privkey.pem) 用于 HAProxy

所以我会说用 PEM 发送一个 JSON 对象:

{ "cert": "..."
, "chain": "..."
, "privkey": "..."
}

然后让客户端根据需要做response.cert + '\\r\\n' + response.chain等构造fullchain.pembundle.pem

最佳选择?

无论是最简单和最便携的 - 可能是 PEM,然后是 JWK,接下来可能是 Base64URLSafe,但不是任何特定 Java 库的自定义格式。将来您可能会扩展到支持非 Java 服务。

【讨论】:

    猜你喜欢
    • 2015-07-31
    • 2020-01-01
    • 1970-01-01
    • 2012-08-06
    • 2014-05-11
    • 2019-01-07
    • 2012-07-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多