プロトコル 47 と TCP ポート 47:二つのヘッダー、二つのルール
プロトコル番号とポートは別のヘッダーにあり、一方のルールが他方を置き換えることはできません。PPTP は両者を分けており、ポート欄だけで GRE を表現することはできません。
ホテルのネットワークや会議場のファイアウォールには独自の許可欄がよくあり、PPTP が動くことを期待して誰かがそこに 47 と入力します。ルールは作られるもののトンネルはつながらず、次の試行では別の番号が使われます。原因はパケット自体にあります:IPv4 には IP ヘッダーの後に何が続くかを示すプロトコルフィールドがあり、TCP と UDP にはポートフィールドがありますが、それはどちらかのヘッダーの内側に入って初めて存在します。両者は同じ許可の別表記ではありません。
IPv4 ヘッダーが次のプロトコルを示す
プロトコルフィールドは IPv4 ヘッダー内の一バイトで、ペイロードを表す番号を保持します:TCP は 6、UDP は 17、GRE は 47、ESP は 50 です。パケットを絞り込むものはすべて、深い側のヘッダーが種類の判明後にしか意味を持たないため、より深く見る前にこの値を読みます。会話の途中でポートを変えても、このフィールドは動きません。
したがってプロトコル 47 に対して書かれたルールは IP 層を記述しています。判断にポートは一切関与しません。
ポートは TCP と UDP の内側にだけ存在する
ポートは TCP と UDP のヘッダー内にある十六ビットの識別子で、一つのアドレスを共有する会話を分離するのが役割です。GRE ヘッダーはプロトコル種別の値、多くの場合 EtherType を運び、さらに多重化のための任意のキーを持ちます。ですからポート 47 という表現は、GRE パケットが一致できる何も指していません。
ファイアウォールの画面は、このうちどこまで見せるかが異なります。プロトコル番号を受け付けるもの、名前付きの一覧を出すもの、TCP か UDP とポートだけを受け付けるものがあります。
PPTP は二つの層を同時に使う
PPTP が最も分かりやすい例なのは、作業を意図的に二つの層に分けているからです。制御接続はポート 1723 への TCP セッションで、データ経路は GRE、プロトコル 47 であり、どこにもポートは関与しません。1723 だけを許可するファイアウォールは、交渉を始めさせたうえでペイロードを捨てます。トンネルは接続に失敗するのではなく認証後に固まったように見え、そのため症状はパスワードの問題として報告されがちです。
| Path | Outer protocol | Port |
|---|---|---|
| Control channel | TCP, protocol 6 | 1723 |
| Data channel | GRE, protocol 47 | None |
ルールを書くときは二つの行を別々に読み、それぞれをベンダーの構文と照合してください。一方の行はポートを必要とし、もう一方はプロトコル番号を必要とし、単一の項目が両方を覆うことはありません。
ポート転送の画面が GRE を表現できない理由
TCP と UDP しか受け付けない転送フォームは、その名前が何であれ GRE を記述できません。アドレス変換は、GRE にはポートがなく変換側が代わりに呼び出し識別子を追う必要があるため、第二の難点を加えます。家庭用ルーターの一部にはこれを扱うヘルパーが付いていますが、多くの製品にはなく、TCP の許可項目を追加してもその動作は生まれません。
現代的なトンネルが本当の要件なら、変換側が正しく推測することを期待するのではなく、TCP か UDP を意図的に使う設計を選んでください。
カプセル化がフィルターの見えるものを決める
カプセル化は外側のパケットを変え、ルールが一致するのはその外側のパケットです。ネイティブの ESP はプロトコル 50 ですが、NAT 通過では ESP を UDP 4500 の中に包み、アドレス変換を生き延びさせます。UDP 4500 を許可するフィルターはプロトコル 50 を決して見ず、プロトコル 50 向けに書かれたフィルターは包まれた形に決して一致しません。
クライアントとゲートウェイがどのカプセル化で合意したかを確認し、その外側の形だけに対してルールを書いてください。
誰かが検証できるようにルールを書く
すべてのルールをアドレスファミリー、外側のプロトコル、あればトランスポートポート、方向、両端点として表現してください。レビュー担当者はその文をパケットキャプチャと突き合わせて判断に達することができます。47 を開けという指示は誰にも検証できず、そのため何年も手順書に残ります。
それを証明する試験を加えてください:外側のインターフェースでキャプチャしながら接続し、トレースに実際に現れる外側のプロトコルとポートを確認します。