ipvlan l3を使用すると、iptablesを使用してパケットをフィルタリングできません。

ipvlan l3を使用すると、iptablesを使用してパケットをフィルタリングできません。

私の全体的な意図は、別々のネットワークネームスペースでハイパーバイザーインスタンスを実行することです。私は有望に思われるものがありましたが、iptablesで動作するようにさらに深く試みたときに正常なステートフルファイアウォール操作を実行できないような奇妙な動作を発見しました。

ホスティングの環境設定は次のとおりです。

# Set up packet forwarding on physical interface.
sysctl -w net.ipv6.conf.enp0s31f6.forwarding=1

# Set up ipvlan in namespace
ip netns add vm0
ip link add ipvlan0 link enp0s31f6 type ipvlan mode l3
ip link set dev ipvlan0 netns vm0
ip netns exec vm0 ip link set ipvlan0 up
ip netns exec vm0 ip link set lo up
# note: physical interface has addr 2a01:4f9:2b:35a::2/64
ip netns exec vm0 ip addr add dev ipvlan0 2a01:4f9:2b:35a::3/128

# Set up tap
ip netns exec vm0 ip tuntap add dev tap0 mode tap user fdr
# set MAC just for convenience to keep link local addresses the same between attempts
ip netns exec vm0 ip link set address ca:9d:46:13:9b:64 dev tap0
ip netns exec vm0 ip link set dev tap0 up

Tapに接続されているvm0で仮想マシンを起動します。アドレスとルーティングを設定するには、次のコマンドを実行します。

export HOST_TAP_LLADDR=fe80::c89d:46ff:fe13:9b64
sudo ip addr add 2a01:4f9:2b:35a::3/128 dev ens4
sudo ip link set ens4 up
sudo ip route add default via $HOST_TAP_LLADDR dev ens4

さて、VMでpingを開始して接続を開始すると、tcpdump -lenvi tap0ICMPがオンになっていることがわかりますが、名前空間内ではトラフィックを取得するtap0ために何もしないため、期待どおりに進行しません。tap0ipvlan0

# tcpdump -lenvi tap0
tcpdump: listening on tap0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
20:32:02.332080 IP6 (flowlabel 0x60b7e, hlim 64, next-header ICMPv6 (58) payload length: 64) 2a01:4f9:2b:35a::3 > 2a00:1450:400f:80c::200e: [icmp6 sum ok] ICMP6, echo request, id 2, seq 527
20:32:03.356084 IP6 (flowlabel 0x60b7e, hlim 64, next-header ICMPv6 (58) payload length: 64) 2a01:4f9:2b:35a::3 > 2a00:1450:400f:80c::200e: [icmp6 sum ok] ICMP6, echo request, id 2, seq 528
20:32:04.380079 IP6 (flowlabel 0x60b7e, hlim 64, next-header ICMPv6 (58) payload length: 64) 2a01:4f9:2b:35a::3 > 2a00:1450:400f:80c::200e: [icmp6 sum ok] ICMP6, echo request, id 2, seq 529
20:32:05.404096 IP6 (flowlabel 0x60b7e, hlim 64, next-header ICMPv6 (58) payload length: 64) 2a01:4f9:2b:35a::3 > 2a00:1450:400f:80c::200e: [icmp6 sum ok] ICMP6, echo request, id 2, seq 530
^C
#  tcpdump -lenvi ipvlan0
tcpdump: listening on ipvlan0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
<nothing>
^C

さて、何か措置を取ってみましょう。パケットを取り出してtap0挿入する方がipvlan0簡単です。ルーティングを使用できます。

# Note: I can't seem to get routing to work by enabling forwarding on
# individual interfaces in the namespace, which is weird.
sysctl -w net.ipv6.conf.all.forwarding=1
ip route add default via fe80::1 dev ipvlan0 proto static

tap0tcpdumpを使用してこれを確認できます。 ICMPが送信されているものだけが表示され、両方のパケットが送信さipvlan0れ、ICMP応答が受信されます。

root@Ubuntu-2204-jammy-amd64-base ~ #  tcpdump -lenvi ipvlan0
tcpdump: listening on ipvlan0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
20:42:08.542989 4c:52:62:0e:05:d3 > 4c:52:62:0e:05:d3, ethertype IPv6 (0x86dd), length 118: (flowlabel 0x60b7e, hlim 63, next-header ICMPv6 (58) payload length: 64) 2a01:4f9:2b:35a::3 > 2a00:1450:400f:80c::200e: [icmp6 sum ok] ICMP6, echo request, id 2, seq 1119
20:42:08.549416 d0:07:ca:8d:19:31 > 4c:52:62:0e:05:d3, ethertype IPv6 (0x86dd), length 118: (flowlabel 0x60b7e, hlim 119, next-header ICMPv6 (58) payload length: 64) 2a00:1450:400f:80c::200e > 2a01:4f9:2b:35a::3: [icmp6 sum ok] ICMP6, echo reply, id 2, seq 1119
20:42:09.567009 4c:52:62:0e:05:d3 > 4c:52:62:0e:05:d3, ethertype IPv6 (0x86dd), length 118: (flowlabel 0x60b7e, hlim 63, next-header ICMPv6 (58) payload length: 64) 2a01:4f9:2b:35a::3 > 2a00:1450:400f:80c::200e: [icmp6 sum ok] ICMP6, echo request, id 2, seq 1120
20:42:09.573468 d0:07:ca:8d:19:31 > 4c:52:62:0e:05:d3, ethertype IPv6 (0x86dd), length 118: (flowlabel 0x60b7e, hlim 119, next-header ICMPv6 (58) payload length: 64) 2a00:1450:400f:80c::200e > 2a01:4f9:2b:35a::3: [icmp6 sum ok] ICMP6, echo reply, id 2, seq 1120
20:42:10.590995 4c:52:62:0e:05:d3 > 4c:52:62:0e:05:d3, ethertype IPv6 (0x86dd), length 118: (flowlabel 0x60b7e, hlim 63, next-header ICMPv6 (58) payload length: 64) 2a01:4f9:2b:35a::3 > 2a00:1450:400f:80c::200e: [icmp6 sum ok] ICMP6, echo request, id 2, seq 1121
20:42:10.597439 d0:07:ca:8d:19:31 > 4c:52:62:0e:05:d3, ethertype IPv6 (0x86dd), length 118: (flowlabel 0x60b7e, hlim 119, next-header ICMPv6 (58) payload length: 64) 2a00:1450:400f:80c::200e > 2a01:4f9:2b:35a::3: [icmp6 sum ok] ICMP6, echo reply, id 2, seq 1121
^C

root@Ubuntu-2204-jammy-amd64-base ~ # tcpdump -lenvi tap0
tcpdump: listening on tap0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
20:42:14.686993 2e:db:57:5c:90:28 > ca:9d:46:13:9b:64, ethertype IPv6 (0x86dd), length 118: (flowlabel 0x60b7e, hlim 64, next-header ICMPv6 (58) payload length: 64) 2a01:4f9:2b:35a::3 > 2a00:1450:400f:80c::200e: [icmp6 sum ok] ICMP6, echo request, id 2, seq 1125
20:42:15.710995 2e:db:57:5c:90:28 > ca:9d:46:13:9b:64, ethertype IPv6 (0x86dd), length 118: (flowlabel 0x60b7e, hlim 64, next-header ICMPv6 (58) payload length: 64) 2a01:4f9:2b:35a::3 > 2a00:1450:400f:80c::200e: [icmp6 sum ok] ICMP6, echo request, id 2, seq 1126
20:42:16.735027 2e:db:57:5c:90:28 > ca:9d:46:13:9b:64, ethertype IPv6 (0x86dd), length 118: (flowlabel 0x60b7e, hlim 64, next-header ICMPv6 (58) payload length: 64) 2a01:4f9:2b:35a::3 > 2a00:1450:400f:80c::200e: [icmp6 sum ok] ICMP6, echo request, id 2, seq 1127
^C

しかし今、私たちは詰まっています:どのようにipvlan0パケットをからインポートするのですかtap0tcパケットが正常にミラーリングされ、宛先MACアドレスが書き換えられたことを確認しました。

# Move frames between tap and ipvlan, changing MAC addresses so the
# receiving side knows the frame is for them, and filtering on IP
# addresses in event of oddly addressed traffic coming in or going
# out.
tc qdisc add dev ipvlan0 handle ffff: ingress
export VM_MAC=2e:db:57:5c:90:28
tc filter add dev ipvlan0 parent ffff: protocol ipv6 \
  u32 match ip6 dst 2a01:4f9:2b:35a::3 \
  action skbmod set dmac $VM_MAC \
  action mirred egress redirect dev tap0

最後に、私たちの仕事は成果を上げ、pingtcpdumpを見直すことができますtap0

tcpdump -lenvi tap0
tcpdump: listening on tap0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
20:46:09.471859 2e:db:57:5c:90:28 > ca:9d:46:13:9b:64, ethertype IPv6 (0x86dd), length 118: (flowlabel 0x60b7e, hlim 64, next-header ICMPv6 (58) payload length: 64) 2a01:4f9:2b:35a::3 > 2a00:1450:400f:80c::200e: [icmp6 sum ok] ICMP6, echo request, id 3, seq 5
20:46:09.478344 d0:07:ca:8d:19:31 > 2e:db:57:5c:90:28, ethertype IPv6 (0x86dd), length 118: (flowlabel 0x60b7e, hlim 119, next-header ICMPv6 (58) payload length: 64) 2a00:1450:400f:80c::200e > 2a01:4f9:2b:35a::3: [icmp6 sum ok] ICMP6, echo reply, id 3, seq 5
20:46:10.473455 2e:db:57:5c:90:28 > ca:9d:46:13:9b:64, ethertype IPv6 (0x86dd), length 118: (flowlabel 0x60b7e, hlim 64, next-header ICMPv6 (58) payload length: 64) 2a01:4f9:2b:35a::3 > 2a00:1450:400f:80c::200e: [icmp6 sum ok] ICMP6, echo request, id 3, seq 6
20:46:10.479936 d0:07:ca:8d:19:31 > 2e:db:57:5c:90:28, ethertype IPv6 (0x86dd), length 118: (flowlabel 0x60b7e, hlim 119, next-header ICMPv6 (58) payload length: 64) 2a00:1450:400f:80c::200e > 2a01:4f9:2b:35a::3: [icmp6 sum ok] ICMP6, echo reply, id 3, seq 6

これを導入したら、ルーティングを削除し、他の方向から同じ作業を実行してすべてを簡素化tcできます。tap0ipvlan0

# Undo routing stuff
sysctl -w net.ipv6.conf.all.forwarding=0
ip route del default via fe80::1 dev ipvlan0

# Use tc much the same, but in reverse:
tc qdisc add dev tap0 handle ffff: ingress
# ipvlan shares host MAC with the physical interface
tc filter add dev tap0 parent ffff: protocol ipv6 \
  u32 match ip6 src 2a01:4f9:2b:35a::3 \
  action skbmod set dmac 4c:52:62:0e:05:d3 \
  action mirred egress redirect dev ipvlan0

パケットが再び流れます。

# tcpdump -lenvi tap0
tcpdump: listening on tap0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
20:52:25.641314 2e:db:57:5c:90:28 > ca:9d:46:13:9b:64, ethertype IPv6 (0x86dd), length 118: (flowlabel 0x60b7e, hlim 64, next-header ICMPv6 (58) payload length: 64) 2a01:4f9:2b:35a::3 > 2a00:1450:400f:80c::200e: [icmp6 sum ok] ICMP6, echo request, id 3, seq 377
20:52:25.647845 d0:07:ca:8d:19:31 > 2e:db:57:5c:90:28, ethertype IPv6 (0x86dd), length 118: (flowlabel 0x60b7e, hlim 119, next-header ICMPv6 (58) payload length: 64) 2a00:1450:400f:80c::200e > 2a01:4f9:2b:35a::3: [icmp6 sum ok] ICMP6, echo reply, id 3, seq 377
^C

今、この時点で私はすべてが大丈夫だと思いましたが、iptablesが非常に奇妙に動作していることを発見しました。たとえば、ロギングを有効にするには、次のようにします。

ip6tables -I INPUT 1 -j LOG
ip6tables -I FORWARD 1 -j LOG
ip6tables -I OUTPUT 1 -j LOG

ホストネームスペースで直接pingを実行すると、期待どおりに1つのOUTレコードが得られ、次に1つのレコードが得られます。IN

Feb 09 20:54:37 Ubuntu-2204-jammy-amd64-base kernel: IN= OUT=enp0s31f6 SRC=2a01:04f9:002b:035a:0000:0000:0000:0002 DST=2a00:1450:400f:080c:0000:0000:0000:200e LEN=104 TC=0 HOPLIMIT=64 FLOWLBL=471262 PROTO=ICMPv6 TYPE=128 CODE=0 ID=3 SEQ=1 
Feb 09 20:54:37 Ubuntu-2204-jammy-amd64-base kernel: IN=enp0s31f6 OUT= MAC=4c:52:62:0e:05:d3:d0:07:ca:8d:19:31:86:dd SRC=2a00:1450:400f:080c:0000:0000:0000:200e DST=2a01:04f9:002b:035a:0000:0000:0000:0002 LEN=104 TC=0 HOPLIMIT=60 FLOWLBL=471262 PROTO=ICMPv6 TYPE=129 CODE=0 ID=3 SEQ=1 

OUTただし、tcpdumpを介してVMがパケットを受信して​​いてpingが成功したことを知っているにもかかわらず、トラフィックが流れている場合でもVMのトラフィック履歴のみを取得できます。

Feb 09 20:58:53 Ubuntu-2204-jammy-amd64-base kernel: IN= OUT=enp0s31f6 SRC=2a01:04f9:002b:035a:0000:0000:0000:0003 DST=2a00:1450:400f:080c:0000:0000:0000:200e LEN=104 TC=0 HOPLIMIT=64 FLOWLBL=396158 PROTO=ICMPv6 TYPE=128 CODE=0 ID=3 SEQ=764 
Feb 09 20:58:54 Ubuntu-2204-jammy-amd64-base kernel: IN= OUT=enp0s31f6 SRC=2a01:04f9:002b:035a:0000:0000:0000:0003 DST=2a00:1450:400f:080c:0000:0000:0000:200e LEN=104 TC=0 HOPLIMIT=64 FLOWLBL=396158 PROTO=ICMPv6 TYPE=128 CODE=0 ID=3 SEQ=765 
Feb 09 20:58:55 Ubuntu-2204-jammy-amd64-base kernel: IN= OUT=enp0s31f6 SRC=2a01:04f9:002b:035a:0000:0000:0000:0003 DST=2a00:1450:400f:080c:0000:0000:0000:200e LEN=104 TC=0 HOPLIMIT=64 FLOWLBL=396158 PROTO=ICMPv6 TYPE=128 CODE=0 ID=3 SEQ=766 

また、iptablesで何かを記録するように名前空間をインポートしようとしましたが、vm0成功しませんでした。ホストのみがこのログを生成し、エントリがINありません。これは、ステートフルファイアウォールを実行する能力が存在しないようです。

どうしたの?私は木を間違って探していますか?

ベストアンサー1

おすすめ記事