QEMU 四种网络模式对比与选择指南
QEMU 网络总览
QEMU 支持四种主要网络模式,从最简单到最复杂:
| 模式 | 复杂度 | Guest 上网 | 宿主机访问 Guest | 多虚拟机互通 | 典型场景 |
|---|---|---|---|---|---|
| User mode | ⭐ | ✅ | ❌(需端口转发) | ❌ | 快速测试、单机 |
| SLIRP | ⭐ | ✅ | 有限 | ❌ | macOS/Windows 上的替代 |
| NAT(iptables) | ⭐⭐ | ✅ | ✅ | ✅ | 生产环境、Linux |
| TAP + Bridge | ⭐⭐⭐ | ✅ | ✅ | ✅ | 实验室、多虚拟机集群 |
最常用的是 User mode(简单)和 TAP + Bridge(完整)。
User Mode:零配置最简单
QEMU 的默认网络。不需要 root 权限,不需要任何宿主机配置。
原理
QEMU 实现了一个轻量的 TCP/IP 栈,作为 Guest 的 NAT 网关。Guest 通过这个栈访问外部网络。但这个栈不暴露给宿主的网络栈——宿主看不到 Guest 的 IP。
Guest (10.0.2.15) → QEMU user-mode stack → 宿主网络 → 外网
启用
# 最简:加一个 user 模式网卡
qemu-system-x86_64 -nic user ...
# 指定 IP 池
qemu-system-x86_64 \
-netdev user,id=n0,net=192.168.50.0/24 \
-device virtio-net-pci,netdev=n0
Guest 默认 IP 是 10.0.2.15,网关是 10.0.2.2(QEMU user-mode 栈)。
端口转发
User mode 默认宿主无法直接访问 Guest 里的服务。需要显式配置端口转发:
# 把宿主 2222 端口转发到 Guest 的 22 端口(SSH)
qemu-system-x86_64 \
-nic user,hostfwd=tcp::2222-:22 \
...
# 多个端口转发
qemu-system-x86_64 \
-nic user,\
hostfwd=tcp::2222-:22,\
hostfwd=tcp::8080-:80,\
hostfwd=tcp::4443-:443 \
...
宿主访问:
# SSH 到 Guest
ssh -p 2222 user@localhost
# 访问 Guest 的 Web 服务
curl http://localhost:8080
限制
- 宿主无法 ping 通 Guest(ICMP 在 user mode 不工作)
- 多 Guest 之间不能直接互通
- 性能中等(比 TAP 慢)
- 某些网络应用(FTP 主动模式、多播、广播)会有问题
User mode 适合:快速测试、单机开发、不需要多虚拟机互通的场景。
SLIRP:macOS/Windows 上的替代
macOS 和 Windows 上的 user mode 有时不够稳定,SLIRP 是替代品。原理类似(NAT 网关),但实现更完整。
# macOS/Windows 上用 SLIRP
qemu-system-x86_64 \
-netdev slirp,id=n0 \
-device virtio-net-pci,netdev=n0
需要在编译 QEMU 时启用 --enable-slirp。Homebrew 的 QEMU 已经带了。
NAT + iptables:Linux 上的高级选择
Linux 上可以用 iptables 实现 NAT,让宿主和 Guest 互通:
# 开启 IP 转发
echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward
# iptables NAT 规则
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
sudo iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
Guest 网卡用 TAP 设备(见下一节),再通过 iptables NAT 出去。
TAP + Bridge:完整桥接模式
原理
在宿主上创建一个虚拟桥接设备,把 TAP 网卡和宿主物理网卡都挂到桥上。Guest 会获得和宿主同网段的 IP,就像物理机器直接插在网络里。
宿主物理网卡 eth0 ──┐
├── br0(虚拟桥)── TAP ── Guest
其他虚拟机 TAP ──────┘
配置步骤(Linux)
# 1. 创建桥接网卡 br0
sudo ip link add br0 type bridge
sudo ip link set br0 up
# 2. 把物理网卡 eth0 加到桥上(注意:如果远程操作会断连!)
sudo ip link set eth0 master br0
sudo ip link set eth0 up
# 3. 给桥加 IP
sudo ip addr add 192.168.1.100/24 dev br0
sudo ip link set br0 up
# 4. 启动 QEMU 时指定 TAP
qemu-system-x86_64 \
-netdev tap,id=n0,ifname=tap0,script=no,downscript=no \
-device virtio-net-pci,netdev=n0
也可以用 qemu-system-x86_64 -net nic,model=virtio-net-pci -net tap 旧语法。
Guest 侧
Guest 里配置和宿主同网段的 IP(DHCP 或手动):
# Guest 里用 DHCP
sudo dhclient ens3
# 或手动配置
sudo ip addr add 192.168.1.200/24 dev ens3
sudo ip route add default via 192.168.1.1
限制与注意事项
- 需要 root 权限创建 TAP 设备
- 远程操作配置桥接时小心:把物理网卡加到桥上会断 SSH!建议用
virsh或写好脚本 - WiFi 网卡通常不支持桥接(AP 隔离限制)
- 宿主上需要安装
bridge-utils(Debian/Ubuntu)或已内置 iproute2(新系统)
TAP + Bridge 适合:实验室环境、多虚拟机集群、需要虚拟机和物理机在同一网段的场景。
virt-manager 的网络配置
用 virt-manager 启动的虚拟机默认有 default 网络——这是 libvirt 管理的 NAT 网络。图形界面里可以轻松切换桥接模式。
# 查看 libvirt 网络
virsh net-list --all
# 创建桥接网络
virsh net-define bridge-net.xml
virsh net-start bridge-net
virsh net-autostart bridge-net
libvirt + virt-manager 组合是生产环境最常用的方案——它封装了 TAP、iptables、DHCP 等底层细节。
选择建议
| 场景 | 推荐 |
|---|---|
| 快速测试、单机开发 | User mode + 端口转发 |
| macOS / Windows | SLIRP(或直接 -accel whpx/hvf + 默认) |
| Linux 上生产 / 多虚拟机 | libvirt + virt-manager + NAT 或桥接 |
| 实验室 / 同网段互通 | TAP + Bridge |
下一步
网络搞通了,去 跨架构模拟 看看 QEMU 真正独特的能力——在 x86 主机上跑 ARM 和 RISC-V。