我有一个云服务器池(约 50 个),需要使用 SSH 与许多其他远程云服务器(约 4000 个)通信。每个远程服务器都有自己的 SSH 密钥,因此我们需要一个地方来安全地存储所有这些远程服务器的 SSH 密钥。我们应该如何存储这些密钥而不把它们全部保存?
在一个地方安全地存储大量 SSH 密钥并让我们的服务器在运行时请求它们的最佳方法是什么?
我有一个云服务器池(约 50 个),需要使用 SSH 与许多其他远程云服务器(约 4000 个)通信。每个远程服务器都有自己的 SSH 密钥,因此我们需要一个地方来安全地存储所有这些远程服务器的 SSH 密钥。我们应该如何存储这些密钥而不把它们全部保存?
在一个地方安全地存储大量 SSH 密钥并让我们的服务器在运行时请求它们的最佳方法是什么?
你必须做出重要的区分:有公钥和私钥。当“安全存储”时,它们需要不同的“安全”概念。
每个 SSH 服务器都拥有一个公钥/私钥对。每个服务器都应该生成自己的密钥对,并且私钥不应该离开服务器本身。公钥是公开的,这意味着每个人都可以学习它。当您连接到服务器时,这是服务器告诉您的第一件事:它的公钥。它在网络上大喊大叫。在处理 SSH 公钥及其存储时,问题实际上是完整性问题:给定的 SSH 客户端必须记住它要与之通信的所有服务器的公钥($HOME/.ssh/known_hosts
通常 Linux SSH 客户端的文件);攻击者可能想要在其中包含一个假公钥,以运行一个假服务器。
每个 SSH 客户端可能拥有一个公钥/私钥对:这样的密钥对将用于服务器的客户端身份验证。如果您使用基于密码的客户端身份验证,则客户端没有此类密钥对。如果您使用基于密钥的客户端身份验证,那么每个服务器都必须知道“授权客户端”的公钥($HOME/.ssh/authorized_keys
Linux SSH 实现)。
在您的情况下,您有 50 个 SSH 客户端与 4000 个 SSH 服务器通信。因此,使用正常的 SSH 模型,您必须确保:
鉴于这些数字,相关文件会很庞大,密钥管理会成为问题(如果添加新客户端,则必须将新客户端的公钥导入 4000 台服务器,并具有受保护的完整性)。发明了公钥基础设施来解决这个问题。原始的“官方” OpenSSH实例不知道如何使用 X.509 证书;但是,存在修改后的版本(另请参阅上一个问题)。使用支持 X.509 的 SSH 代码库,您可以运行自己的证书颁发机构(例如开源EJBCA),并为您的客户端和服务器颁发证书。这样,SSH 客户端和服务器将在需要时动态地相互发送他们的证书。每台机器只需要存储自己的私钥和证书,并且还“知道”CA 证书(在相关的“信任库”中)。添加一个新的客户端或一个新的服务器只是发布一个证书,管理问题就解决了(或者,更确切地说,移动:现在你有一个 PKI 来处理)。
这是 Puppet、Chef 等配置管理软件的工作。它的创建正是为了处理这类问题。如果您有这么多服务器,我强烈建议您使用配置管理软件。
关于安全存储密钥的部分,一种选择是将私钥存储在 HSM(硬件安全模块)中。有一些知名供应商提供这些服务,但也有其他选择。参见例如Cryptostick。
使用 HSM 的优点是私钥只能在系统上存在硬件设备时使用,并且不能将私钥复制到其他地方。
这种类型的解决方案还需要对 SSH 服务器上的授权 SSH 密钥进行适当的审计和管理。否则,没有什么能阻止入侵者在 SSH 服务器中生成和放置他们自己的密钥集。
然而,管理这些密钥是一个问题。有用于管理 SSH 密钥的商业产品,但我不知道有什么好的开源解决方案。
正如 Thomas 所说,一种选择是转向基于 PKI 的方法,但这需要更新所有 SSH 客户端和服务器。
免责声明:我在一家销售商业 SSH 密钥管理产品的公司工作。
考虑一些可以存储和动态管理(更改)ssh 密钥的 ssh 密钥管理软件,这直接类似于密码管理系统。
然而,这些解决方案是有代价的!