在Windows上使用QEMU、MSYS2和Emacs运行虚拟机的开源解决方案

本文详细介绍了如何在Windows系统上通过开源工具QEMU、MSYS2和Emacs配置和运行虚拟机,包括安装步骤、性能优化技巧以及VMware虚拟机文件的转换方法。

QEMU、MSYS2和Emacs:在Windows上运行虚拟机的开源解决方案

| Dave Blandford

渗透测试员。开发者。纯GNU/Linux手机爱好者。

作为一名测试员,我所有的工作都在虚拟机(VM)内完成。最近,我遇到了一种情况,需要在Windows PC上运行虚拟机。问题在于,我不想与Broadcom创建账户或使用VirtualBox。我需要启动并运行QEMU(https://www.qemu.org/),即快速模拟器。QEMU是开源的(这在我的书中总是加分项!),并允许从qcow2镜像运行虚拟机。

这开始了我寻找一个像样的QEMU入门指南的旅程,但并没有找到,所以我决定自己写一个。

QEMU既是一个模拟器,也是一个虚拟化器。作为模拟器,QEMU可以运行与主机架构不同的虚拟机。例如,Android虚拟设备(AVD)使用QEMU来运行基于ARM的Android系统,无论主机的物理架构如何。这一功能在处理IoT固件时特别有用,因为在两种架构之间转换指令可能很困难/繁琐/不可能。

作为虚拟化器,QEMU使用主机上的硬件虚拟化来创建虚拟机。

无论你的需求是什么,QEMU都能做到!

接下来是如何让QEMU在Windows上工作。我可以直接在Windows PC上安装QEMU,但这需要手动配置和管理依赖项。我想要一个简单的按钮。我还想使用一个开源项目来完成这个任务。这就是MSYS2(https://www.msys2.org/)的用武之地。作为一个开源项目,MSYS2给了我想要的UNIX shell来设置QEMU,这更符合QEMU的设计。MSYS2自动处理依赖项,节省时间。此外,它有一种Arch Linux的感觉,并使用Pacman包管理器,所以加分!请注意,当你安装MSYS2时,会安装多个终端。在本文中,我们使用MSYS2 MinGW 64位shell。这个shell给了我们一个原生的Windows环境。

安装MSYS2就像下载安装程序并运行安装程序一样简单。一旦你安装了MSYS2,打开一个MSYS2终端,更新包数据库,并安装QEMU:

更新:

1
pacman -Syu

使用Pacman更新

安装:

1
pacman -S mingw-w64-x86_64-qemu

验证安装:

1
qemu-system-x86_64 --version

安装的QEMU版本9.1.0

太棒了——QEMU已经启动并运行了。接下来,下载你最喜欢的GNU Linux发行版(我想你可以使用Windows,也有BSD用户,但我们坚持使用GNU Linux)。我们为这个指南抓取一个64位Kali虚拟机镜像,这将给我们一个虚拟化环境。

下载Kali qcow2镜像

一旦你有了镜像,如果需要,可以创建一个快照。你很可能需要从一个以管理员身份打开的MYSYS2控制台运行这个命令:

1
qemu-img create -f qcow2 -F qcow2 -b "C:\path\to\image\kali-linux-2024.2-qemu-amd64.qcow2" "C:\path\to\snapshot\kali-snapshot.qcow2"

然后,运行这个命令将给你一个Kali VM。标志的描述在注释中提供:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
qemu-system-x86_64 \
        # 使用现代PC芯片组模型并启用Windows Hypervisor Platform
        -machine type=q35,accel=whpx \
        # 基本x86_64 CPU模型。
        -cpu qemu64 \
        # 给VM 2个CPU核心
        -smp 2 \
        # 4GB RAM
        -m 4G \
        # qcow2镜像的路径。MSYS2也接受这种格式:/c/Path/to/snapshot
        -drive file="C:\Path\to\your\kali-snapshot.qcow2",format=qcow2,if=virtio \
        # 使用virtuio GPU以提高性能
        -vga virtio \
        # 显示使用SDL
        -display sdl \
        # 设置此选项可改善鼠标性能和集成
        -device usb-tablet \
        # 给VM网络
        -netdev user,id=net0 \
        -device virtio-net-pci,netdev=net0

这是我用于提高性能的命令。你的体验会根据你的主机而有所不同。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
qemu-system-x86_64 \
    -name "Kali Qemu" \
    -machine type=q35,accel=whpx,kernel-irqchip=off \
    -cpu qemu64,hv_relaxed,hv_spinlocks=0x1fff,hv_vapic,hv_time \
    -smp cores=2,threads=1 \
    -m 4G \
    -drive file="C:\Path\to\your\kali-snapshot.qcow2",format=qcow2,if=virtio \
    -boot menu=on \
    -vga virtio \
    -display sdl,gl=off \
    -device usb-tablet \
    -usb \
    -device usb-ehci,id=ehci \
    -device nec-usb-xhci,id=xhci \
    -netdev user,id=net0 \
    -device virtio-net-pci,netdev=net0 \
    -audiodev id=audio1,driver=dsound \
    -device ich9-intel-hda \
    -device hda-output,audiodev=audio1 \
    -device virtio-balloon-pci \
    -monitor stdio

使用QEMU运行VM

我们有了一个使用QEMU的工作VM。

在QEMU中运行的Kali VM

预打包的VM配置为VMWare包,包括一个VDMK文件和VMWare配置文件(VMX)。没有可用的qcow2镜像。

VMWare文件

我们可以使用QEMU的磁盘映像工具将VDMK文件转换为qcow2文件。仅文件转换不会让你在QEMU中运行VM,因为它没有解决在VMX文件中定义的虚拟机配置。

1
qemu-img convert -f vmdk -O qcow2 /c/path/to/sof.vmdk /c/path/SOF-ELK.qcow2

将VDMK文件转换为qcow2

VMX文件可以用你选择的文本编辑器查看。我使用Emacs,我鼓励你也使用Emacs!我们想查看VMX配置,以确保在运行QEMU时匹配设置。

VMX文件的部分视图

在配置文件的下方,有一个对UEFI bios设置的引用。由于MSYS2使用Arch的Pacman包管理器,我们需要解决一个已知问题(https://bugs.archlinux.org/task/64175),即libvirt无法定位OVMF映像。OVMF是一个开源的UEFI固件实现,用于虚拟化环境,这是运行SOF-ELK所必需的。然而,当时使用Pacman时,Arch Linux使用的edk2-ovmf包不可用。

对于这个问题有许多变通方法——这是我的。在这个仓库:(https://www.kraxel.org/repos/jenkins/edk2/),我们可以抓取包含OVMF文件的x64 RPM。

包含OVMF RPM的仓库

一旦下载,我们需要提取RPM并访问打包在RPM中的文件。继续提取RPM文件,我使用bsdtar(https://man.archlinux.org/man/bsdtar.1)。在下面的例子中,文件保存在MSYS2路径中,而不是Windows路径。

提取RPM文件

随着RPM的提取,我们现在可以访问路径中的OVMF文件:/usr/share/edk2.git/ovmf-x64。OVMF文件是使用UEFI而不是BIOS启动VM所需的UEFI固件映像。OVMF文件可以通过fd扩展名识别。虽然有多个fd文件,但我使用了OVMF-pure-efi.fd映像,我将其移动到了我的工作目录。

OVMF-pure-efi.fd文件

现在我们有了一个UEFI启动解决方案,我们需要将我们的指令与虚拟机匹配,以匹配VMWare配置。下面的命令镜像了重要的VMWare配置值。注释显示了添加的指令以匹配VMX文件。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
qemu-system-x86_64 \
  -name "SOF-ELK" \
  -machine q35 \
  # 匹配AMD配置
  -cpu EPYC,hv_vendor_id=AuthenticAMD \
  # 匹配4个CPU核心
  -smp cores=4,threads=1,sockets=1 \
  # 来自VMX的内存
  -m 4096 \
  -drive file=SOF-ELK.qcow2,if=none,id=hd0,format=qcow2 \
  # VMX使用SATA且无法1:1匹配 – 提供兼容的磁盘接口
  -device ide-hd,drive=hd0,bus=ide.0 \
  -device vmxnet3,netdev=net0 \
  -netdev user,id=net0 \
  # 原始VMX文件中的USB支持
  -device usb-ehci \
  -device usb-tablet \
  # 设置原始VMX文件中的音频
  -device intel-hda \
  -device hda-duplex \
  # 模拟VMWare图形
  -vga vmware \
  -display gtk \
  # 设置启动顺序从硬盘开始 – 在VMX文件中设置
  -boot order=c,menu=on \
  # 使用UEFI固件的OVMF文件
  -bios "OVMF-pure-efi.fd" \
  # 使用主机本地时间 – VMWare处理时间的方式
  -rtc base=localtime,clock=host \
  -serial stdio
  # 设置VMX文件中定义的MAC地址
  -device vmxnet3,netdev=net0,mac=00:0c:29:ae:1b:b0 -netdev user,id=net0

运行命令给我们一个使用QEMU的SOF-ELK虚拟机!

在QEMU中运行的SOF-ELK

请记住,QEMU是高度可定制的,所以研究你的主机限制和要求,并充分利用这个用于机器虚拟化和模拟的开源替代方案。

在故障排除时,需要注意的几件事是:

1.)如果启用了Hyper-V,它将成为根超级管理程序。Hyper-V可能会减慢QEMU的速度,特别是在不使用Windows Hypervisor Platform(WHPX)加速器时。QEMU的默认加速器硬件加速执行管理器(HAXM)加速器在启用Hyper-V时不起作用。

2.)当将物理USB设备连接到你的VM时,你可能需要以管理员身份打开MSYS2终端。

3.)对于性能,定制你的QEMU命令以利用主机的CPU、GPU和内存。

5.)对于网络,virtio-net驱动程序提供更好的性能。与模拟网络适配器相比,Virtio-net驱动程序减少了开销,并且在使用多个核心时特别有用。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计