如何为微服务创建 public 密钥存储?
How to create a public key store for microservices?
我在 docker 环境中实现了一组微服务。这些服务中的每一个都使用 JWT 令牌相互通信。当服务A调用服务B时
- 服务A,使用他的私钥签署令牌并传递给服务
B
- 服务 B,从 public 密钥库获取服务 A 的 public 密钥并验证令牌
Public/private 密钥生成过程由微服务本身完成,然后它们会将 public 密钥传递给 public 密钥库。所以 public 密钥库唯一要做的事情,
- 存储 public 服务发送的密钥
- 根据请求向服务发送正确的 public 密钥
我要做的与这张图中显示的类似。
上图来自:https://www.youtube.com/watch?v=dBdZrw2pPvc&t=462s
所以我的问题是,是否有这种 public 密钥存储的标准实现?如果有,它们是什么?
如果安全性不重要:
- Redis:https://redis.io/
- 领事:https://www.consul.io/
- 等:https://coreos.com/etcd
- 动物园管理员:https://zookeeper.apache.org/
如果安全很重要:
- 保险库:https://www.vaultproject.io/
- 召唤:https://www.conjur.com/
- 甲状腺素:https://thycotic.com/
- Docker 秘密:https://docs.docker.com/engine/swarm/secrets/
老实说还有很多选择,但这些是 DevOps 社区最著名和审查过的一些。
披露:我是 Conjur 的 CTO。
考虑工作流程:
- 服务A的容器启动。
- 它生成一个新的密钥对。
- 它将 public 密钥提交到 public 密钥库。
- public 密钥库接收 public 密钥。
- public 密钥库将它收到的 public 密钥与身份 "service-a" 相关联。
- 服务 A 签署对服务 B 的请求。
- 服务 B 向密钥库询问服务 A 的已知 public 个密钥。
- 密钥库提供 public 个密钥。
- 服务 B 验证签名与其中一个密钥匹配。
public 密钥库必须确保:
- 以防篡改的方式存储 public 密钥。
- 以防篡改的方式将每个 public 密钥与服务身份相关联。
- 为管理员提供一些方法来操纵密钥库(例如,删除死容器的密钥)。
- 对发生的一切进行审计记录。
但还有一点很难。在步骤 (5) 中,当密钥库收到服务 A 的密钥时,它需要验证该密钥确实来自服务 A,而不是来自冒名顶替者。换句话说,它必须对请求进行身份验证。
如何执行此操作取决于基础架构的详细信息。如果您使用原始 Docker(相对于 Kubernetes),您可以使用服务器上的代理将容器的 IP 地址关联到机器上的容器列表 (docker ps
)。这会告诉你容器的图像,它应该告诉你服务的身份。
这个问题有很多微妙之处,每个容器环境的解决方案都有些不同。
我在 docker 环境中实现了一组微服务。这些服务中的每一个都使用 JWT 令牌相互通信。当服务A调用服务B时
- 服务A,使用他的私钥签署令牌并传递给服务 B
- 服务 B,从 public 密钥库获取服务 A 的 public 密钥并验证令牌
Public/private 密钥生成过程由微服务本身完成,然后它们会将 public 密钥传递给 public 密钥库。所以 public 密钥库唯一要做的事情,
- 存储 public 服务发送的密钥
- 根据请求向服务发送正确的 public 密钥
我要做的与这张图中显示的类似。
上图来自:https://www.youtube.com/watch?v=dBdZrw2pPvc&t=462s
所以我的问题是,是否有这种 public 密钥存储的标准实现?如果有,它们是什么?
如果安全性不重要:
- Redis:https://redis.io/
- 领事:https://www.consul.io/
- 等:https://coreos.com/etcd
- 动物园管理员:https://zookeeper.apache.org/
如果安全很重要:
- 保险库:https://www.vaultproject.io/
- 召唤:https://www.conjur.com/
- 甲状腺素:https://thycotic.com/
- Docker 秘密:https://docs.docker.com/engine/swarm/secrets/
老实说还有很多选择,但这些是 DevOps 社区最著名和审查过的一些。
披露:我是 Conjur 的 CTO。
考虑工作流程:
- 服务A的容器启动。
- 它生成一个新的密钥对。
- 它将 public 密钥提交到 public 密钥库。
- public 密钥库接收 public 密钥。
- public 密钥库将它收到的 public 密钥与身份 "service-a" 相关联。
- 服务 A 签署对服务 B 的请求。
- 服务 B 向密钥库询问服务 A 的已知 public 个密钥。
- 密钥库提供 public 个密钥。
- 服务 B 验证签名与其中一个密钥匹配。
public 密钥库必须确保:
- 以防篡改的方式存储 public 密钥。
- 以防篡改的方式将每个 public 密钥与服务身份相关联。
- 为管理员提供一些方法来操纵密钥库(例如,删除死容器的密钥)。
- 对发生的一切进行审计记录。
但还有一点很难。在步骤 (5) 中,当密钥库收到服务 A 的密钥时,它需要验证该密钥确实来自服务 A,而不是来自冒名顶替者。换句话说,它必须对请求进行身份验证。
如何执行此操作取决于基础架构的详细信息。如果您使用原始 Docker(相对于 Kubernetes),您可以使用服务器上的代理将容器的 IP 地址关联到机器上的容器列表 (docker ps
)。这会告诉你容器的图像,它应该告诉你服务的身份。
这个问题有很多微妙之处,每个容器环境的解决方案都有些不同。