关注了就能看到更多这么棒的文章哦~

Challenges in protecting virtual machines from untrusted entities

December 1, 2020
This article was contributed by Kashyap Chamarthy
KVM Forum
DeepL assisted translation
https://lwn.net/Articles/838488/

随着越来越多的工作负载被转移到云端,CPU 厂商已经开始推出特制的硬件功能,用来将虚拟机(VM)与可能有敌意者隔离开来。处理器中的这些新功能,以及扩展,实现了 "secure VMs"(或 "confidential VMs")的概念:需要保护虚拟机的 "敏感状态(sensitive state)"不能受到不可靠的实体的影响。Janosch Frank 从他为 s390 架构的安全虚拟机实现所做的贡献经验出发,在 2020 年(虚拟)KVM 论坛的演讲中描述了这个过程中面临的挑战。虽然各 CPU 厂商的具体实现可能各不相同,但有许多共同问题,这里可能有合作空间。

来自 AMD 的安全加密虚拟化(SEV,Secure Encrypted Virtualization)(更多信息可参见去年 KVM 论坛演讲 和 LWN 的简要回顾),英特尔的信任域扩展(TDX, Trust Domain Extensions),以及 IBM 的 s390 和 Power 架构上用到的 Secure Execution(去年 KVM 论坛演讲介绍过),这些都是旨在保护虚拟机免受潜在恶意实体侵害的硬件技术。其他架构,比如 Arm,预计也会跟进。

安全虚拟机(secure VM)的敏感状态(sensitive state)不允许 hipervisor 来访问,而需要由一个 "受信任的实体,trusted entity"(包括软件、CPU 固件和硬件的组合)来管理它。但这带来了一个问题。什么才算 "sensitive stage"?这包括 guest 系统中的内存内容,其中可能含有磁盘加密密钥和其他敏感数据。此外,guest 的 CPU 寄存器也可以保存了加密密钥片段,也是敏感信息。虚拟机的执行路径(execution path)是另一个敏感信息,一个恶意的 hypervisor 可能会改变虚拟机的执行流程,例如,它可以向 guest 注入一个 exception,这肯定会出问题。因此,必须根据有效的 "VM control",来决定执行哪些指令,以及如何执行这些指令。此外,一个恶意 hypervisor,即使不能从 guest 中提取任何信息,也仍然可以对 guest 发动拒绝服务(DoS)攻击。

还有 "静止数据,data at rest"(即存储在磁盘上的 guest 数据),这些数据通常不受 trusted entity 的保护,虚拟机有必要使用磁盘加密等常见技术来保护起来。成功保护虚拟机及其数据,才可以让用户在公有云中部署敏感工作。

Threat vectors

要想缩小我们需要防御的 threat vector 的话,需要先定义好什么是可以 trust 的,也就是通常所说的 "threat modeling"。在公有云设置中,位置临近的 VM 以及它们共同的 host hypervisor 都是被视为完全不可信任的。AMD 的 SEV 里使用了定义比较模糊的 "善意但易受攻击的管理程序(benign but vulnerable hypervisor)"的 model,其中提到 "hypervisor 不能被认为是 100%安全的,但它可以被认为是本着善意来做事的"。也就是说,hypervisor 管理程序可能不会主动尝试去攻击已经打开了 SEV 的 VM,但它可能包含可被利用的漏洞。举例来说,除了 “secure VM” 以外,AMD 只将处理器硬件和固件视为完全可信(fully trusted)。

而什么是不可信的呢?云计算运营商(cloud operator)、处理器 firmware、SMM(System Management Mode)、host 的操作系统及 hypervisor、所有外接 PCI(e)设备等等。这里的 "untrusted(不可信)"是指这些东西被认为是可能是 "恶意的,有可能与其他不受信任的模块配合起来,企图破坏 SEV-SNP 虚拟机的安全保障机制"。与此类似地,英特尔的 TDX[PDF]也定义了其 "trust boundaries"。英特尔的硬件,包括其 TDX module,是可信的,其 firmware 中的 Authenticated Code Modules (认证代码模块) 也是可信的。其余的都是不可信的。

Frank 概述了一些常见的用来防范不受信任实体攻击、并保护虚拟机的敏感状态的主要措施。首先,要对虚拟机的内存和其他可以修改的位(如 guest CPU 寄存器)进行加密,这样攻击者在没有密钥的情况下只能看到乱七八糟的数据。其次,是通过 access control,来限制对 guest 中敏感数据的访问。三是 "integrity verification (完整性验证)",确保虚拟机只访问不会被恶意攻击者改变的内容。

Protecting memory, vCPU registers, and boot integrity

通过加密 guest 内存,使其无法读取,这样一来除了 guest 本身和 trusted entity 外,其他实体都无法访问,从而提供 "memory confidentiality(内存保密性)"。实现这一目标的一种方法是让 CPU 的内存控制器来完成内存加密的重任,每个 guest 都有自己的密钥,存储在硬件中,永远不会失效。

将加密密钥存储在硬件中还可以防止 "冷启动攻击,cold-boot attacks",这是一种需要能接触到硬件的情况下通过 side-channel attack 来把存储在 RAM 中的敏感信息窃取出来的攻击方式。不过,存储在硬件中的密钥意味着可以存储的数量是受硬件条件限制的,比如第一代 AMD EYPC("Zen")CPU 就有 15 个加密密钥的硬性限制,这严重限制了 secure VM 的数量。但后来的一代 CPU(AMD "Zen 2")就将其扩展到 509 个密钥。

仅仅加密 guest 内存是不够的,还需要防篡改。因为尽管加密了,hypervisor 仍然可以破坏 guest RAM。通过体系架构中的硬件访问控制,就可以防止对 guest 内存的篡改。源自安全虚拟机外部的读写将导致 exception。这样一来,只要它不离开 protected state,就能一直保证内存的完整性。此外,Frank 提醒说,这也允许把 "rogue access,恶意访问" 追踪和记录下来了。

guest CPU 寄存器需要保证无法被外部读取。hypervisor 应该只有在需要模拟执行 CPU 指令的情况下,才允许从指定的寄存器来进行读取或写入。因此,trusted entity 必须对所有或某些特定的 guest CPU 寄存器进行加密。虚拟机的状态,无论是在初始化时,还是在正常运行时,都存储在称为虚拟机 "control block" 的厂商相关数据结构中。guest CPU 寄存器通过向 hypervisor 提供一个 dummy VM control block 来隔离开,只有 trusted entity 才能管理真正的 control block。

然而还有另一个挑战,只有用户批准的可执行文件才应该允许在 guest 中启动。有两种方法来处理这个问题:一种是 boot-data encryption,可执行文件(例如 guest kernel)被加密,并添加了一个 header,其中保存着可执行文件被允许运行在每台物理机上的密钥 slot,以及一些完整性校验数据。然后,处理器的固件(是 trusted entity)搜索它可以提取的密钥 slot,从中获取到可执行文件的加密密钥。另一种做法是 "remote attestation,远程证明"。这个想法已经存在了很久,但实现和管理起来却非常困难,它允许虚拟机向远程方,即虚拟机的所有者证明自己的身份,证明它确实正在运行经过批准的可执行文件。这种证明可以让所有者相信,guest 是在真正的、经过认证的硬件上执行授权过的工作负载。

remote attestation 可以做到快速地更改虚拟机和其他 entity 的认证规则(authorization rules),而 boot-data encryption 更容易实现,而且不需要网络连接。但只依靠 boot-data encryption 也有问题:授权一台新的机器时需要使用新的密钥 slot 来重新生成可执行文件并更新可执行文件,这个过程需要用户干预。此外,还有一个长期存在的问题,就是如何分发和验证公钥和私钥。

Frank 强调,通常情况下,将所有这些技术结合起来会产生最好的结果。

What about I/O and swap

一旦安全虚拟机启动并运行,它可能会想要进行 I/O 和 swap。试图在加密的 guest 内存页上执行 I/O 操作的设备只会看到乱码数据或得到访问异常。需要有一种方法来 "unprotect"(去掉保护)一些特殊的 I/O page。这应该是基于 guest 的明确请求才会进行的操作。guest 的 I/O 是会使用 bounce 机制来放到 shared page 上的,因此在 guest 对敏感数据进行任何 I/O 之前,必须先对其进行加密,可以通过使用 SSH、HTTPS、LUKS disk encryption 等常见机制。然而,对 I/O 的特殊处理意味着会降低性能,但 Frank 有信心未来可以大大减少性能降低的幅度。

让 swap 可用,这是另一个挑战。在 swap-out 过程中,内存 page 被放置到存储设备上,它需要以加密的形式被主机访问到,这样才能将其写入设备。在 swap 过程中,当 page 被拉回主内存时,它应该在 guest 再次访问该页面之前进行完整性检查和解密。还需要防止 "replay" 攻击,即攻击者可以用虚拟机以前的一份内存副本来替换当前的内存内容。hypervisor 可以在 trusted entity 的帮助下来协调 swap-out 和 swap-in 的过程,从而保障整个操作是安全的。

但与特殊的 I/O 处理一样,swap 会产生显著的性能影响。因此应避免在内存过度占用的环境中使用 secure VM。

Current development efforts

事实证明,之前提出的一种 "generalize memory encryption models, 通用化的内存加密模型"的方法,相当难以得到一个公用的实现,因为 CPU 架构在实现 secure VM 方面差异太大。英特尔仍在增加对 secure VM 的支持(另见 Sean Christopherson 在 KVM 论坛上关于英特尔 TDX 演讲 https://static.sched.com/hosted_files/kvmforum2020/57/TDX%20-%20KVM%20Forum%202020.pdf))。Frank 指出,s390 已经深入到了 Linux 内存管理子系统来对 I/O page 进行 pin 操作。其他平台也需要使用类似的机制。然而,他预计实现这些功能的 mainline kernel 会需要更多的时间,因为这牵涉到改动公共代码。IBM 的 Secure Extension 从 Linux 5.4 开始支持其 Power 架构,在 Linux 5.7 中开始支持 s390。

在 Linux 4.16 中为基于 KVM 的 guest 引入了对 AMD SEV 的支持。Linux 5.10 已经支持了 AMD 的 Encrypted State 扩展,对 Secure Nested Paging 的支持也在进行中。此外,目前正在努力将 SEV 的 "address space IDs"(ASIDs)的支持添加到 Linux 的 cgroup 中。这里就牵涉到前面提到的最大可能的硬件加密密钥数量限制的问题。其他 CPU 架构的开发人员很快就表示有兴趣想找一种公用的方法来解决这个问题。

Frank 指出的一个迫切的问题是测试很复杂:设置 boot-data encryption 和配置 remote attestation 环境都很麻烦。内核将有更多的编译选项,还有新的 KVM ioctl()调用,新的 trusted entity 接口,以及用户空间组件(如 QEMU,libvirt)也有改动。所有这些都增加了测试的负担。

Future

实时迁移(live migration)有望最终得到解决。在迁移过程中,虚拟机的整个状态需要加密,并在目的地上对其完整性进行验证。Frank 预计这里会有很麻烦的向后兼容问题——传统上由 hypervisor 处理的迁移逻辑现在部分转移到 trusted entity 上了。此外,迁移策略需要确定 secure VM 可以迁移到哪些主机,这涉及到许多条件判断。未来几年还有很多工作要做。此外,我们可能会看到 "secure I/O devices",这类设备只会响应来自认证过的安全虚拟机的 I/O 请求,根本不与 host 交流。

另一个潜在的棘手话题是在 guest 内核崩溃时需要能抓取其内存内容。使用 kdump,可以抓取 crash dump 来存储到加密磁盘上,但这要求执行这部分功能的代码要能够在 guest 内部执行才行。需要能够启动 kdump 加载的用来采集内存内容特制的 "crash kernel"(通过 kexec 子系统来实现),才能真正将内存内容写入磁盘。

最重要的是,Frank 指出,需要由 trusted entity 来施加进一步的保护措施,以防止 side-channel attack,比如需要禁用 SMT(simultaneous multithreading)和 extra cache flushing。

总的来说,支撑安全虚拟机的基本功能在各种 CPU 架构中都是通用的。厂商可以合作的一个具体领域是与 boot 阶段相关的工具。远程认证和加密引导可执行文件都需要许多工具。如果 CPU 厂商在这个领域不出现太大的分歧,他们就可以合作出公用的工具,而不是每个人都维护自己的定制工具。就像 AMD 的 sev-tool,s390 的 genprotimg 等等。

Enarx 是一个相对较新的项目,它希望 "让部署[敏感]工作负载到各种不同的可信执行环境(TEE)的工作变得简单"。它与 CPU 架构无关,因此旨在为处理器厂商的不同 TEE 创建一个抽象。更具体地说,Enarx 为 "data in use"(指那些不是静止或者正在传输中的数据)提供加密,并管理 attestation。所有这些工作就可以不需要每个硬件平台从头开始做了。

"安全虚拟机的重要性和复杂性将随着每一个架构的[硬件]扩展发布而继续增加。幸运的是,我们仍然有时间来一起讨论合作的可能性。"Frank 总结道。由于多个 CPU 架构已经引入了这一理念,开发人员也在致力于安全虚拟机的实现,所以现在是所有厂商合作的最佳时机。

【感谢 Janosch Frank 对本文的认真审阅】。

全文完
LWN 文章遵循 CC BY-SA 4.0 许可协议。

欢迎分享、转载及基于现有协议再创作~

长按下面二维码关注,关注 LWN 深度文章以及开源社区的各种新近言论~

LWN:如何保护虚拟机不受恶意来源的攻击?相关推荐

  1. plus钱包受黑客攻击_如何保护您的在线业务免受黑客攻击

    plus钱包受黑客攻击 您的企业安全吗? (How safe is your business?) The news that's made every business think twice ab ...

  2. 2011年至2019年制造的 AMD 处理器均易受两种新型攻击

    聚焦源代码安全,网罗国内外最新资讯! 编译:奇安信代码卫士团队 本周,奥地利格拉茨技术大学和法国雷恩大学的六名研究人员表示,2011年至2019年制造的 AMD 处理器易受两种新型攻击的影响.它们影响 ...

  3. 思科称其安全设备易受 SNIcat 数据渗透攻击

     聚焦源代码安全,网罗国内外最新资讯! 编译:代码卫士 思科表示该的某些安全产品未能检测并阻止流量进入恶意服务器,导致攻击者滥用 SNIcat 技术从企业网络窃取数据. 受影响设备包括运行 FTD ( ...

  4. linux脚本攻击,恶意shell脚本攻击的方法与预防策略

    前言 网络安全对于互联网从业者而言,一直是一个重要的.绕不开的话题,PowerShell可以给运维人员带来极大的方便,但同时也是被攻击者盯上的重灾区.想想就非常可怕,攻击的人只要能从远程执行shell ...

  5. NVE-01-2015-11090:SSL/TLS 受诫礼(BAR-MITZVAH)攻击漏洞(CVE-2015-2808) [端口: 443]

    漏洞标识 NVE-01-2015-11090 漏洞名称 SSL/TLS 受诫礼(BAR-MITZVAH)攻击漏洞(CVE-2015-2808) 漏洞类别 WEB服务器测试 发布日期 2015.03.3 ...

  6. SSL/TLS 受诫礼(BAR-MITZVAH)攻击漏洞(CVE-2015-2808)漏洞加固指南

    漏洞信息 序号 漏洞类型 风险等级 漏洞主机( 操作系统及版本) 1 SSL/TLS 受诫礼(BAR-MITZVAH)攻击漏洞(CVE-2015-2808)漏洞 中 linux 漏洞加固实施 漏洞1: ...

  7. office受保护视图_使用受保护的视图激发恶意Office文档

    office受保护视图 介绍 (Intro) I wanted to share an interesting behavior I discovered with Microsoft Office ...

  8. 安装安全防护软件有助于保护计算机不受侵害,9. 安装安全防护软件有助于保护计算机不受病毒侵害。...

    摘要: 装安助于系统操作赖于数据库依.进行的压安装验包完毕力试后应括(,护软害炸性介质的工道有爆业管危险输送.其主能有要功,有计算机次要成膜颜料物质料的是涂.... 装安助于系统操作赖于数据库依. 热 ...

  9. 为何苹果电脑虚拟机如此受欢迎

    2019独角兽企业重金招聘Python工程师标准>>> 成为一款合格的虚拟机需要经历不断地测试,考虑用户可能会遇到的各种情况,让它在使用时能够发挥最大作用. 作为一款连续超过9年ma ...

最新文章

  1. CSDN如何删除自己不用的分类(亲测有效!)
  2. spring boot mybatis 整合_MyBatis学习:MyBatis和Spring整合
  3. 公众号第三方平台开发 - 教程五 代公众号发起网页授权源码
  4. springboot中使用websocket_在 Spring Boot 项目中使用 activiti
  5. python之路---15 装饰器
  6. C/C++底层实现指定磁盘只读
  7. linux下驱动程序数字签名,64位Windows操作系统为驱动程序添加测试数字签名
  8. Java金融计算机计算irr_手把手教你使用金融计算器
  9. Android 图片查看器选择器 PictureSelector
  10. 植树问题java,云南省优秀多媒体育软件大赛公示.doc
  11. oracle虚拟用户和密码,创建 Virtual Private Catalog(虚拟用户目录)(Oracle 11g)
  12. 利用VSCode+platformio学习esp32开发
  13. python itchat实现微信自动回复
  14. EV3文件打不开,闪退怎么办(完美解决,无弹窗,无警告)
  15. Ambari——大数据平台的搭建利器(一)
  16. golang的ping检测网络实现
  17. SLAM十四讲第三章课后习题
  18. C#串口通信从入门到精通(3)——虚拟串口工具的使用
  19. 强化学习:Q-Learning
  20. android shell du,Linux du 命令 command not found du 命令详解 du 命令未找到 du 命令安装 - CommandNotFound ⚡️ 坑否...

热门文章

  1. 使用mint ui(一)
  2. Android灯光系统背光灯
  3. IDEA运行工程时报错:java: java.lang.OutOfMemoryError: GC overhead limit exceeded
  4. Android 8源码目录结构详解
  5. WIN10 查看隐藏进程并强制终止进程
  6. 陈皓:程序员技术练级攻略
  7. 你如何看待重仓、轻仓、空仓(DBEx平台招商代理)
  8. 可关注10只超跌次新小盘股
  9. 【BZOJ】1455 罗马游戏 左偏树
  10. 一个c加一个g是什么牌子_C和G打头的手表都有哪些?