开源 OpenPubkey SSH (OPKSSH):将单点登录集成到 SSH 中

7 分钟阅读

OPKSSH 使得使用诸如 OpenID Connect 之类的单点登录技术进行 SSH 非常容易,从而无需手动管理和配置 SSH 密钥。它在不添加除了你的身份提供商 (IdP) 之外的受信任方的情况下实现这一点。

我们很高兴地宣布 OPKSSH (OpenPubkey SSH) 已经在 OpenPubkey 项目的保护下开源。虽然底层协议 OpenPubkey 在 2023 年成为了 一个开源的 Linux 基金会项目,但 OPKSSH 是闭源的,归 BastionZero (现在的 Cloudflare) 所有。Cloudflare 已将此代码捐赠给 OpenPubkey 项目,使其成为开源。

在这篇文章中,我们将介绍 OPKSSH 是什么,它如何简化 SSH 管理,以及 OPKSSH 开源对你意味着什么。

背景

现代访问控制的基石是单点登录 (SSO),用户向 身份提供商 (IdP) 进行身份验证,作为响应,IdP 向用户颁发一个 token。用户可以出示此 token 以证明他们的身份,例如“Google 说我是 Alice”。SSO 是一种罕见的安全性技术,它既提高了便利性(用户只需登录一次即可访问许多不同的系统),又提高了安全性。

OpenID Connect

OpenID Connect (OIDC) 是用于 SSO 的主要协议。如下所示,在 OIDC 中,IdP(称为 OpenID Provider (OP))向用户颁发一个 ID Token,其中包含有关用户的身份声明,例如“email is alice@example.com”。这些声明由 OP 进行数字签名,因此任何收到 ID Token 的人都可以检查它是否确实由 OP 颁发。

不幸的是,虽然 ID Token 确实 包含诸如姓名、组织和电子邮件地址之类的身份声明,但它们_不_包含用户的公钥。这阻止了它们被用于直接保护诸如 SSH 或 端到端加密消息传递 之类的协议。

请注意,在整篇文章中,我们使用术语 OpenID Provider (OP) 而不是 IdP,因为 OP 指定了我们正在使用的 IdP 的确切类型,即 OpenID IdP。我们使用 Google 作为 OP 的示例,但 OpenID Connect 适用于 Google、Azure、Okta 等。

显示用户 Alice 使用 OpenID Connect/OpenPubkey 登录 Google,然后生成 PK Token

显示用户 Alice 使用 OpenID Connect 登录 Google 并接收 ID Token

OpenPubkey

OpenPubkey(如下所示)将公钥添加到 ID Token 中。这使得可以将 ID Token 像证书一样使用,例如“Google 说 alice@example.com 正在使用公钥 0x123”。我们将包含公钥的 ID token 称为 PK Token。OpenPubkey 的优点在于,与其他方法不同,OpenPubkey 不需要对现有 SSO 协议进行任何更改,并且支持任何符合 OpenID Connect 标准的 OP。

显示用户 Alice 使用 OpenID Connect/OpenPubkey 登录 Google,然后生成 PK Token 虽然 OpenPubkey 使得可以将 ID Token 用作证书,但 OPKSSH 扩展了此功能,以便这些 ID Token 可以用作 SSH 协议中的 SSH 密钥。这为 SSH 添加了 SSO 身份验证,而无需更改 SSH 协议。

为什么这很重要

OPKSSH 使用户和管理员无需管理长期存在的 SSH 密钥,从而使 SSH 更加安全和方便。

“在许多组织(甚至是非常注重安全的组织)中,过时的授权密钥数量通常比员工人数多。更糟糕的是,授权密钥通常授予命令行 shell 访问权限,这本身通常被认为是特权。我们发现,在许多组织中,大约 10% 的授权密钥授予 root 或管理员访问权限。SSH 密钥永远不会过期。” - Challenges in Managing SSH Keys – and a Call for Solutions by Tatu Ylonen (SSH 发明者)

在 SSH 中,用户生成一个长期存在的 SSH 公钥和一个 SSH 私钥。为了使用户能够访问服务器,用户或该服务器的管理员配置该服务器以信任该用户的公钥。用户必须保护包含其 SSH 私钥的文件。如果用户丢失此文件,他们将被锁定。如果他们将 SSH 私钥复制到多台计算机或备份密钥,则会增加密钥被泄露的风险。当私钥被泄露或用户不再需要访问权限时,用户或管理员必须从当前信任的任何服务器中删除该公钥。所有这些问题都会给用户和管理员带来麻烦。

OPKSSH 克服了这些问题:

提高安全性: OPKSSH 将长期存在的 SSH 密钥替换为由 OPKSSH 按需创建并在不再需要时过期的临时 SSH 密钥。这降低了私钥被泄露的风险,并限制了攻击者可以使用泄露的私钥的时间段。默认情况下,这些 OPKSSH 公钥每 24 小时过期,但可以在配置文件中设置过期策略。

提高可用性: 创建 SSH 密钥就像登录 OP 一样简单。这意味着用户可以从安装了 opkssh 的任何计算机上进行 SSH,即使他们没有将 SSH 私钥复制到该计算机。

要生成他们的 SSH 密钥,用户只需运行 opkssh login,他们就可以像通常一样使用 ssh。

提高可见性: OPKSSH 将 SSH 从通过公钥授权转换为通过身份授权。如果 Alice 想让 Bob 访问服务器,她不需要索要他的公钥,她只需将 Bob 的电子邮件地址 bob@example.com 添加到 OPKSSH 授权用户文件中,他就可以登录。这使得跟踪谁有权访问变得更加容易,因为管理员可以看到授权用户的电子邮件地址。

OPKSSH 不需要对 SSH 服务器或客户端进行任何代码更改。对 SSH 服务器上的 SSH 唯一需要的更改是在 SSH 配置文件中添加两行。为了方便起见,我们提供了一个安装脚本来自动执行此操作,如下面的视频所示。

工作原理

显示用户 Alice 使用其 SSH 公钥内的 PK Token SSH 到服务器。然后,服务器使用 OpenPubkey 验证器验证她的 SSH 公钥。

显示用户 Alice 使用其 SSH 公钥内的 PK Token SSH 到服务器。然后,服务器使用 OpenPubkey 验证器验证她的 SSH 公钥。

让我们看一个 Alice (alice@example.com) 使用 OPKSSH SSH 到服务器的例子:

考虑一下我们在无需对 SSH 协议或软件进行任何更改的情况下使 OpenPubkey 与 SSH 协同工作所面临的问题:

我们如何将 PK Token 从用户的机器内部的 SSH 协议传递到 SSH 服务器? 我们利用 SSH 公钥可以是 SSH 证书这一事实,并且 SSH 证书具有 一个扩展字段,该字段允许在证书中包含任意数据。因此,我们将 PK Token 打包到 SSH 证书扩展中,以便 PK Token 将作为 SSH 协议的正常部分在 SSH 公钥中传输。这使我们能够将 PK Token 作为 SSH 证书中的附加数据发送到 SSH 服务器,并允许 OPKSSH 在无需对 SSH 客户端进行任何更改的情况下工作。

我们如何在 PK Token 到达 SSH 服务器后检查其是否有效? SSH 服务器支持一个名为 AuthorizedKeysCommand 的配置参数,该参数允许我们使用自定义程序来确定 SSH 公钥是否已授权。因此,我们通过对 sshd_config 进行以下两行更改来更改 SSH 服务器的配置文件以使用 OpenPubkey 验证器而不是 SSH 验证器:

AuthorizedKeysCommand /usr/local/bin/opkssh verify %u %k %t
AuthorizedKeysCommandUser root

OpenPubkey 验证器将检查 PK Token 是否未过期、有效且由 OP 签名。它检查 PK Token 中的用户电子邮件地址以确定是否授权该用户访问服务器。

我们如何确保 PK Token 中的公钥实际上是保护 SSH 会话的公钥? OpenPubkey 验证器还检查 SSH 公钥中的公钥字段中的公钥是否与 PK Token 中的用户公钥匹配。这是因为 SSH 公钥中的公钥字段是保护 SSH 会话的实际公钥。

发生了什么

我们已经 开源了 OPKSSH,它采用 Apache 2.0 许可证,并在 GitHub 上以 openpubkey/opkssh 的形式发布。虽然 OpenPubkey 项目自项目成立之初就拥有将 SSH 与 OpenPubkey 结合使用的代码,但此代码旨在作为一个原型,并且缺少许多重要功能。有了 OPKSSH,OpenPubkey 中的 SSH 支持不再是一个原型,而是一个完整的功能。Cloudflare 不认可 OPKSSH,只是向 OPKSSH 捐赠代码。

OPKSSH 为 OpenPubkey 提供了以下改进:

了解更多信息

请参阅 OPKSSH 自述文件 以获取有关如何使用 OPKSSH 进行安装和连接的文档。

如何参与

有很多方法可以参与 OpenPubkey 或 OPKSSH。该项目通过 OPKSSH GitHub 进行组织。我们正在建立一个开放友好的社区,欢迎任何人的 pull request。如果您有兴趣参与,请参阅 我们的贡献指南

我们每月举行一次 社区 会议,该会议对所有人开放,您也可以在 OpenSSF Slack 的 #openpubkey 频道中找到我们。