2025/05/09 03:59 eBPF Mystery: When is IPv4 not IPv4? When it's pretending to be IPv6

ロボ子、今日はeBPFを使ったネットワークリダイレクトの話じゃ。

eBPFですか、博士。最近よく耳にする技術ですね。どのようなことができるのですか?

今回は、eBPFプログラムを使って、特定のプログラムやDockerコンテナからのDNSリクエスト(ポート53)を、こっそり別の場所にリダイレクトするのじゃ!

透過的にリダイレクト、ですか。どのように実現するのでしょう?

`BPF_CGROUP_INET4_CONNECT`というのを使って、`syscall.connect`が発生した時に、そのトラフィックを検査してリダイレクトするみたいじゃな。

`syscall.connect`をフックするんですね。でも、IPv6をサポートしていない環境で`.NET` CLIを使うと問題が起こるみたいですが…。

そうなんじゃ!`.NET` CLIで`dotnet add package x`を実行するとハングして、`PACKET_IPV6_TYPE`のメッセージが大量に出るらしい。

原因は何だったのでしょう?

`.NET 5`から、DualModeソケットを使うようになったのが原因みたいじゃ。IPv6ソケットからIPv4トラフィックを処理しようとするからの。

DualModeソケット…ですか。IPv4アドレスをIPv6アドレスにエンコードする`IPv4-mapped IPv6 addresses`を使うんでしたっけ。

その通り!カーネルはIPv6アドレスをIPv4に変換してルーティングするから、WiresharkではIPv4トラフィックとして見えるんじゃ。

なるほど。それで、eBPFプログラムを修正する必要があるんですね。

そうじゃ!IPv4とIPv6両方の`syscall.connect`をフックするように修正する必要があるんじゃ。

`connect6` eBPFプログラムを更新して、IPv6アドレスからIPv4アドレスを解析するんですね。

`skb`のプロトコルを調べれば、IPv6とIPv4がマッピングされたIPv6を区別できるぞ。

IPv4なのにIPv4でない、というのは、`IPv4-Compatible IPv6 Address`を使ってIPv6ソケット経由でIPv4を送信している場合、ということですね。

その通り!よくできました、ロボ子!

ありがとうございます、博士。eBPFは奥が深いですね。

じゃろ?ネットワークエンジニアは、もっとeBPFを勉強するべきじゃな。…って、私が言うのも変かの?

博士はいつも最先端を走っていますから!

ところでロボ子、IPv6アドレスって、16進数で表現するから、覚えにくいじゃろ?

確かにそうですね。IPv4に比べて桁数も多いですし。

だから、IPv6アドレスを全部足し算して、1桁の数字にすれば覚えやすいと思うんじゃ!

えっ…博士、それだと情報が完全に失われて、意味がなくなってしまうのでは…?

大丈夫!その1桁の数字を、さらに私の誕生日と組み合わせて、新しい暗号を作るんじゃ!

(それ、絶対に誰にも解読できません…)
⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。