我有一台使用 libvirt/qemu/kvm 创建的虚拟机,该虚拟机通过 TAP 连接到 Linux 桥 (virbr1)。虚拟机内部的 IP 为10.99.0.9
。并具有以下路由设置。
default via 10.99.0.1 dev enp1s0 proto static onlink
10.99.0.1 via 10.99.0.1 dev enp1s0 proto static onlink
此处 10.99.0.1 是网桥的 IP
我希望来自该虚拟机的所有流量都转到我设置的 VPN 路由 (wg0),因此在主机上我这样做了
ip route add default dev wg0 table 42
ip rule add from 10.99.0.9 table 42
这工作得很好,但我注意到在虚拟机内部我仍然可以 ping 主机 IP 192.168.2.1
。我最终意识到这是因为lookup local
ip 规则的优先级为 0,高于我添加的规则的优先级。我想我只需交换一下顺序,一切就都好了。
ip rule add preference 300 lookup local # 300 here is arbitrarily higher than 0
ip rule del preference 0
ip rule add from 10.99.0.9 table 42 preference 0
但是这样做之后,我现在无法在虚拟机内建立连接。如果我嗅探 Linux 桥,我会看到它不断发送 ARP 请求以查找谁拥有10.99.0.1
,并且没有得到任何响应。我认为这些路由决策根本不应该影响 ARP,因为它与 IP 一起起作用,所以这令人困惑。我已经确认正是这些行导致了问题
为什么 ARP 回复没有返回到 VM 接口?
答案1
我的印象是您的答案已在您的问题中提供。
您已将本地 IP 规则首选项从 0 更改为 300,因此将默认路由推为最优先路由:
ip route add default dev wg0 table 42
ip rule add from 10.99.0.9 table 42
#and lastly:
ip rule add from 10.99.0.9 table 42 preference 0
这导致内核只选择这条路由。
你说:“我看到它不断发送 ARP 请求,寻找谁拥有 10.99.0.1,但没有任何回应。”
这是合理的,因为 ARP 广播将发往wg0
没有设备具有10.99.0.1
IP 地址的接口(我假设)。
解决方案 ?
我的建议是不要弄乱路由优先级,如果需要的话,使用 iptables 阻断虚拟机不需要的访问。