Red Hat Training

A Red Hat training course is available for RHEL 8

第 15 章 保护虚拟机

作为使用虚拟机(VM)的 RHEL 8 系统管理员,保护虚拟机的安全可尽可能降低您的客户端和主机操作系统被恶意软件破坏的风险。

本文档概述了 在 RHEL 8 主机上保护虚拟机 的工具程序 ,并提供了提高虚拟机安全性的方法列表

15.1. 虚拟机中的安全性是如何工作的

通过使用虚拟机,可在单一主机机器中托管多个操作系统。这些系统通过虚拟机监控程序(hypervisor)连接到主机,通常还通过虚拟网络连接。因此,每个虚拟机都可用作使用恶意软件攻击主机的向量,主机可以用作攻击任何虚拟机的向量。

图 15.1. 在虚拟化主机上潜在的恶意软件攻击向量

virt sec 成功攻击

因为虚拟机监控程序使用主机内核来管理虚拟机,所以在虚拟机操作系统中运行的服务通常会被利用来将恶意代码注入主机系统。但是,您可以使用主机和您的客体系统中的安全功能来保护您的系统不受此类安全隐患。

这些功能,如 SELinux 或 QEMU 沙盒,提供了各种措施,使恶意代码更难以攻击虚拟机监控程序,并在您的主机和虚拟机间进行传输。

图 15.2. 防止对虚拟化主机进行恶意软件攻击

Virt sec 阻止安全攻击

RHEL 8 为虚拟机安全性提供的许多功能始终活跃,无需启用或配置。详情请查看 第 15.4 节 “虚拟机安全性的自动功能”

另外,您可以遵循各种最佳实践,以尽量减小虚拟机和虚拟机监控程序的安全漏洞。更多信息请参阅 第 15.2 节 “保护虚拟机的最佳实践”

15.2. 保护虚拟机的最佳实践

根据以下步骤,您的虚拟机被恶意代码利用,并用作攻击向量攻击您的主机系统的风险会大幅降低。

在客户端中:

  • 象保护物理机器一样保护虚拟机的安全。增强安全性的具体方法取决于客户端操作系统。

    如果您的虚拟机正在运行 RHEL 8,请参阅在 RHEL 8 中配置和管理安全性 以了解有关提高客户端系统安全性的详细说明。

在主机端:

  • 当远程管理虚拟机时,请使用加密的工具(如 SSH)和网络协议(如 SSL)连接到虚拟机。
  • 确定 SELinux 处于 Enforcing 模式:

    # getenforce
    Enforcing

    如果 SELinux 被禁用或者处于 Permissive 模式,请参阅使用 SELinux 文档来激活 Enforcing 模式。

    注意

    SELinux Enforcing 模式还启用 sVirt RHEL 8 功能。这是用于虚拟化的一组特殊的 SELinux 布尔值,可手动调整,以便进行细致的虚拟机安全管理。

  • 使用带有 SecureBoot 的虚拟机:

    SecureBoot 是一个确保虚拟机运行以加密方式签名的操作系统的功能。这可防止因为恶意软件攻击而更改了操作系统的虚拟机引导。

    SecureBoot 只能在安装使用 OVMF 固件的 Linux 虚拟机时使用。具体步骤请查看 第 15.3 节 “创建 SecureBoot 虚拟机”

  • 不要使用 qemu-* 命令,如 qemu-img

    QEMU 是 RHEL 8 中虚拟化架构的一个基本组件,但很难手动管理,而不正确的 QEMU 配置可能会导致安全漏洞。因此,红帽不支持使用 qemu-* 命令。强烈建议您使用 libvirt 工具(如 virshvirt-installvirt-xml )与 QEMU 进行交互,因为这些工具会根据最佳实践编配 QEMU。

其它资源

15.3. 创建 SecureBoot 虚拟机

以下提供了有关创建使用 SecureBoot 功能的 Linux 虚拟机(VM)的步骤,可确保您的虚拟机运行以加密方式签名的操作系统。如果虚拟机的客户机操作系统被恶意软件所更改,则 SecureBoot 会阻止虚拟机引导,这可以停止恶意软件向您的主机分散的可能性。

先决条件

  • 虚拟机使用 Q35 机器类型。
  • 已安装 edk2-OVMF 软件包:

    # yum install edk2-ovmf
  • 操作系统(OS)安装源可存在于本地或者网络中。可以是以下格式之一:

    • 安装介质的 ISO 镜像
    • 现有虚拟机安装的磁盘镜像
  • 可选:对于快速、简单的配置安装,可以使用 Kickstart 文件。

流程

  1. 使用 virt-install 命令创建虚拟机,如 第 2.2.1 节 “使用命令行界面创建虚拟机” 所述。对于 --boot 选项,使用 uefi,nvram_template=/usr/share/OVMF/OVMF_VARS.secboot.fd 值。这使用 OVMF_VARS.secboot.fdOVMF_CODE.secboot.fd 文件作为虚拟机非 volatile RAM(NVRAM)设置的模板,它启用了 SecureBoot 功能。

    例如:

    # virt-install --name rhel8sb --memory 4096 --vcpus 4 --os-variant rhel8.0 --boot uefi,nvram_template=/usr/share/OVMF/OVMF_VARS.secboot.fd --disk boot_order=2,size=10 --disk boot_order=1,device=cdrom,bus=scsi,path=/images/RHEL-8.0-installation.iso
  2. 根据屏幕中的说明按照 OS 安装过程进行操作。

验证

  1. 安装客户端操作系统后,通过在 图形客户机控制台 中打开终端或 使用 SSH 连接到客户端操作系统来访问虚拟机的命令行
  2. 要确认虚拟机上启用了 SecureBoot,请使用 mokutil --sb-state 命令:

    # mokutil --sb-state
    SecureBoot enabled

其它资源

  • 有关创建使用 RHEL 8 作为客户机操作系统的虚拟机时的安装过程详情,请参阅 引导 RHEL 8 安装

15.4. 虚拟机安全性的自动功能

除了手动方法提高 第 15.2 节 “保护虚拟机的最佳实践” 中列出的虚拟机安全性外,很多安全功能还由 libvirt 软件套件提供,并在 RHEL 8 中使用虚拟化时自动启用。它们是:

系统及用户会话

要访问 RHEL 8 中虚拟机管理的所有可用工具,您需要使用 libvirt 系统会话。要做到这一点,您必须在系统中具有 root 权限,或者是 libvirt 用户组的一部分。

没有在 libvirt 组中的非 root 用户只能访问 libvirt 的 用户会话,该会话必须在访问资源时遵守本地用户的访问权利。例如,在用户会话中,您无法检测或访问系统会话或其他用户创建的虚拟机。另外,可用的 VM 网络配置选项也有很大限制。

注意

RHEL 8 文档假定您有 libvirt 系统会话权限。

虚拟机分离
单个虚拟机作为隔离进程在主机上运行,并依赖于主机内核强制的安全性。因此,虚拟机无法读取或访问同一主机上其他虚拟机的内存或者存储。
QEMU 沙盒
防止 QEMU 代码执行系统调用的功能可能会破坏主机的安全。
内核地址空间需求(KASLR)
启用随机化内核镜像压缩的物理地址和虚拟地址。因此,KASLR 会防止客户机安全漏洞根据内核对象的位置进行安全攻击。

15.5. 虚拟化布尔值

要在 RHEL 8 系统中精细配置虚拟机安全性,您可以在主机上配置 SELinux 布尔值,以确保虚拟机监控程序以特定的方式进行操作。

要列出所有与虚拟化相关的布尔值及其状态,请使用 getsebool -a | grep virt 命令:

$ getsebool -a | grep virt
[...]
virt_sandbox_use_netlink --> off
virt_sandbox_use_sys_admin --> off
virt_transition_userdomain --> off
virt_use_comm --> off
virt_use_execmem --> off
virt_use_fusefs --> off
[...]

要启用特定的布尔值,以 root 用户身份使用 setsebool -P boolean_name on 命令。要禁用布尔值,请使用 setsebool -P boolean_name off

下表列出了 RHEL 8 中可用的与虚拟化相关的布尔值以及启用后的功能:

表 15.1. SELinux 虚拟化布尔值

SELinux 布尔值描述

staff_use_svirt

启用非 root 用户创建并转换虚拟机至 sVirt。

unprivuser_use_svirt

启用非特权用户创建虚拟机并将其转换至 sVirt。

virt_sandbox_use_audit

启用沙盒容器来发送审核信息。

virt_sandbox_use_netlink

启用沙盒容器使用 netlink 系统调用。

virt_sandbox_use_sys_admin

启用沙盒容器使用 sys_admin 系统调用,如 mount。

virt_transition_userdomain

启用虚拟进程作为用户域运行。

virt_use_comm

启用 virt 使用串行/并行通信端口。

virt_use_execmem

允许受限制的虚拟客户机使用可执行内存和可执行堆栈。

virt_use_fusefs

启用 virt 读取 FUSE 挂载的文件。

virt_use_nfs

启用 virt 管理 NFS 挂载的文件。

virt_use_rawip

启用 virt 与 rawip 套接字交互。

virt_use_samba

启用 virt 管理 CIFS 挂载的文件。

virt_use_sanlock

启用受限制的虚拟客户机与 sanlock 交互。

virt_use_usb

启用 virt 使用 USB 设备。

virt_use_xserver

启用虚拟机与 X 窗口系统交互。

15.6. 在 IBM Z 中设置 IBM Secure Execution

当使用 IBM Z 硬件来运行 RHEL 8 主机时,您可以通过为虚拟机配置 IBM Secure Execution 来提高虚拟机(VM)的安全性。

IBM Secure Execution(也称 Protected Virtualization)可防止主机系统访问虚拟机的状态和内存内容。因此,即使主机被攻击,也无法用作攻击客户端操作系统的向量。另外,安全执行也可以用来防止不可信主机从虚拟机获取敏感信息。

以下流程描述了如何将 IBM Z 主机上的现有虚拟机转换为安全虚拟机。

先决条件

  • 系统硬件是以下之一:

    • IBM z15 或更高版本
    • IBM LinuxONE III 或更高版本
  • 为您的系统启用安全执行功能。要验证,请使用:

    # grep facilities /proc/cpuinfo | grep 158

    如果这个命令显示任何输出,代表您的 CPU 与安全执行兼容。

  • 内核包含对安全执行的支持。要确认,请使用:

    # ls /sys/firmware | grep uv

    如果该命令生成任何输出结果,您的内核支持安全执行。

  • 主机 CPU 模型包含 unpack 工具。要确认,请使用:

    # virsh domcapabilities | grep unpack
    <feature policy='require' name='unpack'/>

    如果命令生成上述输出,则您的 CPU 主机模型与安全执行兼容。

  • 虚拟机的 CPU 模式设置为 host-model。要确认这一点,请使用以下内容并将 vm-name 替换为虚拟机的名称。

    # virsh dumpxml vm-name | grep "<cpu mode='host-model'/>"

    如果该命令生成任何输出结果,则会正确设置虚拟机的 CPU 模式。

流程

  1. 在主机的 引导配置 中添加 prot_virt=1 内核参数。

    # # grubby --update-kernel=ALL --args="prot_virt=1"
  2. 为您要保护的虚拟机创建参数文件。例如:

    # touch ~/secure-parameters
  3. 在主机的 /boot/loader/entries 目录中,使用最新版本识别引导装载程序条目:

    # ls /boot/loader/entries -l
    [...]
    -rw-r--r--. 1 root root  281 Oct  9 15:51 3ab27a195c2849429927b00679db15c1-4.18.0-240.el8.s390x.conf
  4. 检索引导装载程序条目的内核选项行:

    # cat /boot/loader/entries/3ab27a195c2849429927b00679db15c1-4.18.0-240.el8.s390x.conf | grep options
    options root=/dev/mapper/rhel-root crashkernel=auto rd.lvm.lv=rhel/root rd.lvm.lv=rhel/swap
  5. 将选项行和 swiotlb=262144 的内容添加到创建的参数文件。

    # echo "root=/dev/mapper/rhel-root crashkernel=auto rd.lvm.lv=rhel/root rd.lvm.lv=rhel/swap swiotlb=262144" > ~/secure-parameters
  6. 为所选虚拟机生成 IBM Secure Execution 镜像。

    例如,以下内容基于 /boot/vmlinuz-4.18.0-240.el8.s390x 镜像创建一个 /boot/secure-image 安全镜像,使用 secure-parameters 文件、/boot/initramfs-4.18.0-240.el8.s390x.img 初始 RAM 磁盘文件和 HKD-8651-000201C048.crt 主机密钥文档。

    # genprotimg -i /boot/vmlinuz-4.18.0-240.el8.s390x -r /boot/initramfs-4.18.0-240.el8.s390x.img -p ~/secure-parameters -k HKD-8651-00020089A8.crt -o /boot/secure-image

    使用 genprotimg 实用程序创建安全镜像,其中包含内核参数、初始 RAM 磁盘和引导镜像。

  7. 在虚拟机的客户端操作系统中,更新虚拟机的引导菜单以从安全镜像引导。另外,删除以 initrdoptions 开头的行,因为不需要它们。

    例如,在 RHEL 8.3 虚拟机中,可在 /boot/loader/entries/ 目录中编辑引导菜单:

    # cat /boot/loader/entries/3ab27a195c2849429927b00679db15c1-4.18.0-240.el8.s390x.conf
    title Red Hat Enterprise Linux 8.3
    version 4.18.0-240.el8.s390x
    linux /boot/secure-image
    [...]
  8. 启用 virtio 设备以使用共享缓冲区。要做到这一点,使用 virsh edit 修改虚拟机的 XML 配置,并将 iommu='on' 添加到所有设备的 <driver> 行中。例如:

    <interface type='network'>
      <source network='default'/>
      <model type='virtio'/>
      <driver name='vhost' iommu='on'/>
    </interface>

    如果设备配置不包含任何 <driver> 行,请添加 <driver iommu='on'\>

  9. 禁用虚拟机上的内存 Ballooning,因为此功能与安全执行不兼容。要做到这一点,请在虚拟机 XML 配置中添加以下行。

    <memballoon model='none'/>
  10. 创建可引导磁盘镜像

    # zipl -V
  11. 安全地删除原始的未保护的文件。例如:

    # shred /boot/vmlinuz-4.18.0-240.el8.s390x
    # shred /boot/initramfs-4.18.0-240.el8.s390x.img
    # shred secure-parameters

    原始引导镜像、初始 RAM 镜像和 kernel 参数文件不受保护。如果没有删除它们,启用安全执行功能的虚拟机仍可能会被抓取尝试或敏感数据处理。

验证

  • 在主机上,使用 virsh dumpxml 实用程序确认安全虚拟机的 XML 配置。配置必须包含 <driver iommu='on'/><memballoon model='none'/> 项。

    # virsh dumpxml vm-name
    [...]
      <cpu mode='host-model'/>
      <devices>
        <disk type='file' device='disk'>
          <driver name='qemu' type='qcow2' cache='none' io='native' iommu='on'>
          <source file='/var/lib/libvirt/images/secure-guest.qcow2'/>
          <target dev='vda' bus='virtio'/>
        </disk>
        <interface type='network'>
          <driver iommu='on'/>
          <source network='default'/>
          <model type='virtio'/>
        </interface>
        <console type='pty'/>
        <memballoon model='none'/>
      </devices>
    </domain>

其它资源

15.7. 将加密 coprocessors 附加到 IBM Z 上的虚拟机

要在 IBM Z 主机上的虚拟机中使用硬件加密,请从加密的 coprocessor 设备创建介质设备并将其分配给预期的虚拟机。具体步骤请查看以下说明。

先决条件

  • 您的主机运行在 IBM Z 硬件上。
  • 加密 coprocessor 与设备分配兼容。要确认这一点,请确保您的 coprocessor 的 type 列为 CEX4 或更高版本。

    # lszcrypt -V
    
    CARD.DOMAIN TYPE  MODE        STATUS  REQUESTS  PENDING HWTYPE QDEPTH FUNCTIONS  DRIVER
    --------------------------------------------------------------------------------------------
    05         CEX5C CCA-Coproc  online         1        0     11     08 S--D--N--  cex4card
    05.0004    CEX5C CCA-Coproc  online         1        0     11     08 S--D--N--  cex4queue
    05.00ab    CEX5C CCA-Coproc  online         1        0     11     08 S--D--N--  cex4queue
  • 已安装 mdevctl 软件包。
  • 载入 vfio_ap 内核模块。要验证,请使用:

    # lsmod | grep vfio_ap
    vfio_ap         24576  0
    [...]

    要载入模块,请使用:

    # modprobe vfio_ap

流程

  1. 在主机上,将加密设备重新分配给 vfio-ap 驱动程序。以下示例为 vfio-ap 分配了两个位掩码 ID 为 (0x05, 0x0004)(0x05, 0x00ab) 的加密设备。

    #  echo -0x05 > /sys/bus/ap/apmask
    #  echo -0x0004, -0x00ab > /sys/bus/ap/aqmask

    有关识别位掩码 ID 值的详情,请参考来自 IBM 的 KVM Virtual Server Management 文档中 的为加密适配器资源准备 pass-through 设备 的信息。

  2. 验证是否正确分配了加密设备。

    # lszcrypt -V
    
    CARD.DOMAIN TYPE  MODE        STATUS  REQUESTS  PENDING HWTYPE QDEPTH FUNCTIONS  DRIVER
    --------------------------------------------------------------------------------------------
    05          CEX5C CCA-Coproc  -              1        0     11     08 S--D--N--  cex4card
    05.0004     CEX5C CCA-Coproc  -              1        0     11     08 S--D--N--  vfio_ap
    05.00ab     CEX5C CCA-Coproc  -              1        0     11     08 S--D--N--  vfio_ap

    如果域队列的 DRIVER 值更改为 vfio_ap,则代表状态可以成功。

  3. 生成设备 UUID。

    # uuidgen
    669d9b23-fe1b-4ecb-be08-a2fabca99b71

    在此流程的以下步骤中,将 669d9b23-fe1b-4ecb-be08-a2fabca99b71 替换为您生成的 UUID。

  4. 使用 UUID,创建新的 vfio_ap 设备。

    以下示例演示了创建永久介质设备并为它分配队列。例如,以下命令将域适配器 0x05 以及域队列 0x00040x00ab 分配给设备 669d9b23-fe1b-4ecb-be08-a2fabca99b71

    # mdevctl define --uuid 669d9b23-fe1b-4ecb-be08-a2fabca99b71 --parent matrix --type vfio_ap-passthrough
    # mdevctl modify --uuid 669d9b23-fe1b-4ecb-be08-a2fabca99b71 --addattr=assign_adapter --value=0x05
    # mdevctl modify --uuid 669d9b23-fe1b-4ecb-be08-a2fabca99b71 --addattr=assign_domain --value=0x0004
    # mdevctl modify --uuid 669d9b23-fe1b-4ecb-be08-a2fabca99b71 --addattr=assign_domain --value=0x00ab
  5. 启动 mediated device。

    # mdevctl start --uuid 669d9b23-fe1b-4ecb-be08-a2fabca99b71
  6. 检查配置是否已正确应用

    # cat /sys/devices/vfio_ap/matrix/mdev_supported_types/vfio_ap-passthrough/devices/669d9b23-fe1b-4ecb-be08-a2fabca99b71
    05.0004
    05.00ab

    如果输出包含您之前分配给 vfio-ap 的队列的数字值,则代表过程成功。

  7. 使用 virsh edit 命令打开您要使用加密设备的虚拟机 XML 配置。

    # virsh edit vm-name
  8. 在 XML 配置的 <devices> 部分添加以下行,并保存它。

    <hostdev mode='subsystem' type='mdev' managed='no' model='vfio-ap'>
      <source>
        <address uuid='669d9b23-fe1b-4ecb-be08-a2fabca99b71'/>
      </source>
    </hostdev>

    请注意,每个 UUID 每次只能分配给一个虚拟机。

验证

  1. 启动您为其分配该介质设备的虚拟机。
  2. 客户端操作系统引导后,请确定它检测到分配的加密设备。

    # lszcrypt -V
    
    CARD.DOMAIN TYPE  MODE        STATUS  REQUESTS  PENDING HWTYPE QDEPTH FUNCTIONS  DRIVER
    --------------------------------------------------------------------------------------------
    05          CEX5C CCA-Coproc  online         1        0     11     08 S--D--N--  cex4card
    05.0004     CEX5C CCA-Coproc  online         1        0     11     08 S--D--N--  cex4queue
    05.00ab     CEX5C CCA-Coproc  online         1        0     11     08 S--D--N--  cex4queue

    客户机操作系统中的这个命令的输出,与在有相同加密的 coprocessor 设备的主机逻辑分区中是一致的。

15.8. 在 Windows 虚拟机中启用标准硬件安全性

要保护 Windows 虚拟机,您可以使用 Windows 设备的标准硬件功能启用基本级别的安全性。

先决条件

  • 请确定您安装了最新的 WHQL 认证的 VirtIO 驱动程序。
  • 确保虚拟机固件支持 UEFI 引导。
  • 在主机机器上安装 edk2-OVMF 软件包。

    # yum install edk2-ovmf
  • 在主机机器上安装 vTPM 软件包。

    # yum install swtpm libtpms
  • 确保虚拟机使用 Q35 机器架构。
  • 请确定您有 Windows 安装介质。

流程

  1. 通过在虚拟机 XML 配置的 <devices> 部分添加以下参数来启用 TPM 2.0。

    <devices>
    [...]
      <tpm model='tpm-crb'>
        <backend type='emulator' version='2.0'/>
      </tpm>
    [...]
    </devices>
  2. 在 UEFI 模式中安装 Windows。有关如何操作的更多信息,请参阅创建 SecureBoot 虚拟机
  3. 在 Windows 虚拟机上安装 VirtIO 驱动程序。有关如何操作的详情,请参考在 Windows 客户端中安装 virtio 驱动程序
  4. 在 UEFI 中,启用安全引导。有关如何进行此操作的更多信息,请参阅 安全引导

验证

  • 确定 Windows 机器中的设备安全性页面显示以下信息:

    设置 > Update & Security > Windows Security > 设备安全

    Your device meets the requirements for standard hardware security.

15.9. 在 Windows 虚拟机中启用增强的硬件安全性

为了进一步保护 Windows 虚拟机(VM),您可以启用基于虚拟化的代码完整性保护,也称 Hypervisor-protected Code Integrity(HVCI)。

先决条件

  • 确定启用了标准硬件安全性。如需更多信息,请参阅 在 Windows 虚拟机中启用标准硬件安全性
  • 确定启用了 KVM 嵌套。如需更多信息,请参阅 创建嵌套虚拟机
  • 在 KVM 命令行中,

    • 指定 CPU 型号。
    • 启用虚拟机扩展(VMX)功能。
    • 启用 Hyper-V 引擎。

      # -cpu Skylake-Client-v3,hv_stimer,hv_synic,hv_relaxed,hv_reenlightenment,hv_spinlocks=0xfff,hv_vpindex,hv_vapic,hv_time,hv_frequencies,hv_runtime,+kvm_pv_unhalt,+vmx

流程

  1. 在 Windows 虚拟机上,导航到 Core 隔离详情页:

    设置 > Update & Security > Windows Security > Device Security > Core isolated details

  2. 切换开关来启用 内存完整性
  3. 重启虚拟机。
注意

有关启用 HVCI 的其他方法,请参阅相关的 Microsoft 文档。

验证步骤

  • 确保 Windows 虚拟机上的 设备安全 页面显示以下信息:

    设置 > Update & Security > Windows Security > 设备安全

    Your device meets the requirements for enhanced hardware security.
  • 或者,检查 Windows 虚拟机的系统信息:

    1. 在命令提示符中运行 msinfo32.exe
    2. 检查 凭证 Guard 是否在 基于虚拟化的安全服务 Running 下列出,Hypervisor 强制 代码完整性

为了尽快向用户提供最新的信息,本文档可能会包括由机器自动从英文原文翻译的内容。如需更多信息,请参阅此说明。