У меня есть настольный компьютер (Ubuntu 19.10) с контейнерами и виртуальными машинами. Его Ethernet 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
и интерфейс OpenVPN ovpn
в 10.0.1.2/24
.
Мои контейнеры и виртуальные машины работают под внутренним мостом virbr0
где хост имеет адрес 172.17.0.1/16
. Странно то, что ни один контейнер или виртуальная машина не могут получить доступ к сети за пределами интерфейса хоста. bridge
, но все они могут получить доступ к чему угодно с хост-интерфейсов wlp3s0
(например. 192.168.5.1
) и ovpn
(например. 10.0.1.1
).
Я пробовал пинговать разные места с виртуальной машины и смотреть пакеты на хосте.
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
Как видно выше, 3-й пакет от bridge
или enp2s0
похоже, идет не в то место (это должно было быть virbr0
), а также неправильные MAC-адреса. Вот результаты virbr0
. Обратите внимание, как ответ 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
В моем iptables есть пустая цепочка FORWARD с политикой ACCEPT, и я не трогал nat
таблица после настройки KVM (с libvirt). Что здесь не так и как это исправить?
Так глупо с моей стороны!
Я хотел убедиться, что пакеты, поступающие из интерфейса Ethernet, возвращаются таким же образом, поэтому в моих сценариях запуска были следующие строки:
ip rule add dev bridge table 1
ip route add table 1 default via 192.168.1.1 dev bridge
Это приводит к тому, что ответный пакет ICMP с NAT возвращается к 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