ISPがUDPを遮断しているのか、トンネル内のアプリなのか
ISPは暗号化された内側ヘッダーを読まずに外側のUDPトランスポートを破棄できる。外側の配送、内側の転送、アプリの挙動を分けて考える。
VPNが「UDPを遮断する」という報告があるが、この一言にはまったく別の二つの主張が隠れている。一つはアクセス網が見ることのできるトランスポートについて、もう一つはトンネル内で復号された後のアプリのパケットについてである。暗号化されたトンネルは鍵なしで外からフィルタリングでき、内側のUDPアプリはフィルタリングとは無関係な理由で失敗しうる。証拠を集める前に、どちらの主張を検証しているのかを決めよう。
二つのヘッダー、一つの言葉
NAT-traversalを用いたIPsecの配備では、外側のパケットは二つのVPNエンドポイント間で宛先指定されたUDPであり、通常はポート4500を使う。その内側で、暗号化されたペイロードはトンネルが転送するものをそのまま運び、それ自体がTCPやUDPであることもある。つまりUDPという言葉は、異なる意味と異なる可視性で二度現れる。
中間のネットワークは外側のヘッダーだけを見て、内側は何も見えない。外側のフローを許可し、整形し、あるいは破棄でき、そのために何かを復号する必要はない。この非対称性こそが二つの主張を混同させる最大の理由である。同じ言葉が、ネットワークがフィルタリングするものとアプリが送るものの両方を指す。所見を記録するときは必ず言葉の隣に層を書き添えれば、混乱はほとんど消える。
内側のヘッダーは、復号後に受信側エンドポイントでのみ見えるようになる。その時点からパケットは他のものと同様に転送され、経路、ポリシー、エンドポイント自身のフィルタリングに従う。これらは別々の機器が下す別々の判断である。
ネットワークがなお見えるもの
暗号化が隠すのはペイロードと内側のトランスポートヘッダーであり、フローが存在するという事実ではない。エンドポイントのアドレス、ポート、パケットサイズ、タイミングは見えたままで、それだけでトラフィックをヒューリスティックに分類したり、特定の宛先を遮断したりできる。
sudo tcpdump -ni eth0 'udp port 4500' sudo tcpdump -ni tun0 'udp port 5201'
最初のキャプチャは物理インターフェース上の外側フローを、二つ目はトンネルインターフェース上の内側フローを示す。両方を同時に走らせれば問いに直接答が出る。外側があって内側がないなら、アプリはトンネルに何も送っていない。両方あって何も戻らないなら、問題はトンネルの先、宛先か戻り経路にある。
RFC 3948 は外側のUDPカプセル化を定義し、ESP仕様はその内側の保護された配置を定義する。どちらの文書も、アクセス網が外側フローを通すことを約束してはいない。だからこそ、内側についての理論を立てる前に、外側のタプルで到達性テストを走らせる価値がある。外側のタプルが遮断されればトンネルはそもそも成立せず、成立したトンネルが一つのアプリだけ失うという話にはならない。
動いているトンネルの中で一つのUDPアプリが失敗する理由
Webアプリは通すがUDPアプリは通さないトンネルには、もっともらしい説明がいくつかあり、ISPによる内側プロトコルのフィルタリングはその最初ではない。最も多いのは網羅性である。UDP宛先への経路がないか、クライアントのスプリットトンネル規則がそれを除外しているため、二つのアプリが同じトンネルに入っていないのだ。
二つ目はエンドポイントである。プロトコルの一覧を許可するVPNサーバー、宛先側のファイアウォール、期待したポートで決して待ち受けないサービスは、いずれもネットワーク遮断とまったく同じに見えるタイムアウトを生む。
三つ目はパケットサイズである。UDPアプリはWebリクエストより大きなデータグラムを送ることが多く、カプセル化が利用可能なMTUを減らすため、ハンドシェイクが成功した後に最初のフルサイズのペイロードで沈黙することがある。小さなパケットは通り大きなものだけ消えるので、これは遮断と読み違えやすい。素早いMTU検査で一分もかからず決着し、答えは通常ネットワークフィルターではなく、より小さなペイロードか修正されたMSSである。
ping -M do -s 1400 -c 2 10.60.0.20 iperf3 -u -c 10.60.0.20 -p 5201 -b 1M -t 5
最初のコマンドは、フラグメンテーションを無効にした経路を大きなパケットが通るかを試し、MTU問題を素早くあぶり出す。二つ目は小さく制限されたUDPストリームを送り、損失とジッターを報告する。始まってから止まるストリームは、遮断ではなくサイズを指し示す。
プロトコルではなく層を報告する
所見は三つの形のいずれかで書く。外側の配送が失敗した、内側の転送が失敗した、アプリが失敗した、である。それぞれ担当が違い、混ぜるとチケットは誤ったチームへ送られる。
ローカルポートを変えても遠端に対応するリスナーは作れない。だから助かったように見えるクライアント側の回避策は、たいてい元の宛先が誤っていた証拠である。同様に、提供された代替プロファイルは到達性について何かを示すが、アプリが正しく設定されているかについては何も示さない。
推論と観測も分けておく。トラフィック分析は復号せずにフローが何かを示唆でき、それは有用な所見だが、内側ヘッダーを読むという主張と同じではない。実際にどちらを持っているのかを明記しよう。