本章将 SPIFFE 与其他解决类似问题的技术进行了比较。

简介

SPIFFE 和 SPIRE 所解决的问题并不新鲜。每一个分布式系统都必须有某种形式的身份认证才是安全的。网络公钥基础设施、Kerberos/Active Directory、OAuth、秘密存储和服务网格就是例子。

然而,这些现有的身份识别形式并不适合用于识别组织内的内部服务。网络 PKI 的实施具有挑战性,对于典型的内部部署来说也是不安全的。Kerberos,Active Directory 的认证组件,需要一个永远在线的票证授予服务器,并且没有任何同等的证明。服务网格、秘密管理器和覆盖网络都解决了服务身份的部分难题,但并不完整。SPIFFE 和 SPIRE 是目前服务身份问题的唯一完整解决方案。

网络公钥基础设施

网络公钥基础设施(Web PKI)是广泛使用的从我们的网络浏览器连接到安全网站的方法。它利用 X.509 证书来断言用户正在连接到他们打算访问的网站。由于你可能对这种模式很熟悉,所以有理由问:为什么我们不能在我们的组织内使用 Web PKI 进行服务识别?

在传统的 Web PKI 中,证书的发放和更新完全是手工操作。这些手工过程不适合现代基础设施,因为在现代基础设施中,服务实例可能随时动态地增长和缩小。然而,在过去的几年里,网络 PKI 已经转向了一种自动的证书颁发和更新过程,称为域名验证(Domain Validation)。

在域名验证中,证书颁发机构向证书请求者发送一个令牌。证书请求者使用 HTTP 服务器共享这个令牌。证书颁发机构访问该令牌,对其进行验证,然后签署该证书。

这种安排的第一个问题是,内部服务经常没有单独的 DNS 名称或 IP 地址。如果你想在所有服务之间进行相互的 TLS,那么即使是客户端也需要 DNS 名称来获得证书,这对配置来说是个挑战。为在一台主机上运行的多个服务分配身份需要单独的 DNS 名称,这对配置来说也是一个挑战。

一个更微妙的问题是,任何能够成功响应请求的人都可以成功获得证书。这可能是在同一台服务器上运行的不同服务,甚至是在可以篡改本地二层网络的不同服务器上。

一般来说,虽然网络 PKI 对互联网上的安全网站很有效,但它并不适合用于服务身份。许多需要证书的内部服务并没有 DNS 名称。如果攻击者成功渗透到本地网络的任何服务中,目前可用的做证书验证的过程很容易被破坏。

Active Directory(AD)和 Kerberos

Kerberos 是一个认证协议,最初于 20 世纪 80 年代末在 MIT 开发。最初,它被设计为允许使用一个集中的用户数据库进行人对服务的认证。后来,Kerberos 被扩展到支持服务对服务的认证,以及除了用户账户之外还可以使用机器账户。Kerberos 协议本身是与帐户数据库无关的。然而,Kerberos 最常见的用法是在 Windows 域中进行认证,使用 Active Directory (AD) 作为账户数据库。

Kerberos 的核心凭证被称为 票据(ticket)。一个票据是一个可以被单个客户用来访问单个资源的凭证。客户端通过调用 Ticket Granting Service (TGS) 获得票据。客户端在访问每一个资源时都需要一个新的票据。这种设计导致了更多的聊天协议并降低了可靠性。

所有服务都与 TGS 建立了信任关系。当一个服务在 TGS 注册时,它与 TGS 共享密钥材料,如对称秘密或公钥。TGS 使用密钥材料来创建票据,以验证对该服务的访问。轮换密钥材料需要服务和 TGS 之间的协调。服务必须接受以前的密钥材料,并保持对它的了解,以便现有的票据保持有效。

SPIRE 如何缓解 Kerberos 和 AD 的弊端

在 SPIRE 中,每个客户端和资源将调用 SPIRE 服务器一次,以获得其凭证(SVID),所有资源都可以在信任域(和联合信任域)中验证这些凭证,而无需再调用 SPIRE 服务器。SPIRE 的架构避免了为每个需要访问的资源获取新凭证的所有开销。

基于 PKI 的认证机制,如 SPIRE,使凭证轮换更简单,因为这种服务和集中式验证器之间的密钥材料协调并不存在。

最后,值得注意的是,Kerberos 协议将服务与主机名紧密结合在一起,这使得每个主机和集群的多个服务变得复杂。另一方面,SPIRE 很容易支持每个工作负载和集群的多个 SVID。也有可能将同一个 SVID 分配给多个工作负载。这些特性提供了一个强大的、高度可扩展的身份识别方法。

OAuth 和 OpenID Connect(OIDC)

OAuth 是一个旨在实现访问 ** 委托(delegation)** 协议,而不一定是作为一个实现认证本身的协议。OIDC 的主要目的是允许人类允许一个二级网站(或移动应用程序)代表他们对不同的一级网站采取行动。在实践中,该协议能够在二级网站上对用户进行认证,因为被委托的访问凭证(OAuth 协议中的访问令牌)是来自一级网站的证明,即用户针对该网站进行了认证。

如果主网站包括用户信息或提供了一种使用访问令牌检索用户信息的方法,那么二级网站可以使用主网站的令牌来验证用户。OpenID Connect 是 OAuth 的一种观点,是一个很好的例子。

OAuth 是为人类设计的,而不是为非人类实体设计的。OAuth 的登录过程需要浏览器的重定向与交互式密码。OAuth 2.0 与其前身相似,包括对非人类实体的支持,通常是通过创建服务账户(即代表工作负载而不是人类的用户身份)。当一个工作负载想要获得 OAuth 访问令牌以访问远程系统时,它必须使用 OAuth 客户端的秘密、密码或刷新令牌来验证 OAuth 提供者并接收访问令牌。工作负载都应该有独立的凭证,以实现工作负载身份的高度精细化。对于弹性计算来说,这些凭证的管理很快就会变得复杂和困难,因为每个工作负载和身份都必须向 OAuth 提供商注册。当秘密必须被撤销时,长期存在的秘密会带来更多的复杂性。由于轮换,秘密在环境中的传播减少了基础设施的流动性,在某些情况下,如果开发人员手动管理秘密,可能会出现攻击的载体。

SPIFFE 和 SPIRE 如何减轻 OAuth 和 OIDC 的复杂性

依靠预先存在的凭证来识别工作负载,如 OAuth 客户秘密或刷新令牌,无法解决底层乌龟的问题(如第 1 章所解释)。在这些情况下,利用 SPIRE 作为身份提供者,允许在与 OAuth 基础设施联系之前发布引导凭证(bootstrap credential)或底层乌龟。SPIRE 极大地提高了安全性,因为没有长期的静态凭证需要与工作负载本身共同部署。SPIFFE 可以作为 OAuth 的补充。它消除了直接管理 OAuth 客户端凭证的需要 —— 应用程序可以根据需要使用他们的 SPIFFE ID 来验证 OAuth 提供商。事实上,OAuth 访问令牌本身可以是 SVID,允许用户以与工作负载相同的方式对 SPIFFE 生态系统中的服务进行认证。参见与 OIDC 的集成来了解更多。

秘密管理者

秘密管理器通常代表工作负载或管理员控制、审计和安全地存储敏感信息(共享秘密,通常是密码)。一些秘密管理器可以执行额外的功能,如加密和解密数据。许多秘密管理器的一个共同特征是中央存储,即所谓的保险库(vault),它对数据进行加密。工作负载在执行秘密检索或数据解密等操作前必须单独对保险库进行认证。

部署秘密管理器的一个典型的架构挑战是如何安全地存储工作负载用来验证秘密管理器本身的凭证。这有时被称为 “零号凭证”、“引导凭证”,或者更广泛地说,安全引入的过程。

通过提供一个可以存储、检索、轮换和撤销这些秘密的安全位置,使用一个秘密管理器极大地改善了依赖共享秘密的系统的安全状况。然而,大量的使用会使共享秘密的使用永久化,而不是使用强大的身份识别。

如何利用 SPIFFE 和 SPIRE 来减轻秘密管理人员的挑战

如果你确实需要使用一个秘密管理器,它可以被配置为使用 SPIFFE 证书进行认证。这允许你在服务之间使用相同的 SPIFFE 证书进行直接认证,并检索秘密来与非 SPIFFE 证书对话。

服务网格

服务网格旨在通过提供自动认证、授权和强制执行工作负载之间的相互 TLS 来简化工作负载之间的通信。服务网格通常提供集成的工具:

  • 确定工作负载。
  • 调解工作负载之间的通信,通常通过部署在每个工作负载附近的代理(sidecar 模式)。
  • 确保每个相邻的代理执行一致的认证和授权策略(一般通过授权策略引擎)。

所有主要的服务网格都包括一个原生的平台特定服务认证机制。

虽然服务网格可以在没有加密身份平面的情况下运行,但为了允许服务间的通信和发现,不可避免地要创建弱形式的身份。本实施方案中的服务网格不提供安全功能,也不解决前面讨论的现有信任根身份问题。

许多服务网格实现了自己的加密身份平面,或与现有的身份解决方案集成,以提供过境通信安全和信任根的解决。大多数服务网格实现了 SPIFFE 或其部分内容。许多服务网格实现都采用了 SPIFFE 规范的部分实现(包括 Istio 和 Consul),并可被视为 SPIFFE 身份提供商。有些将 SPIRE 作为其解决方案的一个组成部分(如 GreyMatter 或 Network Service Mesh)。

例如,Istio 使用 SPIFFE 进行节点识别,但其身份模型与 Kubernetes 的特定基元紧密耦合,并完全基于 Kubernetes。没有办法在 Istio 中基于 Kubernetes 之外的属性来识别服务。IBM 解释了为什么目前的 Istio 机制是不够的。与 SPIRE 这样的通用身份控制平面相比,当希望获得更丰富的证明机制时,或者当服务需要使用通用身份系统在 Istio 之外认证时,这对 Istio 构成了制约因素。使用 SPIRE 进行工作负载身份认证的另一个优势是,它可以确保不受服务网格控制的通信。出于这样的原因,组织有时会将 SPIRE 与 Istio 集成,并使用 SPIFFE 身份而不是内置的 Istio 身份。IBM 发布了一个例子,位于 IBM/istio-spire:Istio 身份与 SPIFFE/SPIRE

服务网格不是 SPIFFE/SPIRE 的直接替代品,相反,它们是互补的 SPIFFE/SPIRE 作为网格内更高层次抽象的身份解决方案。

专门实现 SPIFFE 工作负载 API 的服务网格解决方案支持任何期望该 API 可用的软件。能够为其工作负载提供 SVID 并支持 SPIFFE Federation API 的服务网格解决方案可以在网格识别的工作负载和运行 SPIRE 或运行在不同网格实现的工作负载之间自动建立信任。

覆盖网络

覆盖网络(Overlay Network)模拟了一个单一的统一网络,用于跨多个平台的服务。与服务网格不同,覆盖网络使用标准的网络概念,如 IP 地址和路由表来连接服务。数据被封装并跨过其他网络进行路由,创建一个建立在现有网络之上的节点和逻辑链接的虚拟网络。

虽然最常见的覆盖网络没有认证功能,但最新的网络有。然而,它们在允许服务连接之前仍然不能证明它们的身份。通常情况下,它们依赖于一个预先存在的证书。SPIFFE 很适合为覆盖网络节点提供证书。