Linux-Brücke für virtuelle Maschinen, die keine IP-Pakete weiterleitet (aber ARP weiterleitet)

Linux-Brücke für virtuelle Maschinen, die keine IP-Pakete weiterleitet (aber ARP weiterleitet)

Kernel: 5.5.8-arch1-1

Ich versuche, virtuelle Netzwerke über eine an meine physische Schnittstelle angeschlossene Brücke zum Laufen zu bringen. Dies ist ein typisches Setup, ich versuche nicht einmal, etwas zu tunseltsam.

  • Brücke:br0
  • Physische Schnittstelle:enp6s0f0

Das Problem ist, dass Linux keinen IP-Verkehr über die physische Schnittstelle weiterleitet. Es leitetARP-Verkehrin beide Richtungen, da die ARP-Auflösung funktioniert, aber kein IP-Verkehr ankommtgesendet von enp6s0f0.

Dinge, die ich versucht habe:

  • Hinzufügen enp6s0f1zur Brücke, Geben enp7s0f0an die VM und Verwenden eines Kabels zum Verbinden enp7s0f0mitenp6s0f1
    • gleiches Ergebnis (ARP-Verkehr weitergeleitet, IP-Verkehr nicht)
  • Docker stoppen und alle Tabellen leeren
    • Keine Änderung
  • rp_filter deaktivieren
    • Keine Änderung
  • mithilfe der integrierten Netzwerkkarte
    • keine Änderung (das war eigentlich die Ersteinrichtung und ich habe diese Quad-Port-Karte eingebaut, um zu sehen, ob die integrierte Netzwerkkarte ein Problem verursachte)
  • Pingen der VM von einem anderen Rechner aus
    • Ich konnte die Echo-Anfrage kommen sehenInund ich konnte es sehen, br0aber es wurde nicht an den VM-Port weitergeleitet (entweder den VNet-Port oder enp6s0f1)
  • Aktivieren von STP auf der Brücke (es war zunächst deaktiviert)
    • Keine Änderung
○ → 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

Antwort1

DockerLadungenDiebr_netfilterModul (um diesysctlproperty net.bridge.bridge-nf-call-iptables=1), wenn iptables verwendet wird. Dies machtüberbrücktFrames (Ethernet, Schicht 2) unterliegeniptablesFilterung (IP, Schicht 3):

Was ist Bridge-Netfilter?

Seit dem Linux-Kernel 3.18-rc1 müssen Sie modprobe br_netfilter ausführen, um Bridge-Netfilter zu aktivieren.

Der Bridge-Netfilter-Code ermöglicht die folgende Funktionalität:

{Ip,Ip6,Arp}-Tabellen können überbrückte IPv4/IPv6/ARP-Pakete filtern, selbst wenn es in einem 802.1Q VLAN- oder PPPoE-Header gekapselt ist. Dies ermöglicht die Funktionalität einer Stateful Transparent Firewall. Alle Filter-, Protokollierungs- und NAT-Funktionen der drei Tools können daher auf überbrückte Frames verwendet werden. In Kombination mit ebtables macht der Bridge-NF-Code Linux daher zu einer sehr leistungsstarken transparenten Firewall. Dies ermöglicht beispielsweise die Erstellung einer transparenten Masquerading-Maschine (d. h. alle lokalen Hosts denken, sie seien direkt mit dem Internet verbunden). Die Möglichkeit, {ip,ip6,arp}-Tabellen den überbrückten Datenverkehr anzeigen zu lassen, kann mit den entsprechenden Proc-Einträgen deaktiviert oder aktiviert werden., gelegen in /proc/sys/net/bridge/:

  • bridge-nf-call-arptables

  • bridge-nf-call-iptables

  • bridge-nf-call-ip6tables

Es gibt eine Dokumentation, die die Nebenwirkungen dieses Moduls erklärt. Diese Nebenwirkungen sindbeabsichtigtwenn es für Bridge Transparent Firewalling verwendet wird. Außerdem ist dieiptables physdev(das geladen wird br_netfilter, wenn es selbst geladen wird) kann match ohne es nicht richtig funktionieren (es wird einfach nicht mehr übereinstimmen). Es wird auch erklärt, wie man seine Auswirkungen verhindern kann, insbesondere inKapitel 7:

Aufgrund des br-nf-Codes gibt es zwei Möglichkeiten, wie ein Frame/Paket die drei angegebenen iptables-Ketten durchlaufen kann.Die erste Möglichkeit ist, wenn der Frame überbrückt wird, so dass die iptables-Ketten durch den Bridge-Code aufgerufen werdenDie zweite Möglichkeit ist die Weiterleitung des Pakets.

Anstatt den Anruf zu deaktivieren,iptablesdurch br_netfilterden Code wie folgt:

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

man sollte sich anpasseniptablesRegeln, wo immer sie sind (einschließlich des Netzwerk-Namespaces), wie in Kapitel 7 erläutert, um Nebeneffekte zu vermeiden, indem beispielsweise Akzeptanzregeln in der FORWARD-Kette hinzugefügt werden, die nicht für das Routing, sondern für das Bridging vorgesehen sind. Das einfache Deaktivieren, um ein Problem zu beheben, stört die Anwendungen, die davon abhängen, angefangen bei der internen Containerisolierung von Docker.

Bis vor kurzemIn Kernel 5.3Dieses Modul war nicht namespace-bewusst und wurde durch das Laden plötzlich in allen Netzwerk-Namespaces aktiviert, was unerwarteterweise alle möglichen Probleme verursachte. Seitdem ist es auch möglich, es pro Bridge ( ip link set dev BRIDGE type bridge nf_call_iptables 1) statt pro Namespace zu aktivieren.

Sobald Tools (Docker...) und Kernel (>= 5.3) der Entwicklung folgen, sollte es ausreichen, es einfach in ausgewählten Netzwerk-Namespaces und Bridges zu aktivieren, aber heute wahrscheinlich nicht mehr. Beachten Sie auch, dassKernel 5.3auch geerbtes natives Bridge Stateful Firewalling, nutzbar durchNftables, was ein Schritt ist, um die Verwendung dieses Moduls überflüssig zu machen (sobald direkte Kapselungs-/Entkapselungsunterstützung in der Bridge für VLAN und PPPoE verfügbar ist):

Netzfilter

Fügen Sie native Verbindungsverfolgungsunterstützung für die Bridge hinzu. Vor diesem Patchset bestand die einzige Möglichkeit für Benutzer, Stateful Filtering durchzuführen, darin, die br_netfilter-Emulationsschicht zu verwenden. Dies ist ein Schritt nach vorne, um diese zu verwerfen.

verwandte Informationen