vTPM 实时迁移¶
https://blueprints.launchpad.net/nova/+spec/vtpm-live-migration
当 Nova 首次添加 vTPM 支持时,所有非生成操作都在 API 层面被 拒绝。在移动实例时,需要额外的工作来管理 vTPM 状态。这项工作最终完成了调整大小和冷迁移,并且这些操作被 解禁。对实时迁移、撤离、搁置和救援的阻止仍然 存在。
TPM 设备是 Windows Server 2022 和 2025 的某些功能所 必需的,特别是 BitLocker 驱动器加密。它也是运行 Windows 11 的必要条件。无法实时迁移具有 vTPM 的实例是任何在 OpenStack 云中运行 Windows 客体的主要障碍。
Libvirt对vTPM实时迁移的支持现在已经存在(更多细节请参见问题描述),但在能够移除API阻塞之前,Nova需要进行更改。本规范描述了这些更改。
问题描述¶
vTPM 实时迁移有四个方面:共享与非共享 vTPM 状态存储、Libvirt 支持和密钥管理。还有一个相关问题,虽然与实时迁移无关,但可以通过支持实时迁移所需的更改来解决:Nova 无法在计算主机重新启动后启动具有 vTPM 的实例。
vTPM 状态存储¶
vTPM状态存储与实例状态存储不同。后者可以配置为共享,例如在NFS上。前者始终是非共享的。可以通过source XML元素告知Libvirt在哪里存储vTPM状态,而Nova 不支持这一点。Nova部署使用Libvirt默认的vTPM状态路径。在Ubuntu和Red Hat操作系统上,此路径为/var/lib/libvirt/swtpm/<instance UUID>。此路径与实例状态路径不同,并且可以预期永远不在共享存储上。
因此,本规范要求vTPM状态存储不可共享,并声明使用共享vTPM状态存储进行实时迁移未经测试。这将记录在案。
Libvirt 支持¶
虽然找不到 Libvirt 工件明确演示了对非共享 vTPM 状态存储的 vTPM 实时迁移的支持,但从 版本 8.10 开始,支持具有共享 vTPM 存储的 vTPM 实时迁移,并且 此评论 表明,对于非共享存储,vTPM 实时迁移自版本 7.1.0 起就已支持。
因此,本规范要求Libvirt 7.1.0。
密钥管理¶
在创建具有 vTPM 的实例时,Nova 会要求密钥管理器(通常是 Barbican)生成一个密钥。至关重要的是,这是使用用户的令牌完成的,并且创建的密钥由用户拥有,其他人(包括管理员或 Nova 服务用户)都无法读取它。然后 Nova 在 Libvirt 中定义密钥,并在实例 XML 中通过其 UUID 引用该密钥。这告诉 Libvirt 使用该密钥的内容作为对称密钥来加密实例的 vTPM 状态。Nova 在 Libvirt 域成功生成后 取消定义密钥。
为了使 vTPM 实时迁移起作用,需要在目标主机上定义一个具有相同 UUID 和内容的 Libvirt 密钥,以便目标 Libvirt 可以解密 vTPM 状态。目前,Nova 没有办法做到这一点。实时迁移是一项管理员操作,管理员或 Nova 服务用户都无法访问 Barbican 密钥(除非管理员恰好是实例的所有者,但这是一种边缘情况)。由于该密钥被定义为 私有的,并且在域生成后被取消定义,因此也无法在源主机上重新读取该密钥。
计算主机重新启动¶
由于同样的原因(缺乏 Barbican 密钥访问权限以及无法从 Libvirt 中重新读取 Libvirt 密钥),Nova 无法在计算主机重新启动后启动具有 vTPM 的实例。
用例¶
作为云运营商,我希望能够实时迁移具有 vTPM 设备的实例,特别是 Windows 实例。
作为云用户,我希望保持我的实例的 vTPM 内容的私密性。云系统只有在我通过我的用户令牌请求时才能解密它,并且系统应该只在有限的时间内保留解密密钥。我作为用户愿意接受这种隐私要求限制我对实例进行的一些管理员发起的生命周期操作。
作为云运营商,我希望计算主机上的 vTPM 实例在主机重新启动后能够再次启动。
提议的变更¶
由于 vTPM 密钥的安全性(无论是在 Barbican 中还是在 Libvirt 中)都会影响可以对实例执行的操作,因此用户应该能够指定他们需要的安全级别,并且运营商需要指定他们愿意支持的安全级别。还需要应用一个默认级别,如果未明确指定,则应用于实例。
提出了三种可能的安全级别。它们在下表中呈现。
值 |
机制 |
安全影响 |
实例迁移性 |
|---|---|---|---|
|
只有实例所有者才能访问Barbican密钥。这是现有行为。 |
这是最安全的选项,因为即使 Nova 服务用户和计算主机的 root 都无法读取密钥。 |
实例无法移动,并且无法在计算主机崩溃或重新启动时由 Nova 启动。 |
|
Libvirt 密钥是持久的并且可检索的。 |
这是“中等”安全级别。API 级别的管理员和 Nova 服务用户无法访问密钥,但具有足够权限的计算主机上的用户可以访问它。 |
实例可以实时迁移,因为 Nova 可以从源主机的 Libvirt 中读取密钥,并通过 RPC 发送到目标主机。通过线路上的安全性由运营商负责,但假定使用 TLS 或类似的安全措施。由于相同的原因,实例也可以在计算主机崩溃或重新启动时由 Nova 启动。 |
|
Nova 服务用户拥有 Barbican 密钥。 |
这是最不安全但最灵活的选项。 |
实例可以实时迁移,因为 Nova 可以从 Barbican 下载密钥并在目标主机上定义它。由于相同的原因,实例也可以在计算主机崩溃或重新启动时由 Nova 启动。 |
用户可以通过设置新的hw_tpm_secret_security镜像属性来选择实例所需的安全级别。如果未设置此属性,则可以从新的hw:tpm_secret_security风味额外规格中获取默认值。对于不想处理因这种新的额外规格而导致的风味爆炸的运营商,添加了一个新的主机配置选项作为后备。名为[libvirt]default_tpm_secret_security,默认值为user(这是现有行为),没有镜像属性或风味额外规格的实例将在该主机上启动时,将其主机的tpm_secret_security策略持久化到其system_metadata中。
运营商可以使用新的[libvirt]supported_tpm_secret_security配置选项来指定他们支持的安全级别。这是一个每个计算主机的列表选项,可以取前一个表格中安全级别的一个或多个值。其默认值为所有三个级别。这些值作为驱动程序功能特性公开。 hw_tpm_secret_security镜像属性和风味额外规格被转换为所需的特性,以匹配驱动程序功能。
实例在实时迁移期间的行为由其持久化的hw_tpm_secret_security(由用户显式设置,或由Nova从主机配置选项中添加的默认值)定义。对于具有user的实例,无法进行实时迁移。对于具有host的实例,源计算主机从Libvirt读取密钥并通过RPC发送到目标主机。对于具有deployment的实例,目标主机从Barbican下载密钥并在Libvirt中定义它。由于实例的hw_tpm_secret_security值转换为所需的特性,因此可以保证为实时迁移选择的目标主机支持实例所需的任何行为。
备选方案¶
这是本规范的唯一版本,涵盖了基本内容:告知用户现有实例上由运营商设置的vTPM密钥安全级别,允许新实例的用户选择所需的安全级别,以及允许运营商选择愿意支持的安全级别,考虑到更高安全级别施加的限制。
数据模型影响¶
Nova的ImageMetaProps对象已更新,以支持新的hw_tpm_secret_security镜像属性。数据库模式不受影响。
REST API 影响¶
没有新的微版本。风味额外规格验证代码已更新,以允许hw:tpm_secret_security。
安全影响¶
本规范的主要安全影响是host和deployment值对tpm_secret_security的影响。
在 host 的情况下,任何具有足够访问计算主机权限的人都可以读取 vTPM 密钥。虽然这不太好,但用户也选择加入,并且假定计算主机由云运营商保护。
在 deployment 的情况下,Nova 服务用户的妥协会导致所有 vTPM 密钥暴露。同样,这也是用户选择加入的,并且假定 Nova 服务用户是安全的。
通知影响¶
无。
其他最终用户影响¶
无。
性能影响¶
无。
其他部署者影响¶
无。
开发人员影响¶
无。
升级影响¶
需要计算服务版本更新。当nova-compute启动时使用新的服务版本时,它会检查主机上当前的所有实例。在服务版本更新后创建的任何实例都将在其system_metadata中具有hw_tpm_secret_security值,要么由用户显式设置,要么由Nova作为后备默认值隐式添加,如<Proposed change_>_部分所述。任何未设置此值的实例都是预先存在的实例,需要进行升级。它们将被升级到[libvirt]default_tpm_secret_security值的设置。仅仅将其持久化到其system_metadata中是不够的——他们的所有者还需要使用他们的令牌对实例执行操作,以便Nova可以转换Libvirt密钥为非私有并持久化(在host的情况下),或者使用与Nova服务用户拥有的相同内容创建新的Barbican密钥(在deployment的情况下)。运营商别无选择,只能将其传达给他们的用户,此时用户可以选择选择加入新的安全级别,或者通过不触碰他们的实例或直接删除它们来拒绝。
用户确认机制¶
对于现有实例,由于需要用户令牌才能激活host或deployment vTPM密钥安全策略,仅实例上嵌入的镜像属性的存在并不能传达该策略当前是否处于活动状态。
为了跟踪实例的vTPM密钥安全策略是否当前处于活动状态,一个新的标志tpm_secret_security_confirmed将在实例的system_metadata中设置为True或False。
现有实例将获得tpm_secret_security_confirmed = False,并在用户重新启动其实例时切换为True。如果用户从不触碰其实例,它将保持False。
新实例将获得tpm_secret_security_confirmed = True。
tpm_secret_security_confirmed的值将由Nova内部用于确定是否拒绝实时迁移的API请求。如果vTPM密钥安全策略尚未确认,Nova API将拒绝实时迁移请求,在这种情况下保留现有实例的旧行为。
实现¶
负责人¶
- 主要负责人
notartom, melwitt
功能联络人¶
- 功能联络人
melwitt, dansmith
工作项¶
引入
hw_tpm_secret_security、hw:tpm_secret_security、[libvirt]supported_tpm_secret_security和[libvirt]default_tpm_secret_security镜像属性、风味额外规格和配置选项。修改实时迁移前和回滚代码以处理密钥定义和清理。
在实例
system_metadata中引入tpm_secret_security_confirmed标志。更新服务版本。
修改现有的API阻塞,仅在最小服务版本达到更新后的版本后才允许实时迁移
host或deployment实例。添加白盒/集成测试。
更新文档。
依赖项¶
Libvirt版本7.1.0。这可以在代码中动态强制执行。
测试¶
Nova 的功能测试已扩展为使用 Libvirt fixture 测试 Nova 逻辑。这对于无法在真实环境中轻松测试的情况特别有用,例如回滚。
现有的 whitebox-tempest-plugin vTPM 测试 已扩展,以在实际环境中,使用真实的 Libvirt 测试实时迁移。
文档影响¶
Nova的vTPM文档已更新,以删除实时迁移限制,并解释supported_tpm_secret_security和default_tpm_secret_security配置选项的使用,以及所有可能值的影响。明确了vTPM状态存储不可共享以及共享vTPM状态存储实时迁移未经测试的期望。
参考资料¶
空。
历史¶
发布名称 |
描述 |
|---|---|
2025.2 Flamingo |
重新提出 |
2025.1 Epoxy |
引入 |