我有一台运行容器和虚拟机的台式计算机(Ubuntu 19.10)。它的以太网enp2s0
与 systemd-networkd 桥接:
[Match]
Name=enp2s0
[Network]
Bridge=bridge
LinkLocalAddressing=no
桥接接口的名称准确bridge
,显示时有 IP 地址ip a
,例如192.168.1.2/24
。它还有一个wlp3s0
带 IP 地址的无线接口192.168.5.2/24
和一个 OpenVPNovpn
接口10.0.1.2/24
。
我的容器和虚拟机在内部网桥下运行,virbr0
主机的地址为172.17.0.1/16
。奇怪的是,没有容器或虚拟机可以到达主机接口外部的网络bridge
,但它们都可以从主机接口wlp3s0
(例如192.168.5.1
)和ovpn
(例如10.0.1.1
)到达任何东西。
我尝试从虚拟机 ping 不同位置并观察主机上的数据包。
root@iBug-Server:~# tcpdump -leni bridge icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on bridge, link-type EN10MB (Ethernet), capture size 262144 bytes
00:05:36.068658 86:80:93:9a:83:87 > d8:67:d9:70:e9:41, ethertype IPv4 (0x0800), length 98: 192.168.1.2 > 192.168.1.1: ICMP echo request, id 6227, seq 1, length 64
00:05:36.068902 d8:67:d9:70:e9:41 > 86:80:93:9a:83:87, ethertype IPv4 (0x0800), length 98: 192.168.1.1 > 192.168.1.2: ICMP echo reply, id 6227, seq 1, length 64
00:05:36.068930 86:80:93:9a:83:87 > d8:67:d9:70:e9:41, ethertype IPv4 (0x0800), length 98: 192.168.1.1 > 172.17.2.120: ICMP echo reply, id 6227, seq 1, length 64
^C
3 packets captured
3 packets received by filter
0 packets dropped by kernel
root@iBug-Server:~# tcpdump -leni wlp3s0 icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on wlp3s0, link-type EN10MB (Ethernet), capture size 262144 bytes
00:06:29.306316 12:04:21:2d:39:18 > 74:f8:db:6a:3e:d1, ethertype IPv4 (0x0800), length 98: 192.168.5.2 > 192.168.5.1: ICMP echo request, id 6231, seq 1, length 64
00:06:29.317283 74:f8:db:6a:3e:d1 > 12:04:21:2d:39:18, ethertype IPv4 (0x0800), length 98: 192.168.5.1 > 192.168.5.2: ICMP echo reply, id 6231, seq 1, length 64
^C
2 packets captured
2 packets received by filter
0 packets dropped by kernel
root@iBug-Server:~# tcpdump -leni enp2s0 icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on enp2s0, link-type EN10MB (Ethernet), capture size 262144 bytes
00:09:12.098863 86:80:93:9a:83:87 > d8:67:d9:70:e9:41, ethertype IPv4 (0x0800), length 98: 192.168.1.2 > 192.168.1.1: ICMP echo request, id 6232, seq 1, length 64
00:09:12.099100 d8:67:d9:70:e9:41 > 86:80:93:9a:83:87, ethertype IPv4 (0x0800), length 98: 192.168.1.1 > 192.168.1.2: ICMP echo reply, id 6232, seq 1, length 64
00:09:12.099145 86:80:93:9a:83:87 > d8:67:d9:70:e9:41, ethertype IPv4 (0x0800), length 98: 192.168.1.1 > 172.17.2.120: ICMP echo reply, id 6232, seq 1, length 64
^C
3 packets captured
3 packets received by filter
0 packets dropped by kernel
如上所示,来自bridge
或的第 3 个数据包enp2s0
似乎发往错误的地方(它应该是virbr0
),并且 MAC 地址也错误。以下是 的结果virbr0
。请注意,在 ping 时没有出现 ICMP 回复192.168.1.1
(主机bridge
接口的网关)。
root@iBug-Server:~# tcpdump -leni virbr0 icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on virbr0, link-type EN10MB (Ethernet), capture size 262144 bytes
00:21:49.815124 00:16:3e:03:1a:f8 > 52:b4:4b:3f:45:e2, ethertype IPv4 (0x0800), length 98: 172.17.2.120 > 192.168.1.1: ICMP echo request, id 6238, seq 1, length 64
^C
1 packet captured
1 packet received by filter
0 packets dropped by kernel
root@iBug-Server:~# tcpdump -leni virbr0 icmp
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on virbr0, link-type EN10MB (Ethernet), capture size 262144 bytes
00:21:59.268210 00:16:3e:03:1a:f8 > 52:b4:4b:3f:45:e2, ethertype IPv4 (0x0800), length 98: 172.17.2.120 > 192.168.5.1: ICMP echo request, id 6239, seq 1, length 64
00:21:59.277884 52:b4:4b:3f:45:e2 > 00:16:3e:03:1a:f8, ethertype IPv4 (0x0800), length 98: 192.168.5.1 > 172.17.2.120: ICMP echo reply, id 6239, seq 1, length 64
^C
2 packets captured
2 packets received by filter
0 packets dropped by kernel
nat
我的 iptables 有一个空的 FORWARD 链,策略为 ACCEPT,我在设置 KVM(使用 libvirt)后没有动过这个表。这里出了什么问题,我该如何修复?
答案1
我真是太蠢了!
我想确保来自以太网接口的数据包以相同的方式返回,因此我在启动脚本中加入了以下几行:
ip rule add dev bridge table 1
ip route add table 1 default via 192.168.1.1 dev bridge
这导致 NAT 的 ICMP 回复数据包返回到bridge
接口。
为了解决这个问题,从主表复制所有必要的内容:
ip route add table 1 192.168.5.0/24 dev wlp3s0
ip route add table 1 172.17.0.0/16 dev virbr0
... and so on