仮想マシン用の Linux ブリッジが IP パケットを転送しない (ただし ARP は転送する)

仮想マシン用の Linux ブリッジが IP パケットを転送しない (ただし ARP は転送する)

カーネル: 5.5.8-arch1-1

物理インターフェースに接続されたブリッジを使用して仮想ネットワークを動作させようとしています。これは典型的な設定であり、何もしようとしていません。奇妙な

  • 橋:br0
  • 物理インターフェース:enp6s0f0

問題は、Linuxが物理インターフェースからIPトラフィックを転送していないことです。ARPトラフィックARP解決は機能するが、IPトラフィックは通過しないため、双方向でenp6s0f0から送信

私が試したこと:

  • enp6s0f1ブリッジに追加し、 enp7s0f0VMに渡し、ケーブルを使用してリンクenp7s0f0するenp6s0f1
    • 同じ結果(ARP トラフィックは転送されるが、IP トラフィックは転送されない)
  • dockerを停止し、すべてのテーブルをフラッシュする
    • 変化なし
  • rp_filterを無効にする
    • 変化なし
  • オンボードNICを使用する
    • 変化なし (これは実際には初期設定であり、オンボード NIC が問題の原因かどうかを確認するためにこのクアッド ポート カードを挿入しました)
  • 別のマシンからVMに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モジュール(sysctlnet.bridge.bridge-nf-call-iptables=1iptablesを使用する場合、プロパティを使用します。これにより、橋渡しされたフレーム(イーサネット、レイヤー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 ヘッダーにカプセル化されている場合でも、ブリッジ フレームは透過的に機能します。これにより、ステートフル透過ファイアウォールの機能が有効になります。したがって、3 つのツールのすべてのフィルタリング、ログ記録、および NAT 機能は、ブリッジ フレームで使用できます。したがって、bridge-nf コードは、ebtables と組み合わせることで、Linux を非常に強力な透過ファイアウォールにします。これにより、たとえば、透過的なマスカレード マシン (つまり、すべてのローカル ホストがインターネットに直接接続されていると考える) の作成が可能になります。 {ip,ip6,arp}テーブルがブリッジされたトラフィックを見ることができるようにすることは、適切なprocエントリを使用して無効または有効にすることができます。、 にあります /proc/sys/net/bridge/

  • bridge-nf-call-arptables

  • bridge-nf-call-iptables

  • bridge-nf-call-ip6tables

このモジュールによって生じる副作用を説明するドキュメントがあります。それらの副作用は意図されましたブリッジ透過ファイアウォールに使用する場合。また、iptables physdevbr_netfilterそれ自体がロードされるとロードされます)マッチはそれなしでは正しく動作しません(単にマッチしなくなります)。また、特に第7章:

br-nf コードにより、フレーム/パケットが 3 つの iptables チェーンを通過する方法は 2 つあります。最初の方法はフレームがブリッジされるときであり、iptablesチェーンはブリッジコードによって呼び出されます。2 番目の方法は、パケットがルーティングされるときです。

通話を無効にするのではなくiptablesのコードはbr_netfilter次のようになります:

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

適応すべきだiptables第 7 章で説明したように、副作用を回避するために、たとえばルーティングではなくブリッジングを目的とした FORWARD チェーンに accept ルールを追加することで、ルールがどこにあっても (ネットワーク名前空間が何であれ) ルールを無効にする必要があります。 1 つの問題を解決するために単に無効にすると、Docker の内部コンテナー分離から始まり、それに依存するアプリケーションが中断されます。

最近まで カーネル 5.3このモジュールは名前空間を認識しなかったため、ロードされると突然すべてのネットワーク名前空間で有効になり、予期しないさまざまな問題が発生しました。また、それ以降、ip link set dev BRIDGE type bridge nf_call_iptables 1名前空間ごとではなくブリッジ ( ) ごとに有効にできるようになりました。

ツール(Dockerなど)とカーネル(>= 5.3)が進化すれば、選択したネットワーク名前空間とブリッジで有効にするだけで十分ですが、現時点ではおそらくそうではありません。また、カーネル 5.3また、ネイティブブリッジステートフルファイアウォールも継承されており、nftablesこれは、このモジュールの使用を廃止するためのステップです (VLAN および PPPoE のブリッジで直接カプセル化/カプセル化解除がサポートされるようになったら)。

ネットフィルター

ブリッジのネイティブ接続追跡サポートを追加します。このパッチセット以前は、ステートフルフィルタリングを行う唯一の方法は、br_netfilter エミュレーションレイヤーを使用することでしたが、これはそれを廃止するための一歩です。

関連情報