ESP は TCP ポート 50 ではなく IP プロトコル 50:何を許可すべきか
プロトコル番号とポート番号は別の名前空間です。TCP ポート 50 の規則では何も許可されず、NAT トラバーサルは ESP を UDP 4500 に移します。
ファイアウォールの入力欄は TCP ポートを求め、誰もが 50 と書きます。その設定では何も許可されません。ESP は IP プロトコル番号 50 であり、プロトコル番号はポートではないからです。二つの名前空間は小さな整数を共有するだけで、IKE が終わっても保護された通信が届かないと気づけません。
小さな数字を共有する二つの名前空間
IP ヘッダーには次に何が来るかを示すプロトコルフィールドがあり、TCP は 6、UDP は 17、ICMP は 1、ESP は 50、AH は 51 です。TCP や UDP のヘッダーにはポート番号があり、宛先ホスト上のプロセスを選びます。プロトコル 50 と TCP ポート 50 は無関係な値ですが、ダイアログボックスは両者を交換可能に見せてしまいます。
だからこそポート転送の規則ではネイティブ ESP を表現できません。転送すべき ESP の宛先ポートは存在せず、ポート規則しか理解しない機器には、そのパケットを表す語彙がそもそもありません。正しい規則は IP プロトコルを指定します。ポートのダイアログは、そのパケットには誤った道具です。
混乱にはもう半分あります。パケットが暗号化されると、内部はすべて不透明になり、元の接続の TCP ヘッダーも含まれます。そのパケットのポートを検査するファイアウォールは外側のヘッダーを見ており、ネイティブの場合はそこに検査すべきポートがありません。
ネイティブ ESP、次にカプセル化された方式
ネイティブ ESP は IP プロトコルとして直接運ばれ、同じくらい効率的で厄介です。追加のヘッダーがない点は効率的で、アドレスとポートを変換する機器が追跡できない点は厄介です。NAT トラバーサルはこれを解決するためにあり、ESP パケットを UDP で包んで、変換側に書き換えられるポートを与えます。
| Form on the wire | How it is identified | What the firewall must permit |
|---|---|---|
| IKE negotiation | UDP with a destination port | UDP 500, and 4500 once traversal is detected |
| Native ESP | IP protocol 50 in the outer header | The protocol itself, with no port to name |
| ESP inside UDP | UDP 4500 carrying an ESP payload | The UDP port pair, which translation devices can track |
二つの形式は同じデータチャネルの別々の配備であり、一方の層ではありません。ネイティブ ESP を許可してもカプセル化形式は許可されず、UDP 4500 を許可してもネイティブ通信は許可されないので、規則セットは配備に合わせるべきで、偶然に両方を覆ってはいけません。
検出もここでは重要です。端点はネゴシエーション中にどちらの形式かを決め、切り替えは通常、両者の間に NAT が検出されたときに起こります。そのため、トンネル確立後に経路が変わると、規則が決して覆っていなかった名前空間へ通信が移ることがあります。
接続が実際にどちらの形式を使っているかを読む
ファイアウォールから推測するのではなく端点に尋ねます。Linux では状態エントリが、関連が UDP カプセル化を使っているか、どのポートが関与しているかを報告します。パケットキャプチャは同じ問いに回線側から答え、どちらも規則セットを読んで願うより速い方法です。
ip xfrm state | grep -A3 encap
tcpdump -ni any 'ip proto 50 or udp port 4500'
最初のコマンドは NAT トラバーサルが使われているときにカプセル化の種類を示し、使われていなければ何も示しません。二つ目は二つの形式のどちらが実際にインターフェースを通過しているかを示し、紙の上で正しく見える設定についての議論を終わらせます。
反証も同じ手順に入ります。一致ゼロを報告する規則は、パケットがそこに届いていないことを告げており、それはルーティングかセレクターの問題で、ファイアウォールの問題ではありません。
次に制御チャネルを別に確認します。IKE には独自のポートと独自のログがあり、データなしで完了したネゴシエーションは、まさにこの記事が扱う分離です。
規則を正しい名前空間で書く
プロトコルの規則とポートの規則は別の指示なので、道具は意図した方を表現しなければなりません。nftables ではプロトコルの一致を明示し、カプセル化された方式には独自の UDP 規則を与えます。二つの規則を隣り合わせに置き、レビューで対が見えるようにします。
nft add rule inet filter input ip protocol esp accept
nft add rule inet filter input udp dport { 500, 4500 } accept
誤診を埋め合わせようとしてどちらの規則も広げないでください。すべてのインターフェースで ESP プロトコルを全許可したり、任意から任意への UDP を許可したりすると、症状は直っても設定しようとしていた制御が失われます。形式が分かれば、狭い許可でほとんど足ります。
最後に、トンネルは動くのにアプリケーションが動かないときは、層を混同しないでください。ゲートウェイに届いたパケットには、なお転送と戻り経路と、それを受け入れるポリシーが必要で、どれも ESP の規則では表現されません。ポートの欠落は特定の失敗を説明するもので、すべての IPsec の失敗ではありません。規則の修正とルーティングの確認は、別々の結論として扱ってください。
観測した形式、追加したプロトコル規則、その後に見たカウンターを記録してください。三行で、次の人は名前空間の間違いとルーティングの間違いを、半日ではなく一分で見分けられます。