我正在使用 QEMU(和 KVM)在 Debian 9 上设置虚拟机。我目前正在尝试使其通过桥接网络工作,我已经使用等设置了该网络ip link
;ip tuntap
这是输出brctl show
:
bridge name bridge id STP enabled interfaces
br0 8000.107b444f55d6 no enp4s0
tap0
docker0 8000.0242d4c18983 no
这是输出ip a
:
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: enp4s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UP group default qlen 1000
link/ether 10:7b:44:4f:55:d6 brd ff:ff:ff:ff:ff:ff
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:d4:c1:89:83 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
4: tap0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc pfifo_fast master br0 state DOWN group default qlen 1000
link/ether f6:54:bb:db:d7:c6 brd ff:ff:ff:ff:ff:ff
inet6 fe80::f454:bbff:fedb:d7c6/64 scope link
valid_lft forever preferred_lft forever
5: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 10:7b:44:4f:55:d6 brd ff:ff:ff:ff:ff:ff
inet 192.168.0.26/24 brd 192.168.0.255 scope global br0
valid_lft forever preferred_lft forever
inet6 fe80::127b:44ff:fe4f:55d6/64 scope link
valid_lft forever preferred_lft forever
接口docker0
无关。
据我所知,这应该有效。但是,我在 QEMU 中的 Windows 8.1 客户机无法访问互联网,并且无法通过 DHCP 获取 IP(我只是获取自动生成的 169.xx.xx.xx IP)。
我不确定这是为什么。我的 QEMU 参数是:
-net nic -net tap,ifname=tap0
我也尝试过:
-device e1000,netdev=net0,mac=52:55:00:d1:55:01 -netdev tap,id=net0
这两者都会产生相同的结果,即没有网络访问。我无法弄清楚这一点。
我是不是在做蠢事?
答案1
我刚刚在 QEMU Linux guest 上遇到了非常类似的问题,结果发现 iptables 阻止了流量。如果我为访客设置静态 IP 地址,则主机和访客可以互相 ping 通,但仅此而已。无法从访客计算机访问互联网和我的网络的其余部分。
我强烈建议您使用 Wireshark 或 tcpdump 等工具来调查问题。
我已经使用 Wireshark 从主机捕获了桥接口,看起来请求是从虚拟机发出的,但没有收到响应。
TL;DR:这条线索让我在以下答案中找到了神奇的 iptable 命令(这对我来说很神奇,因为我对 iptables 的经验还不够:)):
https://serverfault.com/a/165786
它起作用了,即使我此刻还不完全理解它,我想我会把我的两分钱留在这里。
祝你好运!
答案2
我目前也在为这个问题而苦苦挣扎。我比你更接近解决方案。
我使用的是 Debian 10,我决定只使用软件包iproute2
(ip link
、ip addr
、bridge link
...),它是内核的一部分,并且可以在任何 Linux 上使用。和包qemu-kvm
。这就是您所需要的一切。
步骤1
打开第一航站楼并将其写下来,以便您能够看到您的进度:
while true; do ip addr; sleep 1; clear; done
第2步
打开第二航站楼并在查看进度时执行这些命令第一航站楼:
sudo ip link add virtual_bridge type bridge
sudo ip link set virtual_bridge up
你有一座桥,那就是up
。
在继续之前只是一个实验
您virtual_bridge
现在是up
,但您的以太网卡可能是up
或down
。现在阅读我通过反复试验找出的这两个场景。这是非常重要的(!)这样您就会了解以太网卡的反应。您可能会尝试或不尝试,但我建议您在观看时完全按照下面的描述进行操作第一航站楼进行更改。
场景一:
如果您的以太网卡down
尝试使用以下命令为其分配主设备。它将起作用:
sudo ip link set enx24f5a2f17b27 master virtual_bridge
现在打开它:
sudo ip link set enx24f5a2f17b27 up
您会惊讶地发现该卡无法将您连接到互联网。即使重新启动它也不会成功:
sudo ip link set enx24f5a2f17b27 down
sudo ip link set enx24f5a2f17b27 up
即使您重新启动应该控制它的卡主人的桥也不会:
sudo ip link set virtual_bridge down
sudo ip link set virtual_bridge up
我设法让它连接到互联网的唯一方法是重新启动卡,删除主卡,刷新它以删除所有IP(也许这个不需要),手动分配一个已知且工作的IP,然后分配master:
sudo ip link set enx24f5a2f17b27 down
sudo ip link set enx24f5a2f17b27 up
sudo ip addr flush enx24f5a2f17b27
sudo ip addr add 192.168.64.100/24 dev enx24f5a2f17b27
sudo ip link set enx24f5a2f17b27 master virtual_bridge
此时互联网应该开始工作。
场景B:
如果您的以太网卡up
可能有一个 IP,并且您的互联网必须正常工作。所以现在尝试使用下面的命令为其分配一个主机。它会起作用的!
sudo ip link set enx24f5a2f17b27 master virtual_bridge
现在多次重置桥并注意卡会发生什么:
sudo ip link set virtual_bridge down
sudo ip link set virtual_bridge up
sudo ip link set virtual_bridge down
sudo ip link set virtual_bridge up
您将看到,每当您启用桥接以太网卡时,它也会被启用,它将获取 IP 并连接到互联网。但是一旦你关闭该卡:
sudo ip link set enx24f5a2f17b27 down
无论您重置网桥多少次,它都无法重新连接到互联网。
所以这就是为什么最重要的是你第一的打开以太网卡并第二指定它为主,而不是相反!换句话说,当您分配主控时,应该启用卡。
步骤3
正如我们从上面的例子中了解到的,我们首先(!)打开以太网卡,它将获得 IP:
sudo ip link set enx24f5a2f17b27 up
然后我们给它指定一个 master:
sudo ip link set enx24f5a2f17b27 master virtual_bridge
我们创建一个 TAP 设备,它就像虚拟机的虚拟以太网卡。这很重要(!)您为其分配 auser
和 a group
,因为否则它可能没有适当的权限:
sudo ip tuntap add virtual_tap mode tap user ziga group ziga
现在你已经创建了它,你可以尝试启用它,但你不会成功,因为只有虚拟机可以做到这一点:
sudo ip link set virtual_tap up
所以它将保持在该down
状态。只需将 master 也应用到它上面即可:
sudo ip link set virtual_tap master virtual_bridge
这样您就完成了网络设置。请注意,此时您的 TAP 设备将没有 IP。当您启动虚拟机并等待虚拟机自行设置时,它将分配给它。
步骤4
现在是时候正确启动虚拟机了。我用最新的来做-nic
,该命令更短且功能更强大(!)比旧命令(读)。无论如何......我使用这个命令:
qemu-system-x86_64 -enable-kvm -cpu host -smp cores=3,threads=1 -m 4096 -nic tap,ifname=virtual_tap,script=no,downscript=no -boot order=c -cdrom ~/Dropbox/workspace/racunalnistvo/programi/kvm/iso/centos-8.1.1911-x86_64-dvd1.iso -drive file=~/Dropbox/workspace/racunalnistvo/programi/kvm/vm/windows.qcow2,format=qcow2
如果您省略选项
script=no
,downscript=no
上述命令将返回无害的警告:RTNETLINK answers: Operation not permitted W: /etc/qemu-ifup: no bridge for guest interface found
发生这种情况是因为在仿真之前,Qemu 尝试使用脚本自动设置它自己的桥接和 TAP
/etc/qemu-ifup
。脚本完成后,它还会尝试删除桥接和 TAP/etc/qemu-ifdown
。如果您查看这些脚本,您会发现它们使用的命令brctl
是bridge-utils
我未安装的包的一部分,并且脚本失败!无论如何,我们手动创建了桥接和 TAP 设备,因此我们不需要这些脚本,并且我们阻止 Qemu 使用
script=no
和 调用它们downscript=no
。
iproute2
重写这些脚本来使用而不是很有趣,bridge-utils
但是您需要root
特权来运行它们,并且专家不建议我们将虚拟机运行为root
.
虚拟机将启动,连接到互联网,但无法 ping 通主机!此外,主机将能够连接到互联网并能够 ping 通同一网关。但它无法 ping 通虚拟机!
还要注意第一航站楼您将在其中看到 TAP 设备现已启用并且它获得了一个 IP,但这里的这个 IP 与您在虚拟机内部看到的 IP 不同!谁能解释一下吗?
去做
这就是我能弄清楚的,我希望它对某人有所帮助。我仍然不知道为什么主机和虚拟机无法互相 ping 通,因为 TAP 设备应该启用 TCP、UDP 和 ICMP...我怀疑这是因为我必须以某种方式将 IP 分配给网桥(读,读)但我不知道如何选择合适的。有人可以帮忙评论一下吗?