在 macos 创建 QEMU 桥接网络

2022-10-15 ⏳1.5分钟(0.6千字) 🕸️

今天记录一下如何在 macos 上为 QEMU 虚拟机创建桥接网络。

QEMU 默认创建的虚拟网卡使用 user 模式。虚拟机可以正常跟外界通信,宿主机无法直接访问虚拟机。

如果想让外界直接访问虚拟机,最简单的办法是建桥接网络。目前网上的内容多数是利用 tap 模式。但是 macos 不支持 tap 设备,需要依赖第三方的 TunTap 项目。又因为新版 macos 已经弃用内核扩展,所以 TunTap 项目也就不再继续开发。

难道就不没有解决办法了吗?有。macos 从 10.10 Yosemite 开始提供 Hypervisor.framework,这是 BSD 内核原生的虚拟化框架,有点类似 Linux 的 KVM 模块。Hypervisor.framework 支持为虚拟机创建桥接网络。QEMU 大约在 2021 年年底开始支持 Hypervisor.framework,可以参考这里

完整启动命令如下:

sudo qemu-system-x86_64 path/to/disk \
         -M accel=hvf \
	 -cpu host -smp cpus=8 -m 256 \
	 -nic vmnet-bridged,ifname=en0

其中-M accel=hvf指定使用 Hypervisor.framework 框架,只在 macos 平台有效。再下面一行是设置为 cpu 核数以及内存大小。再下面的-nic vmnet-bridged,ifname=en0 是指定创建桥接网络。ifname指定就是需要桥接的网卡。

我的无线网卡是 en0,所以上面的命令会把虚拟机的网卡跟 macos 的无线网卡桥接起来。虚拟机启动后就能分配到跟宿主机相同的网段的 IP 地址,而且同时支持 IPv6 网络。

QEMU 有两个参数,分别是 netdev 和 nic。理论上先通过 nic 指定网卡类型,然后再通过 netdev 详细指定网卡的其他参数。但我实验发现使用 netdev 不成功,反而可以直接使用 nic 参数。

完整的参数结构如下:

-netdev vmnet-bridged,id=str,ifname=name[,isolated=on|off]
                configure a vmnet network backend in bridged mode with ID 'str',
                use 'ifname=name' to select a physical network interface to be bridged,
                isolate this interface from others with 'isolated'
-nic [tap|bridge|user|vde|vhost-user|vmnet-host|vmnet-shared|vmnet-bridged|socket][,option][,...][mac=macaddr]
                initialize an on-board / default host NIC (using MAC address
                macaddr) and connect it to the given host network backend

如果仅指定 netdev 参数会报 qemu-system-x86_64: warning: netdev bridge1 has no peer 如果仅指定 -nic bridge 参数会报错 qemu-system-x86_64: -nic vmnet-bridged: Parameter ‘ifname’ is missing

所以我们就直接使用 -nic vmnet-bridged,ifname=en0 吧😄

QEMU 还支持另外两种网络模式:

这两种都不如桥接来的方便,就不详细介绍了。