Linux-мост для виртуальных машин не пересылает IP-пакеты (но пересылает ARP)

Linux-мост для виртуальных машин не пересылает IP-пакеты (но пересылает ARP)

Ядро: 5.5.8-arch1-1

Я пытаюсь заставить работать виртуальную сеть, используя мост, подключенный к моему физическому интерфейсу. Это типичная настройка, я даже не пытаюсь ничего делатьстранный.

  • Мост:br0
  • Физический интерфейс:enp6s0f0

Проблема в том, что Linux не пересылает IP-трафик из физического интерфейса. Он пересылаетARP-трафикв обоих направлениях, так как разрешение ARP работает, но IP-трафик не проходитотправлено из enp6s0f0.

Что я пробовал:

  • добавление enp6s0f1к мосту, предоставление enp7s0f0виртуальной машине и использование кабеля для подключения enp7s0f0кenp6s0f1
    • тот же результат (ARP-трафик пересылается, IP-трафик — нет)
  • остановка докера и очистка всех таблиц
    • без изменений
  • отключение rp_filter
    • без изменений
  • с использованием встроенной сетевой карты
    • никаких изменений (на самом деле это была первоначальная настройка, и я вставил эту четырехпортовую карту, чтобы проверить, не вызывает ли проблема встроенная сетевая карта)
  • пингование виртуальной машины с другой машины
    • Я мог видеть, как пришел эхо-запросви я мог видеть его, br0но он не был перенаправлен на порт виртуальной машины (ни порт vnet, ни enp6s0f1)
  • включение STP на мосту (изначально он был отключен)
    • без изменений
○ → ip addr
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: enp6s0f0: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc mq master br0 state UP group default qlen 1000
    link/ether 00:10:18:85:1c:c0 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::210:18ff:fe85:1cc0/64 scope link 
       valid_lft forever preferred_lft forever
3: enp6s0f1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 00:10:18:85:1c:c2 brd ff:ff:ff:ff:ff:ff
4: enp7s0f0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 00:10:18:85:1c:c4 brd ff:ff:ff:ff:ff:ff
5: enp7s0f1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 00:10:18:85:1c:c6 brd ff:ff:ff:ff:ff:ff
6: enp9s0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether b4:2e:99:a6:22:f9 brd ff:ff:ff:ff:ff:ff
7: wlp8s0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 08:71:90:4e:e9:77 brd ff:ff:ff:ff:ff:ff
8: br-183e1a17d7f6: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 02:42:ba:03:e1:9d brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.1/16 brd 172.18.255.255 scope global br-183e1a17d7f6
       valid_lft forever preferred_lft forever
9: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 02:42:02:61:00:66 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
10: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 00:10:18:85:1c:c0 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.205/24 brd 192.168.1.255 scope global dynamic noprefixroute br0
       valid_lft 9730sec preferred_lft 7930sec
    inet6 fe80::210:18ff:fe85:1cc0/64 scope link 
       valid_lft forever preferred_lft forever
11: vnet0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel master br0 state UNKNOWN group default qlen 1000
    link/ether fe:54:00:be:eb:3e brd ff:ff:ff:ff:ff:ff
    inet6 fe80::fc54:ff:febe:eb3e/64 scope link 
       valid_lft forever preferred_lft forever

○ → brctl showstp br0
br0
 bridge id      8000.001018851cc0
 designated root    1000.44e4d9d88a00
 root port         1            path cost          4
 max age          19.99         bridge max age        19.99
 hello time        1.99         bridge hello time      1.99
 forward delay        14.99         bridge forward delay      14.99
 ageing time         299.99
 hello timer           0.00         tcn timer          0.00
 topology change timer     0.00         gc timer          25.78
 flags          


enp6s0f0 (1)
 port id        8001            state            forwarding
 designated root    1000.44e4d9d88a00   path cost          4
 designated bridge  1000.44e4d9d88a00   message age timer     19.21
 designated port    800d            forward delay timer    0.00
 designated cost       0            hold timer         0.00
 flags          

vnet0 (2)
 port id        8002            state            forwarding
 designated root    1000.44e4d9d88a00   path cost        100
 designated bridge  8000.001018851cc0   message age timer      0.00
 designated port    8002            forward delay timer    0.00
 designated cost       4            hold timer         0.22
 flags          

○ → bridge -d link show
2: enp6s0f0: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 master br0 state forwarding priority 32 cost 4 
    hairpin off guard off root_block off fastleave off learning on flood on mcast_flood on mcast_to_unicast off neigh_suppress off vlan_tunnel off isolated off enp6s0f0
8: br-183e1a17d7f6: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 master br-183e1a17d7f6 br-183e1a17d7f6
9: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 master docker0 docker0
10: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master br0 br0
11: vnet0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 master br0 state forwarding priority 32 cost 100 
    hairpin off guard off root_block off fastleave off learning on flood on mcast_flood on mcast_to_unicast off neigh_suppress off vlan_tunnel off isolated off vnet0

○ → sysctl net.bridge.bridge-nf-call-iptables
net.bridge.bridge-nf-call-iptables = 1

○ → sysctl net.ipv4.conf.br0.forwarding
net.ipv4.conf.br0.forwarding = 1

решение1

Докернагрузки the br_netfilterмодуль (чтобы получитьsysctlсвойство net.bridge.bridge-nf-call-iptables=1) когда он использует iptables. Это делаетмостовойкадры (Ethernet, уровень 2) в зависимости отiptablesфильтрация (IP, уровень 3):

Что такое bridge-netfilter?

Начиная с ядра Linux 3.18-rc1, для включения bridge-netfilter необходимо modprobe br_netfilter.

Код bridge-netfilter обеспечивает следующие функции:

Таблицы {Ip,Ip6,Arp} могут фильтровать пакеты IPv4/IPv6/ARP, передаваемые по мосту, даже если инкапсулирован в заголовок 802.1Q VLAN или PPPoE. Это обеспечивает функциональность прозрачного брандмауэра с отслеживанием состояния. Все функции фильтрации, регистрации и NAT этих 3 инструментов могут использоваться в мостовых кадрах. В сочетании с ebtables код bridge-nf делает Linux очень мощным прозрачным брандмауэром. Это позволяет, например, создать прозрачную маскирующую машину (т. е. все локальные хосты думают, что они напрямую подключены к Интернету). Разрешение таблицам {ip,ip6,arp} видеть трафик моста можно отключить или включить с помощью соответствующих записей процедуры., находится в /proc/sys/net/bridge/:

  • bridge-nf-call-arptables

  • bridge-nf-call-iptables

  • bridge-nf-call-ip6tables

Есть документация, объясняющая побочные эффекты, вызванные этим модулем. Эти побочные эффектынамеревалсяпри использовании его для прозрачного брандмауэра моста. Также,iptables physdev(который загружается br_netfilter, когда сам загружается) match не может работать правильно без него (он просто больше не будет match). Также объясняется, как предотвратить его эффекты, особенно вглава 7:

Из-за кода br-nf существует 2 способа, которыми кадр/пакет может пройти через 3 указанные цепочки iptables.Первый способ — когда фрейм соединен мостом, то цепочки iptables вызываются кодом моста.. Второй способ — когда пакет маршрутизируется.

Вместо того, чтобы отключить вызовiptablesпо br_netfilterкоду вроде этого:

sysctl -w net.bridge.bridge-nf-call-iptables=0

нужно приспособитьсяiptablesправила, где бы они ни находились (включая сетевое пространство имен), как описано в главе 7, чтобы избежать побочных эффектов, например, добавляя правила приема в цепочку FORWARD, предназначенную не для маршрутизации, а для моста. Простое отключение его для устранения одной проблемы нарушит работу приложений, которые от него зависят, начиная с внутренней изоляции контейнера Docker.

До не давнего временив ядро 5.3этот модуль не был осведомлен о пространстве имен, и его загрузка внезапно включила его во всех сетевых пространствах имен, вызывая всевозможные проблемы, когда это было неожиданно. Также с тех пор стало возможным включать его для моста ( ip link set dev BRIDGE type bridge nf_call_iptables 1), а не для пространства имен.

После того, как инструменты (Docker...) и ядро ​​(>= 5.3) последуют эволюции, просто включить его в выбранных сетевых пространствах имен и мостах должно быть достаточно, но сегодня, вероятно, нет. Также обратите внимание, чтоядро 5.3также унаследовал собственный межсетевой экран с отслеживанием состояния моста, используемыйnftables, что является шагом к отказу от использования этого модуля (после того, как станет доступна поддержка прямой инкапсуляции/декапсуляции в мосту для VLAN и PPPoE):

Сетевой фильтр

Добавить собственную поддержку отслеживания соединений для моста. До этого патча единственным шансом для людей сделать фильтрацию с сохранением состояния было использование слоя эмуляции br_netfilter, это шаг вперед к его отмене

Связанный контент