Skip to content

本文为 SPIFFE 官方规范 SPIFFE Federation 的中文译本,仅供学习参考;若与英文原文有出入,以英文版为准。

SPIFFE 联邦(Federation) ​

稳定性:稳定(Stable) —— 参见 STABILITY.md。

本备忘录的状态 ​

本文档为互联网社区规定了一项身份 API 标准,并欢迎各方就改进提出讨论与建议。本文档的分发不受限制。

1. 背景 ​

SPIFFE 系列规范定义了构建一套平台无关的工作负载身份框架所需的文档与接口,该框架能够在不同域的系统之间架起桥梁,而无需实现身份转换或凭据交换逻辑。这些规范定义了“信任域(trust domain)”,它充当一个身份命名空间。

SPIFFE 在本质上是去中心化的。每个信任域都以自身的名义、在自身的权威之下运作,并在管理上与驻留在其他信任域中的系统相隔离。尽管信任域界定了各自的管理域和/或安全域,但 SPIFFE 的一个核心用例正是在需要时实现跨越这些边界的通信。因此,有必要定义一种机制,使某个实体能够被引荐给一个外部信任域,从而使其能够认证由“其他”SPIFFE 权威颁发的凭据,并使一个信任域中的工作负载能够安全地认证外部信任域中的工作负载。

SPIFFE 证书包(bundle) 是一种资源,其中包含用于认证来自某个特定信任域的凭据所需的公钥材料。本文档引入了一项规范,借此可以安全地获取 SPIFFE 证书包,以认证由外部权威所颁发的身份。文中包含了如何提供 SPIFFE 证书包、如何检索 SPIFFE 证书包,以及如何认证提供这些证书包的端点等信息。

2. 引言 ​

SPIFFE 联邦(federation)使得跨信任域认证身份凭据(SVID)成为可能。具体而言,它是指获取用于认证由其他信任域所颁发 SVID 所必需的 SPIFFE 证书包,并将上述证书包提供给执行认证的工作负载这一行为。

要校验来自某信任域的 SVID,就必须持有该信任域的证书包。因此,实现 SPIFFE 联邦必然要求在信任域之间交换 SPIFFE 证书包。这种交换应定期进行,以允许信任域证书包的内容随时间发生变化。

为此,SPIFFE 联邦定义了一个“证书包端点(bundle endpoint)”,即一个为某特定信任域提供 SPIFFE 证书包的 URL。此外还定义了一组“端点配置档(endpoint profile)”,用于规定证书包端点服务器与客户端之间所使用的协议及认证语义。最后,本文档进一步规定了证书包端点客户端与服务器的行为,以及对联邦关系及由此产生的证书包数据的管理。

3. 目标用例 ​

归根结底,SPIFFE 联邦使工作负载能够认证驻留在其他信任域中的对端。这一功能是支撑众多用例所必需的,不过我们希望聚焦于三个核心用例。

SPIFFE 信任域经常被用于在同一公司或组织内部划分具有不同信任级别的环境。例如在预发布(staging)与生产(production)环境之间,或在 PCI 与非 PCI 环境之间。在这些情形下,各个域中所使用的 SPIFFE 部署共享同一个管理主体,并且很可能由同一套实现支撑。这一区别很重要,因为它意味着这些各自独立的部署有能力就某些事项(例如命名方案)达成一致,并且每个部署的安全态势都能被其他部署所知晓和充分理解。

其次,SPIFFE 联邦也用于分属不同公司或组织的信任域之间。这种情形与第一种类似,因为我们同样是在多个 SPIFFE 部署之间建立联邦,但由于实现和管理上可能存在差异,协作通常仅限于本文所述 SPIFFE 联邦协议中交换的数据。

最后,SPIFFE 联邦还能为那些尚未部署成熟 SPIFFE 控制平面的消费方开启一系列用例。例如,某个托管产品可能希望使用客户的 SPIFFE 身份来认证客户,而无需在内部实现或部署 SPIFFE。这可以通过允许工作负载直接获取客户的信任域证书包来实现,从而认证其调用方,免去投入完整 SPIFFE 部署的必要。

4. SPIFFE 证书包端点(Bundle Endpoint) ​

SPIFFE 证书包端点是一种资源(由一个 URL 表示),它为某个信任域提供一份 SPIFFE 证书包的副本。SPIFFE 控制平面既可以暴露也可以消费这些端点,以便在彼此之间传输证书包,从而实现联邦。

SPIFFE 证书包端点的语义类似于 OpenID Connect 规范中定义的 jwks_uri 机制,因为证书包包含一个信任域所使用的一个或多个公开密码学密钥(用于为信任域内的身份签发证明)。证书包端点是一个 HTTPS URL,它对 HTTP GET 请求以一份 SPIFFE 证书包作出响应。关于 SPIFFE 证书包及其编码方式的更多信息,请参阅 SPIFFE 信任域与证书包 规范。

4.1. 添加与移除密钥 ​

信任域的运维方可以(MAY)根据需要引入或移除用于在信任域内签发 SVID 的密钥(例如作为内部密钥轮换流程的一部分)。在添加新密钥时,应当(SHOULD)提前足够长的时间在证书包端点上发布包含这些密钥的更新后信任证书包,以便外部信任域有机会检索并在其内部分发新的证书包内容;推荐的提前时间为证书包 spiffe_refresh_hint 值的 3 至 5 倍。至少,新密钥必须(MUST)在被用于签发 SVID 之前就已发布到证书包端点上。

已弃用的密钥应当(SHOULD)在信任域中不再存在任何由这些密钥签发的、处于有效期内的活动 SVID 之后,再从信任证书包中移除。在密钥添加到证书包及从中移除的过程中若不遵循这些建议,可能导致短暂的跨域认证失败。

对于仅供内部使用的、用于签发 SVID 的密钥,更新信任证书包的相关要求并不适用。

客户端应当(SHOULD)定期轮询该端点以获取更新,因为其内容预期会随时间发生变化——密钥的有效期以周甚至天为量级是很常见的。客户端应当(SHOULD)以等于证书包 spiffe_refresh_hint 值(单位为秒)的频率进行轮询。如果未设置该值,则应采用一个合理的、较低的默认值——推荐为五分钟。

4.2. 管理已获取的证书包 ​

证书包端点的客户端应当(SHOULD)在每次检索到最新的 SPIFFE 证书包时将其存储下来。在比较两份信任证书包的新旧程度或先后次序时,应当(SHOULD)使用信任证书包的序列号(sequence number)字段。如果信任证书包省略了序列号,运维方应当(SHOULD)将最近检索到的证书包视为最新的。

运维方可以(MAY)在任何时候于本地更新某外部信任域的 SPIFFE 证书包。在这种情况下,该证书包在本地更新后的版本会被视为最新版本,直至被后续的刷新所替换。

来自不同信任域的证书包内容禁止(MUST NOT)合并进单一的、更大的证书包中。这样做会使得在持有该统一证书包的校验方眼中,某个信任域得以伪造属于另一个信任域的身份。因此,务必确保来自外部信任域的证书包彼此保持独立,并清晰地反映它们所属的信任域名称。更多信息请参阅安全性考量一节。

4.3. 端点地址稳定性 ​

一旦外部信任域开始依赖某个特定的端点 URL,再要把该端点的所有客户端迁移到一个替代端点 URL,便是一项精细且极易出错的过程。因此,最稳妥的做法是优先采用稳定的端点 URL。

5. 提供与消费 SPIFFE 证书包端点 ​

本规范为 SPIFFE 证书包端点服务器定义了两种受支持的配置档,二者均基于 HTTPS。其一依赖使用 Web PKI 来认证端点,另一种则借助 SPIFFE 认证。SPIFFE 证书包端点客户端必须(MUST)同时支持这两种配置档,而 SPIFFE 证书包端点服务器则必须(MUST)至少支持其中之一。

支持基于 TLS 的配置档(例如 https_web 或 https_spiffe)的证书包端点服务器,除非所用配置档另有说明,否则必须(MUST)遵守 Mozilla 中间兼容性(intermediate compatibility) 要求。

5.1. 端点参数 ​

在从 SPIFFE 证书包端点检索证书包之前,客户端必须(MUST)已配置以下三项参数:(1)SPIFFE 证书包端点的 URL,(2)端点配置档类型,以及(3)与该证书包端点相关联的信任域名称。前两项参数指明了证书包端点的位置以及如何对其进行认证。由于信任证书包本身不包含信任域名称,客户端使用第三项参数将下载到的证书包与某个特定的信任域名称相关联。特定的端点配置档(例如下文所述的 https_spiffe)可以(MAY)定义额外的强制配置参数。

Bundle Endpoint URL:        "https://example.com/production/bundle.json"
Bundle Endpoint Profile:    "https_web"
Trust Domain:            "prod.example.com"

图 1:针对信任域 prod.example.com 的 SPIFFE 证书包端点配置示例。管理员通过证书包端点配置来配置 SPIFFE 控制平面,以检索外部的信任证书包。

当控制平面在内部向工作负载分发信任证书包时,必须(MUST)传达信任域名称与信任证书包之间的关联关系。关于这些参数敏感性的更多信息,请参阅安全性考量一节。

SPIFFE 证书包分发
图 2:在检索到外部的 SPIFFE 信任证书包后,控制平面会将信任域名称与对应的证书包一并分发给内部工作负载。工作负载利用这项配置来校验外部信任域中的身份。有关信任证书包内容的细节,请参阅 SPIFFE 信任域与证书包,尤其是其中的 SPIFFE 证书包格式 与 SPIFFE 证书包示例 小节。

本节中的各项要求适用于所有 SPIFFE 证书包端点服务器与客户端。各个 SPIFFE 证书包端点配置档可以(MAY)追加进一步的要求。

5.2. 端点配置档(Profile) ​

端点配置档(endpoint profile)描述了在提供或消费某证书包端点时应当使用的传输协议与认证方法。

以下各小节描述了受支持的证书包端点配置档。

5.2.1. Web PKI(https_web) ​

https_web 配置档借助公开受信的证书颁发机构,为配置 SPIFFE 联邦提供了一条低摩擦的路径。它的行为与大多数人在浏览器中访问网页时所熟悉的“https”URL 完全一致。在该配置档中,证书包端点服务器使用由公共 CA 颁发的证书,免去了额外客户端配置的需要;使用 https_web 配置档类型的端点,是通过现代操作系统中普遍安装的那些公共 CA 证书来进行认证的。

关于使用公共证书颁发机构的更多信息,请参阅安全性考量一节。

5.2.1.1. 端点 URL 要求 ​

使用 https_web 的证书包端点 URL 必须(MUST)将 scheme 设为 https,并且禁止(MUST NOT)在 authority 组成部分中包含 userinfo。URL 的其他组成部分(如 RFC 3986 第 3 节 所定义)不受本规范约束。

例如,URL https://host.example.com/trust_domain 对于 https_web 配置档类型而言是一个有效的 SPIFFE 证书包端点 URL。

5.2.1.2. 端点参数 ​

https_web 配置档禁止(MUST NOT)在每种配置档都必需的参数(即信任域名称、配置档类型和端点 URL)之外,再要求任何额外参数才能运作。

5.2.1.3. 提供证书包端点(服务端) ​

支持 https_web 传输类型的 SPIFFE 证书包端点服务器使用标准的、受 TLS 保护的 HTTP(即 HTTPS)。所用的服务器证书应当(SHOULD)由某个公共证书颁发机构(按 CA/Browser 论坛的成员名单所定义)颁发,并且必须(MUST)将端点的 DNS 名称或 IP 地址作为 X.509 主题备用名称(Subject Alternative Name,或 Common Name)包含在内。

出于互操作性方面的考虑,服务器禁止(MUST NOT)要求进行客户端认证才能访问证书包端点;这既包括传输层(例如客户端证书)认证方案,也包括 HTTP 层(例如 Authentication 头)认证方案。

在收到针对正确路径的 HTTP GET 请求后,证书包端点服务器必须(MUST)以其可提供的最新版本 SPIFFE 证书包作出响应。响应必须(MUST)采用 UTF-8 编码,并且应当(SHOULD)将响应的 Content-Type 头设为 application/json。提供 SPIFFE 证书包所用的路径不受本规范约束。

如果提供所请求证书包的权威已发生迁移,证书包端点服务器可以(MAY)以 HTTP 重定向(如 RFC 7231 第 6.4 节 所定义)作出响应。重定向的目标 URL 也必须(MUST)是本配置档所定义的有效证书包端点 URL。服务器应当(SHOULD)使用临时重定向;对重定向的支持意在满足运维方面的考量(例如通过 CDN 提供证书包),而非作为永久迁移证书包端点 URL 的手段。更多信息请参阅安全性考量。

5.2.1.4. 消费证书包端点(客户端) ​

SPIFFE 证书包端点客户端在与 https_web 证书包端点交互时使用标准的、受 TLS 保护的 HTTP(即 HTTPS)。在连接该端点时,必须(MUST)按照 RFC 6125 对服务器证书进行校验。概括该文档而言,服务器证书必须(MUST)由一个在本地受信的证书颁发机构颁发,并且必须(MUST)包含一个与所配置端点 URL 的 host 组成部分相匹配的 X.509 主题备用名称(或 Common Name)。

在与证书包端点建立 TLS 连接并对所出示的服务器证书完成认证之后,客户端针对端点 URL 所指定的路径发起 HTTP GET。响应体是一份 SPIFFE 证书包。客户端必须(MUST)在检索信任证书包之前就知晓该端点 URL 所代表的信任域名称,理想情况下通过显式配置获知;更多信息请参阅安全性考量一节。

证书包端点服务器可以(MAY)以 HTTP 重定向(如 RFC 7231 第 6.4 节 所定义)作出响应。如果目标 URL 满足有效证书包端点 URL 的所有要求,证书包端点客户端应当(SHOULD)跟随该重定向。在连接新 URL 时,必须(MUST)应用与连接原 URL 时相同的 TLS 考量。证书包端点客户端应当(SHOULD)在每次刷新证书包时都使用所配置的端点 URL,并且不应(SHOULD NOT)将该位置永久存储起来供未来获取之用。更多信息请参阅安全性考量。

5.2.2. SPIFFE 认证(https_spiffe) ​

https_spiffe 配置档使用由某个 SPIFFE 信任域颁发的 X509-SVID(而非由公共证书颁发机构颁发的证书)。该配置档使证书包端点得以避免将网络定位符用作服务器身份的一种形式,并且还通过标准的 SPIFFE 机制支持自动化的根 CA 轮换与吊销。

除了所有配置档都必需的端点参数之外,https_spiffe 配置档还要求提供额外的端点客户端参数,详见下文的“端点参数”。

5.2.2.1. 端点 URL 要求 ​

使用 https_spiffe 的证书包端点 URL 必须(MUST)将 scheme 设为 https,并且禁止(MUST NOT)在 authority 组成部分中包含 userinfo。URL 的其他组成部分(如 RFC 3986 第 3 节 所定义)不受本规范约束。

例如,URL https://host.example.com/trust_domain 对于 https_spiffe 配置档类型而言是一个有效的 SPIFFE 证书包端点 URL。

5.2.2.2. 端点参数 ​

使用 https_spiffe 配置档的证书包端点客户端必须(MUST)配置证书包端点服务器的 SPIFFE ID,以及一种用于获取该端点服务器所在信任域之信任证书包的安全方法。自服务(self-serving)证书包端点是指其证书包端点服务器的 SPIFFE ID 与所获取证书包所处的信任域为同一信任域的端点。所配置的证书包端点可能是自服务的,也可能不是。

  • 如果端点是自服务的,则客户端需要配置一份单一的、最新的证书包,以便引导(bootstrap)联邦关系。客户端必须(MUST)支持以 SPIFFE 证书包格式 指定该证书包,并且可以(MAY)支持其他格式(例如 PEM),只要它们提供了校验该连接所必需的一个或多个根证书。客户端在首次检索时依赖这份已配置的证书包,但随后会存储所检索到的证书包,以校验后续的连接。更多信息请参阅下文的消费证书包端点(客户端)。
  • 如果端点不是自服务的,则客户端必须(MUST)针对该端点服务器的信任域进行单独配置。端点服务器的信任域及其证书包可以通过以下任一方式配置:
    • 为该信任域提供端点参数,从而将客户端配置为按本文档所述的端点配置档来获取证书包。请注意,客户端可以(MAY)使用任何可用的配置档,并不局限于 https_spiffe。
    • 一种用于获取或以其他方式配置证书包的流程(可以是自动的,也可以是静态的),该流程不在本文档定义之列,也超出本文档范围。关于以安全方式实施这一方法的指导,请参阅安全性考量一节。
Bundle Endpoint URL:        "https://example.com/global/bundle.json"
Bundle Endpoint Profile:    "https_spiffe"
Trust Domain:            "example.com"
Endpoint SPIFFE ID:        "spiffe://example.com/spiffe-bundle-server"
Endpoint Trust Bundle:        {example.com bundle contents omitted}

图 3:使用 SPIFFE 认证、针对信任域 example.com 的 SPIFFE 证书包端点配置示例。在此示例中,证书包端点是自服务的,配置中包含了证书包端点的 SPIFFE ID,以及该 SPIFFE ID 所属信任域 example.com 的信任证书包。这份初始证书包用于认证与证书包端点的首次连接并校验其 SVID。与该证书包端点的后续连接则使用最近一次获取到的副本进行认证。

Bundle Endpoint URL:        "https://example.com/production/bundle.json"
Bundle Endpoint Profile:    "https_spiffe"
Trust Domain:            "prod.example.com"
Endpoint SPIFFE ID:        "spiffe://example.com/spiffe-bundle-server"

图 4:使用 SPIFFE 认证、针对信任域 prod.example.com 的 SPIFFE 证书包端点配置示例。在此示例中,证书包端点不是自服务的:prod.example.com 的信任证书包由 SPIFFE ID 为 spiffe://example.com/spiffe-bundle-server 的 example.com 提供。用于认证 example.com 所需的信任证书包,已通过上文的联邦示例事先获取。

5.2.2.3. 提供证书包端点(服务端) ​

支持 https_spiffe 传输类型的 SPIFFE 证书包端点服务器使用标准的、受 TLS 保护的 HTTP(即 HTTPS)。服务器证书必须(MUST)是一份有效的 X509-SVID。

出于互操作性方面的考虑,服务器禁止(MUST NOT)要求进行客户端认证才能访问证书包端点;这既包括传输层(例如客户端证书)认证方案,也包括 HTTP 层(例如 Authentication 头)认证方案。

在收到针对正确路径的 HTTP GET 请求后,证书包端点服务器必须(MUST)以其可提供的最新版本 SPIFFE 证书包作出响应。确切的路径值可由运维方选定,并作为证书包端点 URL 的一部分出现。证书包端点服务器必须(MUST)以 UTF-8 编码传输证书包,并且应当(SHOULD)将响应的 Content-Type 头设为 application/json。

如果提供所请求证书包的权威已发生迁移,证书包端点服务器可以(MAY)以 HTTP 重定向(如 RFC 7231 第 6.4 节 所定义)作出响应。重定向的目标 URL 也必须(MUST)是本配置档所定义的有效证书包端点 URL,并且新目标所出示的服务器证书必须是一份有效的 X509-SVID,且其 SPIFFE ID 与原端点相同。服务器应当(SHOULD)使用临时重定向;对重定向的支持意在满足运维方面的考量(例如通过 CDN 提供证书包),而非作为永久迁移证书包端点 URL 的手段。更多信息请参阅安全性考量。

5.2.2.4. 消费证书包端点(客户端) ​

SPIFFE 证书包端点客户端在与 https_spiffe 证书包端点交互时使用标准的、受 TLS 保护的 HTTP(即 HTTPS)。在连接该端点时,必须(MUST)校验服务器证书是一份有效的 X509-SVID,且其对应于作为证书包端点参数所提供的证书包端点 SPIFFE ID。关于校验 X509-SVID 的信息,请参阅 SPIFFE X509-SVID 规范。

自服务证书包端点是指其证书包端点服务器的 SPIFFE ID 与所获取证书包所处的信任域为同一信任域的端点。在首次连接自服务证书包端点时,客户端使用运维方提供的(通过证书包端点参数提供的)SPIFFE 证书包来校验服务器证书。任何后续连接都必须(MUST)使用可获得的最新证书包来进行校验。这使得外部信任域能够在不中断联邦关系的情况下轮换密钥。

非自服务证书包端点是指其证书包端点服务器的 SPIFFE ID 与所获取证书包所处的信任域不属于同一信任域的端点。在连接非自服务端点时,客户端使用与该端点 SPIFFE ID 所处信任域相对应的、可获得的最新 SPIFFE 证书包,该证书包可能是直接配置的,也可能是通过另一段联邦关系获取的。

在与证书包端点建立 TLS 连接并对所出示的服务器证书完成认证之后,客户端针对端点 URL 所指定的路径发起 HTTP GET。响应体是一份 SPIFFE 证书包。客户端必须(MUST)在检索信任证书包之前就知晓该端点 URL 所代表的信任域名称,理想情况下通过显式配置获知;更多信息请参阅安全性考量一节。

证书包端点服务器可以(MAY)以 HTTP 重定向(如 RFC 7231 第 6.4 节 所定义)作出响应。如果目标 URL 满足有效证书包端点 URL 的所有要求,证书包端点客户端应当(SHOULD)跟随该重定向。在连接新 URL 时,必须(MUST)应用与连接原 URL 时相同的 TLS 考量。特别地,它必须(MUST)出示一份有效的 X509-SVID,且其 SPIFFE ID 与最初配置的相同。证书包端点客户端应当(SHOULD)在每次刷新证书包时都使用所配置的端点 URL,并且不应(SHOULD NOT)将该位置永久存储起来供未来获取之用。更多信息请参阅安全性考量。

6. 关系生命周期 ​

本节描述联邦“关系”的生命周期,包括首次连接的建立、持续的维护以及终止。

联邦关系是单向的。换言之,Alice 可以与 Bob 建立关系而反之不然。在这种情况下,Alice 将能够校验由 Bob 颁发的身份,但 Bob 无从得知如何校验由 Alice 颁发的身份。

要实现双向认证(mutual authentication),需要建立两段关系——每个方向各一段。

6.1. 建立关系 ​

正如“端点参数”一节所述,所有证书包端点客户端至少需要三条信息才能被正确配置:外部信任域名称、其证书包端点 URL,以及端点配置档。

证书包端点 URL 提供了可找到外部信任域证书包的地址,而配置档则告诉客户端在调用该端点时应使用哪种协议。某个配置档可能要求提供额外的、特定于该配置档的参数。关于究竟如何连接并认证证书包端点的更多信息,请参阅相关的“端点配置档”小节。

一旦连接成功建立且已收到一份证书包副本,该证书包便会连同其所属信任域的名称一并被存储起来。此时,证书包的内容(例如 CA 证书、JWT 签名密钥等)便可以被分发出去,用于校验源自该外部信任域的 SVID。

这种分发发生的确切性质与机制属于实现细节,超出本文档范围。关于具备 SPIFFE 感知能力的工作负载如何接收证书包更新的更多信息,请参阅 SPIFFE 工作负载 API 规范。

6.2. 维护关系 ​

SPIFFE 证书包端点客户端应当(SHOULD)定期轮询证书包端点以获取更新。当检测到更新时,代表该端点外部信任域的已存储证书包会被更新为与之一致。随后,更新后的内容会被分发出去,以便校验方根据需要添加新密钥并剔除已吊销的密钥。同样,将此更新分发给校验方的确切方法超出本文档范围。

如果轮询证书包端点的尝试失败,证书包端点客户端应当(SHOULD)在下一个轮询间隔时重试,而不应立即或激进地重试,因为那样可能压垮证书包端点服务器。正如添加与移除密钥一节所讨论的,新密钥应在其被使用之前足够提前地发布,以使漏掉一两次轮询不会导致跨域认证失败。

6.3. 终止关系 ​

终止一段联邦关系,就如同删除外部信任域证书包的本地副本并停止轮询其证书包端点那样简单。当然,这一变更也必须传播给校验方,使其剔除该外部信任域的证书包,并停止对其所出示 SVID 的成功校验。

如果该关系日后需要重新建立,则重新开始整个生命周期。

6.4. 生命周期图 ​

一段 SPIFFE 联邦关系的生命周期

7. 安全性考量 ​

本节包含与本规范相关的安全信息与观察。实现者与用户都必须熟悉这些信息,这一点很重要。

7.1. 端点参数的分发 ​

一段联邦关系的配置参数——包括信任域名称、端点 URL 和配置档——本身对篡改极为敏感。一段联邦关系的配置若遭破坏,可能削弱乃至彻底瓦解一个未受损的 SPIFFE 实现所隐含的安全保证。

举几个例子:

  • 篡改信任域名称,会使控制着相应证书包端点的一方能够冒充任意信任域
  • 篡改端点 URL,尤其是与 https_web 配置档配合使用时,会使攻击者能够签发欺诈性的密钥,并冒充相应信任域中的任何身份
  • 篡改端点配置档,会改变联邦的安全保证,例如将 https_spiffe 替换为 https_web。如果你的威胁模型将 Web PKI 遭破坏纳入其中(另请参阅下文的网络流量拦截一节),那么这可被视为安全态势的一次重大降级

因此,控制平面管理员必须谨慎地以安全方式获取这些参数并以安全方式输入它们。证书包端点配置可以通过多种方法获取,包括但不限于电子邮件、受 HTTPS 保护的网站、公司内部维基等。无论初次分发端点配置所采用的具体方法是什么,该分发方法都需要能够抵御传输途中的篡改、静态存储时的未授权修改,以及恶意冒充。例如,电子邮件通常既无法抵御篡改,也无法抵御冒充(即“伪造”邮件)。

7.2. 显式定义端点参数 ​

每段 SPIFFE 联邦关系至少配置有以下参数:

  • 信任域名称
  • 端点 URL
  • 端点配置档

这三项参数被显式地配置,这一点很重要,因为它们的值无法从彼此之间安全地推断出来。

例如,人们可能会想从端点 URL 的 host 部分推断出 SPIFFE 信任域名称。这样做很危险,因为它可能使任何能够让某个文件从某个特定 DNS 名称下被提供出去的人,得以为同名的 SPIFFE 信任域主张信任根。

设想有一家名为 MyPage(mypage.example.com)的网页托管公司,它允许某位客户 Alice 在诸如 https://mypage.example.com/alice/<filename> 这样的 URL 上提供网页内容;进一步设想 MyPage 运营着一个由 SPIFFE 联邦保护的 API,其 SPIFFE 信任域名称为 mypage.example.com。再设想 Alice 与同为 MyPage 客户的 Bob 建立了 SPIFFE 联邦,并且 Alice 选择从 https://mypage.example.com/alice/spiffe-bundle 提供她的信任证书包。

一幅图示,展示 Alice、Bob 与 MyPage 之间的关系
图 5:一幅图示,展示 Alice、Bob 与 MyPage 之间的关系。

如果 Bob 的控制平面隐式地从 URL 获取信任域名称,那么这将使 Alice 能够冒充信任域 mypage.example.com!同样值得强调的是,SPIFFE 信任域名称未必是一个已注册的 DNS 名称,这往往使得上述假设从一开始就是错误的。在此示例中,Alice 的信任域名称仅仅是 alice。

端点配置档同样无法从 URL 安全地推断出来。https_web 与 https_spiffe 都使用具有相同要求的普通 HTTPS URL,没有任何安全的方法能将二者区分开来。基于与上文所述类似的原因,尝试 https_web 并回退到 https_spiffe(或反之)也是不够充分的:从安全角度看,能够在某个特定 HTTPS 端点上用 Web PKI 托管一个文件,并不等同于能够用一份有效的 SPIFFE SVID 来托管它。

7.3. 保持 <Trust Domain, Bundle> 绑定 ​

在认证一份 SVID 时,校验方必须只使用该 SPIFFE ID 所处信任域的证书包。如果我们只是简单地将所有证书包汇集在一起,并只要一份 SVID 能够针对某份证书包通过校验就予以接受,那么各信任域就能轻易地彼此冒充身份。换一种说法就是,证书包被限定在某个特定的信任域范围内。

由于证书包在信任域方面并非自描述的,并且还是自签发的,因此至关重要的是:作为 SPIFFE 联邦关系一部分而配置的信任域名称与证书包端点之间的绑定,在证书包被存储和分发时必须被转化为信任域名称与证书包之间的绑定。这一要求不同于传统的 Web PKI——在传统 Web PKI 中,使用单一的根证书存储来校验所有证书,而无论被校验的证书实际上是由哪套 CA 系统颁发的。

7.4. 证书包端点服务器的可信度 ​

证书包端点服务器的可信度与完整性,对于确保该证书包所代表信任域的安全至关重要。这不仅涉及证书包端点服务器本身,还涉及其运行所在的平台,以及任何对它或其平台拥有管理控制权的实体。

尽管这一事实可能看似不言而喻,但在某些情形下它或许并不那么显而易见。例如,在一个非自服务证书包端点的情形中,信任域 A 为信任域 B 提供证书包,此时信任域 B 便隐式地信任信任域 A 及其管理员会提供正确的证书包内容。类似地,如果从诸如 AWS S3 之类的托管平台提供证书包,那么该证书包所代表信任域的运维方便隐式地信任 AWS 会提供正确的证书包内容。

在选择提供 SPIFFE 证书包的位置时,务必考虑相关各方的可信度。

7.5. 证书包端点的真实性 ​

确保证书包端点的真实性至关重要,这一点怎么强调都不为过。本节探讨在确保证书包端点真实性时应当作出的若干考量。

7.5.1. 证书包端点 URL 重定向 ​

URL 重定向有两种类型:临时的和永久的。本规范建议(通过 SHOULD 指令)服务器只发送临时重定向,并且客户端将所有重定向都视为临时的——即便服务器将其标记为永久的也是如此。

永久重定向如果被客户端遵从,便相当于对证书包端点 URL 这一配置参数进行了一次带内(in-band)、自动化的改写。这会导致两个相关的安全隐患。

其一,信任域运维方可能会想把永久重定向用作迁移证书包端点 URL 的一种方法。然而,没有可靠的手段能确保所有客户端都已处理该重定向,也没有手段能确保它们会永久遵从它(例如在重启、升级、重新部署等之后)。如果一个证书包端点 URL 转移了所有权,而客户端继续从原始端点 URL 获取证书包,那么这些客户端可能会检索到一份由意料之外的所有者所控制的证书包。在使用基于 Web PKI 的方案(如 https_web)时,这一点尤其令人担忧,因为新的域名所有者理应有权获得针对该域的公开受信证书。因此,最稳妥的做法是从长期稳定的角度出发来选择证书包端点 URL。如果确实需要进行 URL 迁移,最好使用当初获取证书包端点配置时所用的带外(out-of-band)方法来处理,并设置一个较长且广为通告的迁移窗口。

其二,永久重定向有可能被滥用,成为将一次短暂的入侵升级为更持久入侵的一种机制。由于重定向是自动的,它很容易被证书包端点客户端的运维方所忽视。

网页托管方常常出于运维目的使用临时重定向:例如,让一个全局稳定的 URL 由一个位于接收方附近的节点来提供。禁止在 SPIFFE 联邦中使用重定向,会从运维方的工具箱中移除一件有用的工具。然而,临时重定向确实存在安全性考量。并非所有网页托管方在安全态势上都是等同的,这意味着一旦发生重定向,运维方可能得不到他们所期望的安全保证。本规范中“客户端‘应当(SHOULD)’跟随重定向”这一建议,应被解读为一项推荐的默认做法:是在运维价值与安全价值之间取得的一种平衡。那些对其所依赖的联邦证书包端点的安全态势做过一定尽职调查的证书包端点客户端运维方,或许会希望考虑禁用重定向,以免出现意外。

7.5.2. 网络流量拦截 ​

尽管所有 SPIFFE 证书包端点配置档都借助了在很大程度上不受网络流量拦截与操纵风险影响的协议,但需要注意的是,这并不必然意味着获取该协议凭据所用的方案也同样不受影响。如果 SPIFFE 是作为“零信任”解决方案的一部分来部署的,或者运维方的威胁模型出于其他原因将网络遭破坏纳入其中,那么就必须特别关注用于签发证书包端点服务器凭据的机制。

签发服务器凭据的一种常见方法是使用质询—响应(challenge-response)机制,即根据请求方回答一个发往某特定网络地址或 DNS 名称的质询的能力,来授权对凭据的请求。ACME 协议就是这样的一个例子;如果希望使用公共证书颁发机构,则应当考虑补偿性控制措施。尤其值得注意的是证书包端点服务器所处二层网络的安全性。

最后应当指出,ACME 与公共证书颁发机构基础设施历来一直稳定而可靠。本节所述的担忧是一个存在了数十年的老问题;然而,鉴于那些将 SPIFFE 用作降低对网络或 DNS 之信任的手段的运维方可能会对此感到意外,审慎起见有必要着重指出这一行为。

7.5.3. 端点参数 ​

破坏证书包端点的一种方式,是篡改端点客户端所消费的端点参数——无论是在传输途中还是在静态存储时。修改原本真实的端点参数,会导致安全态势的降级,甚至可能使客户端与一个完全不同的端点进行通信。更多信息请参阅端点参数的分发一节。

7.6. 使用 https_spiffe 进行链式信任 ​

在使用 SPIFFE 认证时,信任证书包服务器的真实性是通过使用客户端可经由各种途径获取的信任证书包,来校验所出示的 X509-SVID 而确立的。例如,信任域 A 的证书包可能由信任域 B 中的一个端点提供,而信任域 B 的证书包又可能由信任域 C 中的一个端点提供,依此类推。

以这种方式,所获取的证书包是通过提供方信任域与该证书包所属信任域之间的一系列关系链条而得到信任的。这条关系链条最终会终结于以下情形之一:

  • 通过一段通往某个自服务信任域的联邦关系
  • 通过一段通往某个由 Web PKI 提供的证书包端点的联邦关系
  • 终结于一份长期存续、静态配置的信任证书包
  • 终结于某个超出本文档范围的流程

正如证书包端点服务器的可信度一节所述,务必理解:此方案的安全性取决于链条中的每一个信任域都成功地兑现其安全保证。链条中某个信任域或证书包端点服务器遭破坏,将导致“下一个”信任域随之遭破坏。一个具备网络拦截能力、且足够强大的攻击者,有可能以某种方式将此攻击逐级升级,使得链条中更下游的信任域也遭到破坏。因此,通常不鼓励以这种方式形成很长的链条。如果确有必要,管理员应当花时间分析这些链条,以确保所有参与其中的信任域都满足其所期望的标准。

最后应当指出,这条链条中的“链环”是由一次次单独的 HTTPS 请求操作(针对链条中的各个证书包端点服务器)所构成的,而这些操作很可能发生在不同的时间。SPIFFE 证书包端点客户端应当记录这些 HTTPS 请求操作的日志,管理员则应当注意妥善保存这些日志,以备将来必要时进行取证分析。