tunインターフェースとカーネルのIPv6処理について質問があります。
私のネットワークのエンドユーザーに純粋なIPv4ネットワークを介してIPv6を提供したいと思います。 (トンネリングの背景理論のみ)要約すると、すべてのIPv6パケットはIPv4パケットに入れられ、トンネルを介して送信されます。
これらすべてをシミュレートするシナリオは次のとおりです。
- 2つのデバイス間のトラフィックをトンネリングするために使用する2つのIPv4仮想インターフェイスを持つ1台のマシンしかありません。私たちはそれらを「if4a」と「if4b」と呼びます。これらのインターフェイスは管理インターフェイスのサブインターフェイスです。
- また、このマシンには、エンドユーザーのIPv6アドレスをマスクするために使用される2つのIPv6トンインターフェースがあります。私たちはそれらを「if6a」と「if6b」と呼びます。各 tun インターフェイスには、トンネルにパケットを書き込むか、トンネルからパケットを読み取る前に必要なヘッダー (GTP) を挿入または削除する手動プログラムが添付されています (アドレス付き fd00:fea:2001::1 if4a と fd00:fea を持つ if4b :2002住所::1住所)。
- どこにも定義されておらず、実際にエンドユーザーアドレスである2つのIPv6アドレスがあります(fd00:cafe:2001::1はif6aのユーザーを表し、fd00:cafe:2002::1はif6bネットワークのユーザーを表します)。
- ルートテーブルは、エンドユーザトラフィックを「if6a」または「if6b」(tunインターフェイス)に送信するように構成されています。
- パケットが宛先if6xインターフェイスに直接転送されるのを防ぐために、「cafe」アドレスを介して「fea」IPv6アドレスを変更し、IPv6トラフィックがトンインターフェイス、つまり私のGTPハンドラを通過するように強制するNAT設定があります。
問題は次のとおりです。
- if6a 経由で fd00:fea:2001::1 から fd00:cafe:2002::1 に ICMPv6 を送信します。
- NAT以降、ルーティングチェーンはfd00:cafe:2001::1を介して送信元アドレスを変更します。
- if6aでリッスンしているプログラムはICMPv6を読み込み、GTPヘッダーを追加してそれをif4bに送信します(IPv4を使用)。
- GTP でカプセル化された IPv6 パケットのアドレスは次のとおりです。 fd00:cafe:2001::1 ~ fd00:cafe:2002::1
- サーバーはパケットを受信してGTPヘッダーを削除し、それをif6bインターフェースに挿入します(IPv6パケット)。
- tsharkがパケットをスニッフィングしてトレースを印刷する場所です。
- NAT事前ルーティングチェーンはfd00:fea:2002::1を介して宛先アドレスを変更し、スタックIPに上がります。
- パケットがIPv6スタックの代わりにIPv4スタックに入ったため、廃棄されました。
いくつかの兆候:
- シャーク:
[root@vm062 ~]# tshark -i if6b`
Running as user "root" and group "root". This could be dangerous
Capturing on 'if6b'
1 0.000000 fd00:cafe:2001::1 -> fd00:cafe:2002::1 ICMPv6 104 Echo
(ping) request id=0x7383, seq=1, hop limit=0
1 2 0.785373 fd00:cafe:2001::1 -> fd00:cafe:2002::1 ICMPv6 104
Echo (ping) request id=0x7383, seq=2, hop limit=0
2 3 1.782000 fd00:cafe:2001::1 -> fd00:cafe:2002::1 ICMPv6 104
Echo (ping) request id=0x7383, seq=3, hop limit=0
3 4 2.781968 fd00:cafe:2001::1 -> fd00:cafe:2002::1 ICMPv6 104
Echo (ping) request id=0x7383, seq=4, hop limit=0...
- Dropwatchが示すように、ドロップされたパケットは次のとおりです。
[ipv6test@vm062 ssh]$ echo start | dropwatch -l kas
Initalizing kallsyms db
dropwatch> start
Enabling monitoring...
Kernel monitoring activated.
Issue Ctrl-C to stop monitoring
1 drops at ip_rcv+c0 (0xffffffff81536450)
2 drops at ip_rcv+c0 (0xffffffff81536450)
1 drops at ip_rcv+c0 (0xffffffff81536450)
2 drops at ip_rcv+c0 (0xffffffff81536450)
2 drops at ip_rcv+c0 (0xffffffff81536450)
2 drops at ip_rcv+c0 (0xffffffff81536450)
2 drops at ip_rcv+c0 (0xffffffff81536450)
...
ping6 を停止すると、ping6 も停止します。
勉強していましたip_rcv関数そしてこれはIPv4パケットでのみ機能するので、私のIPv6パケットはIPv6スタックではなくIPv4スタックを介して着信しているようです。カーネルはなぜこのようなことをするのか?
同様の質問がありますここ。