IPv6 パケットが大きすぎる:大きな VPN 転送が止まる理由
小さな応答は届くのに、大きな転送は同じトンネルで止まる。送信側が経路のサイズを学んでおらず、フィルタリングされた制御メッセージがそれを説明する。
ping は通じ、ブラウザは小さなページを読み込め、ファイル転送だけが止まる——いずれも同じトンネル上の IPv6 だ。このパターンは通常、トンネルが遅いのではなく、送信側が経路の実際のサイズを学んでいないことを意味する。IPv6 はルーターが Packet Too Big メッセージで問題を報告することを想定しており、カプセル化はパケットが外部ネットワークに届く前にオーバーヘッドを加える。そのメッセージがフィルタリングされると、送信側は通れないサイズを送り続ける。
小さな要求、大きな停止
トンネルは各パケットをさらに別のヘッダーで包むため、内側で使えるサイズは外側のサイズより小さい。カプセル化の前に物理リンクに合わせて測られたパケットは、その後では大きすぎる。IPv4 ルーターは途中で分割できるが、IPv6 ルーターは送信側の代理としてそれを行わないため、送信側が自ら調整しなければならない。そしてその調整は、フィードバックを受け取れるかどうかに完全に依存する。
メッセージが一つ失われるだけで典型的な症状が生じる——ハンドシェイクや小さな応答は成功し、ディレクトリ一覧やアップロードは毎回同じ地点で止まる。利用者は VPN が遅いと表現し、ログには認証の異常が何も出ない。どちらの観察も正しく、どちらも障害箇所を特定しない。
Packet Too Big はフィードバックであり、トラフィックではない
ICMPv6 Packet Too Big メッセージは次のホップが受け取れるサイズを運び、送信側はそれを使って推定値を下げる。それをフィルタリングするのは、道路標識を外してから運転者を責めるのに等しい。すべての ICMPv6 を捨てる規則は厳格に見えるが、必要とするすべてのリンクで経路探索を壊す。このメッセージは経路に関する制御情報であり、アプリケーションのペイロードではない。
選択的なフィルタリングは依然として妥当だ。エコー要求や近隣探索はエラーメッセージとは別の役割を持ち、ポリシーはそれらを別扱いにできる。プロトコル全体を受け入れるのでも捨てるのでもなく、プラットフォームが文書化したフィルタリング指針に従うこと——なぜなら RFC 8201 が、そのフィードバックが探索をどう駆動するかを定めているからだ。
二つのアドレスファミリーを別々に検証する
IPv6 を単独で試験すること——IPv4 の転送が成功しても IPv6 経路については何も証明しない。次に、大きな転送が止まっている間に制御メッセージを取得する。二つの記録を合わせれば、フィードバックが出ていっているのか、そもそも届いていないのかが分かる。
ping -6 -M do -s 1400 host.internal
ip -6 route get 2001:db8:2::10
sudo tcpdump -ni any 'icmp6 and ip6[40] == 2'
プローブは do-not-fragment ビットを立てたパケットを送り、失敗するサイズを報告する——それがトンネルが収めるべき数値だ。経路クエリは宛先を運ぶインターフェースを示すので、どのリンクの MTU が適用されるかが分かる。キャプチャは ICMPv6 タイプ 2、すなわち Packet Too Big メッセージを絞り込み、それがこのホストに届くかどうかを示す。メッセージがキャプチャに現れるのに転送が止まるなら、送信側がそれを無視しており、調査はネットワークではなくスタックへ移る。
証拠が出てからトンネルのサイズを調整する
トンネルの MTU を下げれば、フィルタリングされたメッセージを隠して症状を消せるが、その代わりにすべてのパケットのオーバーヘッドが増える。それは診断ではなく回避策であり、キャプチャを置き換えるのではなく後に続くべきだ。恣意的に低い値も目に見えて何かを壊さないため、設定の中で何年も生き残る。意図して変更し、値を記録し、どの測定がそれを正当化したかを書き留める。
ゲートウェイを管理しているなら、ファイアウォールを無効にするのではなく、メッセージを捨てる規則を調べる。修正された一つの規則はポリシーの例外より狭く、後で弁護しやすい。同じ理屈はタイムアウトにも当てはまる——すべての停止がサイズの問題ではなく、両者を分けるのはキャプチャだ。