Назад | Перейти на главную страницу

Пакеты Linux отправляются на странные интерфейсы при преобразовании через NAT между мостами

У меня есть настольный компьютер (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