虛擬機器的 Linux 橋接器不會轉送 IP 封包(但轉送 ARP)

虛擬機器的 Linux 橋接器不會轉送 IP 封包(但轉送 ARP)

內核:5.5.8-arch1-1

我正在嘗試使用連接到我的實體介面的網橋來使虛擬網路正常工作。這是一個典型的設置,我什至沒有嘗試做任何事情詭異的

  • 橋:br0
  • 實體介面:enp6s0f0

問題在於 Linux 不會將任何 IP 流量轉送出實體介面。正在轉發ARP流量雙向,因為 ARP 解析有效,但沒有 IP 流量從 enp6s0f0 發出

我嘗試過的事情:

  • 新增enp6s0f1至網橋,提供enp7s0f0給虛擬機,並使用電纜連結enp7s0f0enp6s0f1
    • 相同的結果(轉送 ARP 流量,不轉送 IP 流量)
  • 停止 docker 並刷新所有表
    • 不用找了
  • 禁用 rp_filter
    • 不用找了
  • 使用板載 NIC
    • 沒有變化(這實際上是初始設置,我將這個四端口卡放入以查看板載網卡是否導致問題)
  • 從另一台機器 ping 虛擬機
    • 我可以看到回顯請求來了我可以看到它,br0但它沒有轉發到 VM 連接埠(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

碼頭工人負載br_netfilter模組(以獲得系統控制屬性net.bridge.bridge-nf-call-iptables=1)當它使用 iptables 時。這使得橋接的幀(以太網,第 2 層)受iptables過濾(IP,第 3 層):

什麼是橋接網路過濾器?

從Linux核心3.18-rc1開始,您必須modprobe br_netfilter才能啟用bridge-netfilter。

bridge-netfilter 程式碼啟用以下功能:

{Ip,Ip6,Arp}表可以過濾橋接的IPv4/IPv6/ARP封包,即使封裝在 802.1Q VLAN 或 PPPoE 標頭中也是如此。這啟用了狀態透明防火牆的功能。因此,這 3 個工具的所有過濾、日誌和 NAT 功能都可以在橋接幀上使用。因此,bridge-nf 程式碼與 ebtables 結合,使 Linux 成為一個非常強大的透明防火牆。這使得能夠創建透明的偽裝機(即所有本地主機都認為它們直接連接到互聯網)。 可以使用適當的過程條目停用或啟用讓 {ip,ip6,arp} 表查看橋接流量, 位於 /proc/sys/net/bridge/

  • bridge-nf-call-arptables

  • bridge-nf-call-iptables

  • bridge-nf-call-ip6tables

有文件解釋了該模組引起的副作用。這些副作用是故意的當用於橋接透明防火牆時。另外,iptables physdev(它br_netfilter在自身加載時加載)如果沒有它,則匹配就無法正常工作(它根本就不再匹配)。它還解釋瞭如何防止其影響,特別是在第7章

由於 br-nf 程式碼,幀/資料包可以透過 3 個給定的 iptables 鏈通過 2 種方式。第一種方式是當幀被橋接時,因此 iptables 鏈由橋接程式碼調用。第二種方式是當資料包被路由時。

而不是禁用調用iptablesbybr_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 模擬層,這是棄用它的一個進步

相關內容