Swift 临时 URL

https://blueprints.launchpad.net/ironic/+spec/swift-temp-urls

Ironic 需要一个选项,以便安全地从 Swift 下载镜像,而无需在各处传递 admin auth token。 使用 Swift 临时 URL,conductor 可以创建一个具有完全下载特定镜像权限的过期 URL。 这对于 Ironic Python Agent 非常有用,因为我们不希望将 admin auth token 发送到所有 ramdisk agent,从而打开潜在的安全漏洞,但它们仍然需要一种下载镜像的方式。

问题描述

目前,Ironic 从 Glance 直接下载镜像进行写入。 在当前的 PXE 驱动程序中,没有安全问题,因为镜像下载到 conductor,并且不需要传递 token。 对于 Ironic Python Agent 和 iLO 等其他驱动程序,需要将镜像下载到 ramdisk。 要从 Glance 下载,需要将 auth token 与请求一起发送。 在 Ironic 的情况下,这将是 admin token,这将允许 agent 对其他服务拥有 admin 控制权。 Ironic 中的许多其他服务/驱动程序可能希望能够从 Swift 下载,但以类似的方式限制服务可以访问的内容。

直接从 Swift 下载还有可扩展性优势,而不是使用 Glance 作为中间介。 Swift 集群可以扩展以处理更大的负载,而不会给 Glance 集群带来太多额外的负载。

提议的变更

能够为在 Glance 中注册并存储在 Swift 中的镜像创建一个签名的临时 URL,该 URL 可以在没有其他凭据的情况下下载。

  • 给定 Glance 的 show 命令返回的镜像信息以及先前在 Swift 中设置的临时 URL 密钥,将使用 Swift 客户端库创建一个临时 URL 并返回。 它将使用镜像信息中的 direct_url 属性(如果已设置),或者使用 Ironic 中的一组配置选项来生成 URL。

  • 密钥是使用 HTTP 方法、超时、镜像路径和共享密钥的哈希生成的,该哈希附加到 Swift 对象 URL 的末尾,以及超时时间。 由于它是使用共享密钥对 URL 进行签名,因此无需调用 Swift 或 Glance。 实际的 temp url 创建由 python-swiftclient 处理。 参考:[1]

  • 该方法将支持从 Glance 镜像信息中的 direct_url 或在 Ironic 中设置的一组配置选项构造 URL。

  • 如果未启用 direct_url,deployer 需要设置配置选项来与 Swift 通信(http、https),Swift endpoint URL,路径(包括 API 版本和 tenant ID)以及 Glance 镜像存储的容器。

备选方案

  • 启用将 admin auth token 传递给 agent 或以 agent 能够下载它们的方式托管镜像。

  • Deployer 可以在 URL 本身传递带有用户名和密码的 Swift URL,这比 admin auth token 更不安全,但仍然不安全。

  • 镜像也可以由任何 Web 服务器托管,并将该 URL 传递给 agent。

  • 理想情况下,此代码应位于 keystone-client 或 oslo 中,以便其他项目也可以从临时 URL 中受益。 我们现在在 Ironic 中提出它,因为我们需要尽快使用它,但稍后应将其移动。

数据模型影响

REST API 影响

驱动程序 API 影响

Nova 驱动程序影响

安全影响

  • 此代码需要设置 Swift 临时 URL 密钥。 如果此密钥泄露,它可能会允许恶意行为者允许公开访问他们在 Swift 中可以访问的任何内容。

  • 临时 URL 在过期之前会提供对可能属于私有的镜像的完全公开访问权限。

  • 允许的 HTTP 方法只有 GET 和 HEAD,因此恶意行为者将无法修改镜像本身。

其他最终用户影响

可扩展性影响

此更改应允许更好的可扩展性。 Swift 具有高度可扩展性,并被设计为允许您下载大型镜像。 这将减轻 Glance 集群的负载。 主要瓶颈将是 Swift - 节点网络链接。 如果大量节点同时尝试下载镜像,它们很容易饱和。

性能影响

该代码相对较小且自包含。 它需要 Glance image-show 命令的结果来创建临时 URL,但是该 Glance 调用可能已经需要了(例如,在 agent 驱动程序中)。 Ironic 中的 Glance image-show 调用在这里:https://github.com/openstack/ironic/blob/master/ironic/common/glance_service/base_image_service.py#L176。 临时 URL 通过使用共享私钥对 direct-URL(来自 Glance image-show)或使用建议的配置选项构造的 URL 进行签名来工作,因此除了这个 Glance 命令之外,可以生成临时 URL。 不需要额外的数据库调用。

其他部署者影响

  • Deployer 需要设置 Swift 集群并配置 Glance 以使用它,如果他们想利用临时 URL。

  • 需要在 Glance 集群中启用 direct_url,或者设置一组配置选项来将 Glance 镜像 ID 转换为 Swift URL。 要配置 direct_url:[3]

必需的配置选项

  • swift_temp_url_key:这是共享私钥。 在使用之前需要在 Swift 集群中设置。 要设置临时 URL 密钥:[1]

  • swift_temp_url_duration:Swift 临时 URL 有效的时间。 应设置相对较低的值,以防止允许镜像公开。 5 分钟应该足以启动下载并最大限度地减少 URL 泄露的安全问题。 时长将以秒为单位指定。

如果 Glance 中未启用 direct_url,并且选项没有默认值,则需要

  • swift_endpoint_url:Swift 集群的方案、主机名和可选端口。 例如,“http://example.com:8080”。

  • swift_path:集群和容器的 API 版本和 tenant ID,Glance 镜像存储在其中。 例如,“/v1/TENANT_USER_TENANT_UUID”。

  • swift_backend_container:Glance 存储其镜像的 Swift 容器。

开发人员影响

此更改将允许其他驱动程序开发人员使用临时 URL 或至少将其作为选项提供。

实现

负责人

主要负责人

JoshNang

工作项

  • 解决当前补丁上的评论。

  • 添加 tempest 测试

依赖项

  • 合并 python-swiftclient tempurl 补丁 [2]

  • 将 python-swiftclient 添加到 Ironic 的 requirements.txt

测试

  • 最初,将只进行单元测试

  • 此更改也将作为 Ironic Python Agent 集成测试的一部分进行测试。 很难单独对其进行测试,因为它不提供 Tempest 可以测试的任何外部 API。

文档影响

要实现此功能,需要 Glance 使用 Swift 作为镜像数据存储。 Swift 还需要配置 tempurl 中间件才能使临时 URL 正常工作。 Swift 需要设置 tempurl 密钥才能使用此功能,并且需要在 Ironic 中将其设置为 swift_temp_url_key。 Glance 需要配置为提供 direct_url,或者操作员必须设置以下配置选项

  • swift_endpoint_url

  • swift_path

  • swift_backend_container

实际的签名代码是在 python-swiftclient 中提出的。

详细说明如何使用带有 Swift 集群的临时 URL 以及如何配置 Glance 以使用 direct_url 将对 deployer 有所帮助。 利用此更改的驱动程序应链接到这些要求。

参考资料