镜像加密和解密¶
OpenStack 已经具备创建加密卷和临时存储的能力,以确保块数据的机密性。与此不同,目前镜像的处理方式缺乏对机密性的保护,仅提供使用镜像签名来确保完整性的可能性。为了进一步保护用户数据——例如,当用户上传包含私有数据或机密信息的镜像时——镜像数据不应可供未经授权的实体访问。为此,需要在 OpenStack 中引入一种加密的镜像格式。总而言之,需要实现对各种项目(例如 Nova、Glance、Cinder 和 OSC)中镜像加密/解密的支持的若干调整。
问题描述¶
当镜像上传到 Glance 或通过 Nova 从现有服务器(虚拟机)创建时,可能包含敏感信息。已经提供的签名功能仅保护镜像免受篡改。镜像可能存储在多个主机上很长时间。首先,这包括 Glance 自身的镜像存储主机。此外,它可能还涉及计算主机等系统上的缓存。总之,它们暴露于多种潜在场景,涉及不同的主机、不同的访问模式和攻击面。参与这些场景的 OpenStack 组件不会保护镜像数据的机密性。
使用加密存储后端用于卷和计算主机,并结合从/到加密镜像的直接数据传输,可以实现无需在主机文件系统上暴露镜像数据的流程。将加密密钥存储在专用的密钥管理主机上,也能确保密钥的隔离和访问控制。通过这样一套针对安全环境的配置建议,我们能够奠定一个良好的基础。未来的增强功能可以基于此进行构建,并将提供的安全增强扩展到更广泛的变体。
因此,我们建议引入一种加密的镜像格式。
用例¶
用户想要上传包含敏感信息的镜像。为了确保镜像的完整性,可以生成签名并用于验证。此外,用户还希望通过加密来保护镜像数据的机密性。用户在密钥管理器(例如 Barbican)中生成或上传密钥,并在上传时使用 OpenStack 客户端 (osc) 在本地使用该密钥对镜像进行加密。因此,存储在 Glance 主机上的镜像将被加密。
用户想要从具有临时存储的现有服务器创建镜像。该服务器可能包含敏感的用户数据。相应的计算主机然后基于临时存储磁盘的数据生成镜像。为了保护镜像中的数据机密性,用户希望 Nova 也使用来自密钥管理器的密钥(通过其 ID 指定)来加密镜像。因此,存储在 Glance 主机上的镜像将被加密。
用户想要从现有的卷创建镜像。该卷可能包含敏感的用户数据。相应的卷主机然后基于卷的数据生成镜像。为了保护镜像中的数据机密性,用户希望 Cinder 也使用来自密钥管理器的密钥(通过其 ID 指定)来加密镜像。因此,存储在 Glance 主机上的镜像将被加密。
用户想要基于上述任何用例创建的加密镜像创建新的服务器或卷。相应的计算或卷主机必须能够使用存储在密钥管理器中的对称密钥来解密镜像,并将其转换为请求的资源(服务器磁盘或卷)。为此,用户需要通过其项目角色分配来访问密钥管理器中的密钥。
提议的变更¶
对于 Glance,我们建议添加一个新的 container_format,名为 ‘encrypted’(加密的)。此外,我们建议以下附加元数据属性由这种格式的镜像携带
‘os_glance_encrypt_format’ - 使用的主要机制,例如 ‘GPG’
‘os_glance_encrypt_type’ - 加密类型,例如 ‘symmetric’(对称的)
‘os_glance_encrypt_cipher’ - 密码算法,例如 ‘AES256’
‘os_glance_encrypt_key_id’ - 密钥管理器的密钥引用
‘os_glance_decrypt_container_format’ - payload 解密后的格式
‘os_glance_decrypt_size’ - payload 解密后的尺寸
为了将加密的镜像上传到 Glance,我们希望在 OpenStack 客户端中添加支持,使用密钥 ID 加密镜像,该密钥 ID 引用密钥管理器(例如 Barbican)中的对称密钥。这还涉及新的 CLI 参数来指定密钥 ID 和加密方法,并且此实现应使用由所有涉及的 OpenStack 组件共享的全局库提供的集中式加密实现,以消除对各个加密机制实现的需求。
换句话说:用户或 openstack 服务(例如 cinder)必须在上传之前加密镜像。在将加密的镜像上传到 glance 时,必须指定上述元数据属性并将 container format 设置为 ‘encrypted’。
我们建议使用 GnuPG 提供的对称加密实现作为此草案支持的基本机制。它是一种成熟的 PGP 实现,并支持可流式传输的加密/解密过程。
我们要求加密/解密机制具有可流式传输性,原因有两个
将整个镜像加载到计算主机或用户系统的内存中是不可接受的。
我们建议直接解密流式传输到目标存储(例如加密卷),以防止创建临时未加密的文件。
Cinder 的当前实现中已经存在一种创建加密镜像的情况。这就是当直接从加密卷创建镜像时。由于加密的块数据只是被复制到镜像中,因此加密(通常是 LUKS)会自动继承——密钥也是如此,它只是在 Barbican 中被克隆。作为本规范的一部分,我们不会更改此行为。我们的更改仅适用于用户主动打算使用新的镜像加密扩展从任何卷创建加密镜像时。
密钥管理与加密卷或临时存储的处理方式不同。原因是镜像的加密和解密绝不在 Glance 中发生,而是在所有其他消耗镜像的服务中发生。因此,为新创建的加密镜像创建密钥的服务可能与随后必须删除密钥的服务不同(在大多数情况下是 Glance)。删除未由同一实体创建的密钥是坏行为。为了避免这种情况,我们选择让用户创建和删除密钥。为了避免意外删除用于加密镜像的密钥,我们将让 Glance 在上传相应的加密镜像时注册为该密钥(Barbican 中的 secret [1])的消费者,并在 Glance 中删除镜像时取消注册。
备选方案¶
我们可以为每种数据格式和密码算法组合在 Glance 中引入单独的 container 类型,而不是使用带有元数据的单个 container 类型。此决定会影响 nova 和 cinder 中的实现。
关于镜像加密,我们还探讨了使用更复杂和动态的方法,例如 PKCS#7 (CMS),但最终未能找到一个免费的开源实现(例如 OpenSSL),该实现支持可流式传输的 CMS 包装加密数据的解密。更具体地说,我们测试的任何实现都无法在不尝试完全将其加载到内存中或遭受其他关于大文件的限制的情况下解密对称加密的 CMS 包装容器。
我们还评估了基于 LUKS 的镜像加密实现,LUKS 已经用作 Cinder 和 Nova 中卷和临时磁盘的加密机制。但是,我们无法找到合适的解决方案来直接处理用户空间中的基于文件的 LUKS 加密。首先,即使是基于文件的 LUKS 设备,通过 cryptsetup 处理也始终需要 dm-crypt 内核模块和相应的 root 权限。其次,与 LibVirt 使用的本机 LUKS 不同,通过 cryptsetup 可用的 LUKS 处理会创建临时设备映射器端点,数据从中读取或写入。没有直接从/向加密的 LUKS 文件读取/写入,并且 LUKS 打开/关闭需要相应处理。最后,LUKS 是一种主要设计用于磁盘加密的格式。虽然它也可以用于文件(通过将文件格式化为 LUKS 设备),但处理起来比较不方便;例如,LUKS 容器文件的大小需要提前计算和分配,因为它充当具有固定大小的磁盘。
数据模型影响¶
影响取决于实现是否会对镜像数据模型进行实际更改,或者只是使用元数据中的通用属性字段。在后一种情况下,加密属性将被添加到 metadefs 中。
REST API 影响¶
在上传要加密的镜像时,需要在请求主体中引入额外的属性,以指定所需的加密格式和密钥 ID。两者都将在上传之前用于在本地加密镜像。
安全影响¶
对 OpenStack 的安全性有影响
本规范将解决镜像中数据机密性的问题
引入了镜像加密,因此将在所有相关组件(Nova、Cinder、OSC)中使用加密算法。
通知影响¶
无
其他最终用户影响¶
用户应该能够选择性地,但有意识地上传加密的镜像。
如果管理员配置 Glance 以拒绝未加密的镜像,则尝试上传到 Glance 时将不会接受此类镜像。
性能影响¶
OpenStack 组件中建议的加密/解密机制仅在需要时使用,并且完全跳过非加密的镜像容器类型。
因此,任何性能影响仅适用于新引入的加密镜像类型,其中镜像处理将比常规镜像具有更高的计算成本和更长的处理时间。 影响将因各个主机性能和支持的密码算法 CPU 扩展而异。
其他部署者影响¶
部署者可以通过相应地在 ‘container_formats’ 中添加/省略 ‘encrypted’ 来切换接受或强制使用加密镜像。
通过省略 ‘container_formats’ 中的所有其他镜像类型来强制使用加密镜像的部署者将使公共镜像不可用,因为 Barbican 缺乏公共密钥功能。
需要一个密钥管理器——例如 Barbican。
开发人员影响¶
无
升级影响¶
无
实现¶
负责人¶
主要负责人:Markus Hentsch (IRC: mhen)
其他贡献者:Josephine Seifert (IRC: Luzi)
工作项¶
向 Glance 添加支持加密的 container 类型
在上传加密镜像时添加注册 Barbican secret 的消费者
在删除加密镜像时添加取消注册 Barbican secret 的消费者
为可互操作镜像导入提供与 image_conversion 插件的兼容性(跳过加密 payload 的转换尝试)
为 python-glanceclient 添加支持,以便可以上传 container_format: encrypted 的镜像
依赖项¶
为了支持建议的基本加密机制,需要在所有需要执行加密/解密操作的系统上安装 GPG。
本规范要求在参与镜像加密工作流的组件(Nova、Cinder、OSC)之间共享的全局库中实现适当的加密/解密功能。我们确定使用 os-brick。
Barbican 中的 secret consumer API 是 Glance 能够注册和取消注册 secret 消费者所必需的
测试¶
Tempest 测试需要访问加密镜像才能进行测试。 这意味着 Tempest 需要提供一个已经加密的镜像文件及其相应的密钥,或者能够自行加密镜像。 这一点仍在讨论中。
文档影响¶
应该记录给部署者,如何在 OpenStack 配置中启用此功能。应该为最终用户提供有关如何使用加密镜像的文档。
参考资料¶
[1] Barbican Secret Consumer Spec: https://review.opendev.org/#/c/662013/
Nova-Spec: https://review.openstack.org/#/c/608696/
Cinder Spec: https://review.openstack.org/#/c/608663/
历史¶
发布名称 |
描述 |
|---|---|
Victoria |
引入 |