ネットワーク名前空間内の WireGuard: ソケットが取り残された理由
インターフェースを移動しても暗号化された UDP ソケットは移動せず、デバイスを作成した名前空間に残ります。対象の名前空間内で作成してください。
インターフェースは望んだ名前空間に現れ、アプリケーションもそこに結び付いているのに、トンネルのトラフィックが一切現れません。これは Linux カーネルの WireGuard デバイスを別の名前空間で作成して移動した場合の特徴です。インターフェースは移動しましたが、暗号化された UDP ソケットは移動していません。内部トラフィックを意味あるものにする前に、両方を正しい場所に置く必要があります。一つではなく二つのコンテキストを見るべきだと分かれば、確認はすぐに終わります。
症状: 名前空間は正しいのにパケットが流れない
名前空間の内部ではトンネルは健全に見えます。デバイスは存在し、アドレスも割り当てられ、ピア設定も揃っています。外部では、監視していたインターフェースに期待した UDP のやり取りが一切現れず、相手側はハンドシェイクが起きていないと報告します。
原因は、アプリケーションの内部パケットが移動したデバイスに届き、デバイスが別のネットワークコンテキストに属するソケットで送ろうとすることです。使用するアンダーレイの経路も、それに適用されるファイアウォール規則もすべて、デバイスを作成した名前空間のものです。
これは移動の不具合でも、ピアの設定ミスでもありません。カーネル実装がそう動くのであり、WireGuard の名前空間に関するドキュメントが作成規則を直接説明しています。
ソケットに生まれた場所がある理由
WireGuard デバイスは暗号化された転送用の UDP ソケットを一つ所有し、そのソケットはデバイスを作成した名前空間で開かれます。リンクコマンドでインターフェースを移動すると、見えるデバイスは移りますが転送は始まった場所に残ります。結果として二つのオブジェクトの所有者が異なります。
結果を見落としやすいのは、二つの半分を別々の場所で調べるからです。内部経路はアプリケーションが動く名前空間で決まり、外部経路はソケットが存在する場所で決まります。片方だけを確認すると、自信のある誤った結論になります。両方を確認すれば、通常は一度の調査で決着します。
ソケットを置きたい場所で作成する
解決策は、外で作成して移動するのではなく、対象の名前空間の内部でデバイスを作成することです。承認済みの名前空間がすでにあり、名前が未使用であると仮定します。
ip netns exec vpn-apps ip link add wg-demo type wireguard
ip netns exec vpn-apps wg show
これでインターフェースとそのソケットの両方がそのコンテキストに属し、アンダーレイの経路と適用されるフィルター規則はそこで設定されたものになります。設計上クリア側を別の場所に置く必要があるなら、先に基盤のインターフェースを名前空間に入れ、その後でトンネルを作成してください。順序は設計の一部であり、実装の細部ではありません。
これらはレシピではなく、ネットワーク管理のコマンドとして扱ってください。デバイスを作成し状態を表示するだけであり、鍵、ピア、アドレス、経路は依然として承認済みの設定から取得する必要があります。既存の本番インターフェースを例に置き換えてはいけません。
経路の両側を読む
デバイスが正しい場所に来たら、二つの判断を別々に検証します。まずアプリケーションのコンテキストから内部の解決を始め、次にソケットを所有するコンテキストから外部経路を確認します。
ip netns exec vpn-apps ip route get 10.30.0.9
ip netns exec vpn-apps wg show
tcpdump -ni any udp port 51820
内部の解決がトンネル経由で行われ、外部のキャプチャに暗号化されたやり取りが現れれば、二つの半分は一致しています。キャプチャが空なら、ソケットがまだ別の場所にあるか、その名前空間のアンダーレイ経路がエンドポイントに届いていません。
もう一つ記録に入れる確認があります。再起動後にデバイスがどう作成されるかです。別の作成コンテキストでインターフェースを作り直す管理ツールは、ソケットの生まれた場所を変えてしまいます。一度だけ成功した手作業の移動は、管理される経路の証拠にはなりません。