管理密钥对的常用实用策略是什么?

信息安全 密钥管理 公钥基础设施 SSH
2021-09-06 14:24:58

我有少量不同的工作站(加上 iPhone 等客户端设备),用于使用 SSH 连接到众多服务器。

最初,当我了解 PKI 时,我在我的工作站上创建了一个密钥对,我立即开始在任何地方使用它(意味着我将它复制到我的笔记本电脑等),并用它来连接我的所有服务器帐户。

从那以后,我形成了这样一种观点,即这类似于在任何地方都使用一个密码,并且我可能需要有选择地撤销访问权限,例如,如果我的一个工作站遭到破坏。

基本上我正在尝试制定处理密钥对的个人策略:

什么是安全地考虑密钥对以供一般使用,同时保持实用性的正确方法?(即,我认为每个连接点的一次性密钥对也不一定有意义。)

像我过去所做的那样,密钥对从所有接入点(“me-everywhere-id_rsa”)全局表示个人身份是错误的,还是我目前认为唯一的客户端 - 用户组合应该始终表示为它自己的密钥(“me-on-my-personal-laptop-id_rsa”)更合适?

您是否重复使用相同的密钥来连接所有服务器,或者在什么情况下您会考虑创建一个单独的密钥?

4个回答

您已经看到了要点:如果您的一台机器遭到破坏,则必须“撤销”这台机器上包含的私钥:您必须配置您连接的所有服务器以拒绝使用该密钥的进一步身份验证尝试(即您删除来自.ssh/authorized_keys服务器的相应公钥)。有一种缓解技术,其中包括使用密码(或密码)保护私钥。这是有代价的,即您必须输入密码(ssh-agent可以很方便);另一方面,这可能会暂时阻止攻击者获取私钥(这取决于妥协的类型,但如果是盗窃整台机器 - 移动设备的合理场景 - 那么密码将阻止立即访问私钥并给您一些时间重新配置服务器)。


有人可能会注意到“PKI”的意思是“公钥基础设施”,而 SSH 在这方面是初级的。在完整的 PKI 中,将使用证书、委托和集中撤销。有证书:

  • 您将创建一个 CA 密钥对,安全地存储在某处;
  • 对于每台客户端机器,您将获得一个新的密钥对,公钥由 CA签名;
  • 服务器将被配置为自动接受CA 签名的任何公钥(它们会知道 CA 公钥,但不知道单个客户端机器密钥);
  • CA 将维护并定期发布撤销信息,即即使这些密钥已由 CA 签名也必须不再接受的公钥列表(撤销信息必须推送到服务器,或按需提取)。

证书的好处在于您可以集中决策,实际上,这意味着如果您从客户端计算机连接到 20 个服务器,然后添加新的客户端计算机,您不必手动将新的公钥推送到所有 20 台服务器。

OpenSSH从 5.4 版(2010 年 3 月 8 日发布)开始,对证书有一些支持;请参阅手册页中的同名部分ssh-keygenOpenSSH 证书的格式比“通常的”X.509 证书(与 SSL 一起使用)要简单得多。简化也有代价:没有集中的撤销支持。相反,如果私钥被泄露,您仍然必须将所有服务器上相应的公钥列入黑名单,而在 OpenSSH 中,黑名单是一个白名单(AuthorizedPrincipalsFile中的选项sshd_config),通常受root. 所以撤销不能很好地工作,每当您创建或释放密钥时,您仍然必须在每台服务器上手动配置内容,这正是 PKI 应该废除的不便之处。

可以仍然制作有时间限制的密钥,因为 OpenSSH 证书可以嵌入有时间限制的密钥。在这种情况下,你会给每台客户端机器一个密钥,比如一个星期。使用一周后失效的密钥和服务器已知的 CA 公钥,您拥有主要的 CA 优点(当将新机器添加到客户端池时,无需在所有服务器上推送任何内容),如果私有密钥被泄露,损害是“有限的”,假设你有一个密钥密码,大概可以抵抗一周的破解(但如果妥协是对密钥记录器的恶意收购,这将不起作用)。有时间限制的密钥会随着时间的推移变得乏味,并且他们假设所有服务器都有一个正确设置的时钟,这并不总是给定的(不幸的是,由于服务器时钟非常关闭而被锁定在服务器之外,

SSH 的另一个问题是很容易在每台服务器上添加公钥。这意味着,如果攻击者泄露了私钥并获得了对服务器的访问权一次,他可以将自己的公钥添加到.ssh/authorized_keys该服务器上,并且再多的撤销也无法解决这个问题。撤销本质上是一个异步过程。因此,它没有实施足够严格的损害控制。


鉴于 SSH 支持证书的缺点,没有合理的方案可以避免在某些情况下必须在所有服务器上进行一些配置。因此,当您添加新的客户端计算机时,您基本上有以下选择:

  1. 您从另一台客户端计算机复制私钥(这就是您现在正在做的事情)。这不需要在服务器上进行额外配置。

  2. 您为该机器创建一个新的密钥对。您必须将公钥推送到所有服务器。

在密钥泄露出现时,您必须连接到所有服务器以从所有.ssh/authorized_keys. 这是不可避免的(为了避免它,你必须使用证书,而 SSH 不擅长证书,见上文)。然后,如果您使用了选项 1,那么您必须创建一个新的密钥对并将其推送到所有使用受损私钥副本的客户端计算机。

因此,在正常情况下,选择 1 比选择 2 需要更少的配置工作,但如果发生密钥泄露,情况就会逆转。由于妥协通常是罕见的事件,这将有利于选择 1(这是你已经做的)。因此,我建议您使用强密码保护您的私钥,并将其复制到您的所有客户端系统。

注意:在上述所有内容中,我假设您想使用 SSH 连接到服务器列表,并且您想从任何客户端计算机访问任何服务器。可能希望限制访问,例如仅从一台或两台特定客户端计算机访问给定服务器。这可以通过多个客户端密钥来完成,但配置复杂性呈二次方增加。

我赞成每个身份验证领域拥有一个密钥。因此,对于工作中的每台台式机或服务器机器(都非常安全并在一组管理员的控制下),我有一个私钥。我在新家用 PC 上使用与旧家用 PC 相同的私钥。我在笔记本电脑和其他移动设备上使用不同的键。这种方法允许进行细粒度的风险管理:我可以单独撤销密钥,并通过不授权某些机器上的某些密钥来限制我的帐户参与升级渗透的可能性(我没有做太多,但这是一个选项对于偏执狂)。

只要你不做任何复杂的事情,复制公钥并不是那么困难。您可以保留一份授权​​密钥的大列表并在任何地方进行同步;注册设备意味着将一项添加到该列表并推送更改。如果您首先拥有一个中央数据存储库,那么这并不比提取私钥更多的工作。

请注意,虽然拥有单独私钥的最明显优势是能够单独撤销一个,但它们也具有可用性优势:如果机器 A 上的系统管理员决定撤销您所在的 C 机器的密钥,您可能仍然可以找到一些仍然接受 C 的密钥并且其密钥被 A 接受的机器 B。这看起来确实很深奥,但这发生在我身上一次(在Debian 意识到他们没有播种他们的 RNG之后,我很高兴不必完全依赖列入黑名单的密钥),而我还没有在紧急情况下撤销密钥。

每个机器对保留一个单独的密钥对甚至有一个理论上的好处,因为它允许单独的撤销。但是收益极小,管理难度也大了很多(不能再广播授权列表了)。简化密钥管理是公钥加密优于共享密钥的关键优势。

基本上我正在尝试制定处理密钥对的个人策略

如果您主要负责相关服务器,那么我强烈建议您考虑寻找像 puppet/chef 这样的配置管理工具。它们都有将 SSH 密钥分发到您的机器的方法。

我开始使用 puppet 的原因特别是因为我想要一种很好的方法来在人员变动时快速撤销我大约 60 台 Linux 服务器上的密钥。

当您有一个配置管理工具来管理您的密钥时,拥有许多密钥对就变得容易得多。无需手动撤销每个盒子上的密钥,或在每个盒子上添加新密钥,您只需在配置主机上添加公钥,客户端将在您为配置管理设置的任何轮询间隔内更新授权列表工具。

这确实意味着您非常信任您的配置管理主机不会受到损害。因为它通常在您配置它的每台机器上执行具有 root 权限的任务,所以您必须确保它被严格锁定,并进行大量审核。如果攻击者要破坏配置主机,那么它可以执行任何操作,例如添加新密钥、添加新帐户等。

我在每个领域和每台机器上使用一个密钥。从 2 个工作站访问 4 个遥控器 => 8 个私钥。切勿将私钥从主机复制到另一台主机。如果一个工作站受到威胁,请撤销所有这些密钥。

由于创建密钥和配置 SSH 以使用它们非常繁琐,我编写了一个专门用于管理我的 SSH 密钥以供 Github 访问的工具:github-keygen