そのパケットはどこで消えたのか──エンドポイントの内側には、公式一覧にないプロトコルが流れている

セキュリティ

VPNは繋がる。認証も通る。トンネルも張れている。

なのに、その中を流れるはずの通信が一切通らない。Wiresharkでキャプチャを取っても、落ちているパケットがどこにも写っていない。

同じ症状に、半年で2回出会いました。1件目はL2TP/IPsec、2件目はIKEv2。VPNの方式を変えたら、同じ障害が形を変えて戻ってきた格好です。

そして2件目は、Microsoftが公開している必要ポートを全部開けても直りませんでした。


前提条件

この障害は、環境が揃ったときだけ出ます。先に条件を書いておきます。

  • Windows Defender Firewallの送信既定が「ブロック」(最重要。Windowsの既定は「許可」です)
  • ブロックしているのは明示的なBlock規則ではなく、送信既定という既定動作(WFPログの filterOrigin が Default Outbound)
  • Windows標準のVPNクライアント(1件目はL2TP/IPsec、2件目はIKEv2・EAP認証)
  • 経路上にNATがあり、NAT-T(UDP/4500)でESPを包んで通している
  • フルトンネル構成(VPN側にデフォルトルートが向く)
  • ドメイン参加端末

送信既定が「許可」の環境では、この障害は起きません。 後述しますが、そこが公式ドキュメントに記載がない理由にもつながっています。


急いでいる方へ:結論を先に

結論からお伝えすると、エンドポイントの内側には、境界ファイアウォールには一度も現れないプロトコルが流れています。 世に出回っている「VPNの必要ポート一覧」は境界機器向けなので、それを全部開けても、端末側では足りません。

しかも内側に流れるものは、VPNの方式によって変わります。

VPN方式IPsecのモード境界FWに開けるものエンドポイント内部で開けるもの
L2TP/IPsecトランスポートモードUDP/500, UDP/4500, プロトコル50UDP/1701
IKEv2トンネルモードUDP/500, UDP/4500, プロトコル50プロトコル4(IPv4-in-IPv4)

症状: VPN接続は成功する。鍵交換も完走する。しかしトンネル内の通信が0パケット。Firewallを全開放すると正常に動く。

確認方法: 改善策を当てる前に、自分の環境で何が落ちているかを確認してください。WFP(Windows Filtering Platform)のログに、そのまま書いてあります。

netsh wfp capture start file=C:\temp\wfp.cab
#   ここでVPN接続 → 社内宛に何か通信する
netsh wfp capture stop

wfp.cab を展開して wfpdiag.xml を開き、ドロップイベントの <ipProtocol> と <msFwpDirection> を見ます。今回のケースでは、ドロップ1009件のうち912件が ipProtocol 4 の MS_FWP_DIRECTION_OUT でした。

改善策: 確認できたプロトコルを、送信方向で許可します。

# IKEv2 の場合
New-NetFirewallRule -DisplayName "IPsec Tunnel IPv4-in-IPv4 out" -Direction Outbound `
  -Protocol 4 -Action Allow -Profile Any
# L2TP/IPsec の場合
New-NetFirewallRule -DisplayName "VPN L2TP (UDP1701) out" -Direction Outbound `
  -Protocol UDP -RemotePort 1701 -Action Allow -Profile Any

-Profile Any にしている理由は、このパケットが出ていくのは物理NICだからです。WFPログの localAddrV4 はクライアントの物理IP、remoteAddrV4 はVPNサーバのグローバルIP。適用されるのはVPNアダプタではなく、物理接続側のプロファイルです。持ち出し端末なら、社内ではDomain、自宅ではPrivate、社外ではPublicと変わります。-Profile Public だけにすると、社内へ持ち帰った瞬間に当たらなくなります。

以下は、ここに辿り着くまでの記録です。


以降、経緯の詳細についてです。

1件目:ESPが1パケットも出ない

Windows 11のL2TP/IPsec VPNが、Firewall全開放なら繋がるのに、公式の必要ポートに記載があるポートだけ開けると繋がらない。

成功時と失敗時のキャプチャを、Wiresharkを使って並べたところ、鍵交換までの全工程は、バイト単位で完全に一致していました。差が出たのは、その直後です。

成功時は、鍵交換後、同一ミリ秒でESPが出ていきます。失敗時は送受信とも0パケット。約19秒後にNAT-Tキープアライブが出るだけで、セッションが終わります。IPsec SAは確立しているのに、その上を流れるべきデータが1つも見えない状態です。

ここで1つ確定します。このキャプチャはクライアント自身のNIC上で取っています。経路上のFirewallが落としているなら、送信パケットはNICから出ていくので必ず写るはずです。写った上で応答が返らない、という形になる。

写っていない以上、遮断は経路上のFirewallではなく、クライアント内部で起きている。 この一点で、対向・経路・ゲートウェイ設定は今回の課題とは関係ないことが分かります。

ただし、ここで区別しておくことがあります。Wiresharkで「差」自体は見えています。 成功時にはESPがあり、失敗時にはない。しかし見えたのは「無い」ということであって、捨てられたパケットそのものでも、捨てた主体でもありません。どこで、何が、なぜ捨てられたのかは、この時点ではまだ分からないままです。

なぜESP(プロトコル50)ではなく、UDP/1701を疑ったのか

「ESPが出ていないならESPを開ければいい」と考えたくなりますが、ここは違いました。

今回はNAT-T環境です。ESPはプロトコル50としてではなく、UDP/4500に包まれて出ていきます。 そしてUDP/4500は既に開けてあり、実際にIKEのやりとりは通っていました。つまりESPが外側で落とされているわけではない。

だとすると、残る可能性は「ESPに包むべき中身が、そもそも来ていない」です。

ではESPは何を包んでいるのか。L2TP/IPsecは、IPsecをトランスポートモードで使い、L2TPが生成するUDP/1701を保護する構成です。ESPの中身はUDP/1701なのです。

中身が来なければ、ESPは作られません。UDP/1701がESPで包まれる前に落ちている、という仮説が立ちます。そして、それが当たりでした。

この時点では、キャプチャではなくカプセル化の構造から推論して当てています。2件目では、この推論が通用しませんでした。


エンドポイントの内側は、Wiresharkだけでは追えない

Wiresharkでは、パケットがないことは見えましたが、消えた場所は見えなかった。この差がどこから来るかというと、観測点の位置です。

WindowsのL2TP/IPsecは、L2TPが生成したUDP/1701のパケットを WFPで評価してから IPsecでカプセル化します。

L2TPドライバ(UDP/1701 を生成)
   ↓
WFP 送信フィルタ ← Firewall の規則はここで効く(破棄地点)
   ↓
IPsecドライバ(ESPでカプセル化、UDP/4500に包む)
   ↓
NDIS / NIC ← Wireshark(Npcap)が見るのはここ

Firewallが見ているのは平文側、Wiresharkが見ているのは暗号化後。 両者は同じ通信の別の段階を見ています。

UDP/1701はWFPで落とされ、ESPで包まれる段階まで到達しません。ワイヤ上へは最初から何も現れません。

つまり、エンドポイントの内側で、しかもファイアウォールの規則が原因かどうかを調べる場面では、Wiresharkだけでは戦えません。 Wiresharkが見ているのはNICの一点で、ファイアウォールはその手前でも仕事をしているからです。


2件目:方式を変えたら、同じ障害が戻ってきた

数週間後、同じ環境をL2TP/IPsecからIKEv2へ切り替えました。

結果は、VPN接続は成功するのに、トンネル内の通信が一切通らない。まったく同じです。

推測で開けていって、6回外した

素直に、必要そうなものから開けていきました。結果を順に並べます。

試したこと結果
UDP/500・4500を許可IKEは完走するが通信不可
TCP/80・443を許可外部HTTPSは通るがVPN内は不可
TCP・UDPを全許可変化なし
プロトコル50(ESP)を許可変化なし
プロトコル41・47を許可変化なし
プロトコル4を許可解決

TCPとUDPを全部許可しても直らない時点で、TCP/UDP以外のIPプロトコルが関わっているとは分かりました。そこからESP(50)、IPv6カプセル化(41)、GRE(47)と定番を当てにいって、全部外しています。

1件目と同じように構造から推論しようとして、外し続けたわけです。

そして重要なのは、正常時のキャプチャを見ても答えは出なかったことです。

全開放版に出現したプロトコルを全量列挙してみました。IPv4上に現れたのは UDP(17)・TCP(6)・IGMP(2) の3種類だけ。既に開けているものしか出てきません。プロトコル4は1本も写っていない。NAT-Tでの再カプセル化が済んだ後の姿しかNICに出ないからです。

ログに訊いたら、1回で出た

ここで必要になるのが、WFP側のログです。

netsh wfp capture start file=C:\temp\wfp.cab
#   VPN接続 → Test-NetConnection <社内DNS> -Port 53
netsh wfp capture stop

ドロップイベント1009件のうち、912件がプロトコル4の送信ドロップでした。

<ipProtocol>4</ipProtocol>
<localAddrV4>(クライアントの物理IP)</localAddrV4>
<remoteAddrV4>(VPNサーバのグローバルIP)</remoteAddrV4>
<msFwpDirection>MS_FWP_DIRECTION_OUT</msFwpDirection>
<filterOrigin>Default Outbound</filterOrigin>
<appId asString="System"/>

IPプロトコル4は IPv4-in-IPv4。IPv4パケットをIPv4で包んだものです。送信元がクライアントの物理IP、宛先がVPNサーバ。

なぜ1件目と違うものが流れていたのか。IKEv2のVPNはIPsecをトンネルモードで使うからです。トランスポートモードがL2TPのUDP/1701を保護していたのに対し、トンネルモードはIPパケットごと外側のIPヘッダでくるみます。その姿がIPプロトコル4です。

アプリ(内側のIPパケットを生成)
   ↓
IPsecドライバ(トンネルモードで外側IPでくるむ → プロトコル4)
   ↓
WFP 送信フィルタ ← 破棄地点
   ↓
NAT-T カプセル化(UDP/4500)
   ↓
NDIS / NIC ← Wireshark が見るのはここ

1件目の「観測点より上で消えたものは写らない」が、層を変えて再演されていたわけです。


なぜ、公式ドキュメントに書かれていないのか

MicrosoftがIKEv2向けに案内している必要ポートは UDP/500・UDP/4500・プロトコル50 の3つで、プロトコル4の記載はありません。調べた範囲では、この挙動を明記した公式文書を見つけられませんでした。

理由は、この構成を取る組織が少数派だからだと考えています。

意外に思われるかもしれませんが、主要なセキュリティベースラインは、送信を「許可(既定)」のままにするよう求めています。

  • DISA STIG(米国防総省の実装ガイド)— Domain / Private プロファイルとも、Outbound connections を "Allow (default)" に設定せよ
  • CIS Benchmark — 同じく Domain / Private とも "Allow (default)" を推奨
  • Microsoft — 可能な限り既定設定を維持することを推奨

理由は運用負荷です。送信をブロックにすると、許可すべき通信をすべて個別に登録しなければならず、Windows Update、Defender、Teams、OneDrive といったものが次々に止まります。「セキュリティ意識が高いから送信をブロックする」という整理ではないわけです。

実際に送信ブロックを採っているのは、業界標準に従った結果ではなく、独自の内部基準や調達仕様でそう決めている組織です。

つまり、この穴を踏む母数がそもそも小さい。だから文書化されず、検索しても出てきません。

技術的な理屈は単純です。Defender Firewallの送信は既定で「許可」なので、通常はこの層に到達しません。 BFE(Base Filtering Engine)は、UDP/500・4500についてはIKE/AuthIP用の免除フィルタを自動追加します。しかし、カプセル化後のデータ平面には同等の免除がありません。結果として、IKEだけ完走して、データだけが落ちます。

なお、この結論は今回のWFPログから読み取ったものです。 他のゲートウェイ製品やAlways On VPN構成で同じ挙動になるかは検証していません。同じ症状に当たった方は、この記事の結論を当てはめる前に、自分の環境で netsh wfp capture を取ってください。そのほうが速くて確実です。


エンドポイントには、エンドポイント固有の通信がある

2件とも、原因はたった1つの設定でした。送信規則が1本足りない。それだけです。

にもかかわらず、公式ドキュメントに載っている必要ポートを全部開けても直りませんでした。理由は単純で、その一覧が境界ファイアウォール向けだからです。

端末の内側では、境界機器には一度も現れないプロトコルが流れています。しかもその中身は、VPNの方式が変わると入れ替わります。トランスポートモードならUDP/1701、トンネルモードならプロトコル4。境界の外から見ている限り、どちらもUDP/4500の中に隠れていて、区別がつきません。

だとすれば、打ち手はこうなります。

  1. 必要ポート一覧を、境界向けとエンドポイント内部向けの2種類に分けて管理する
    公式の一覧は境界の外から書かれています。内部の地図は、自分で持つしかありません
  2. FW規則テンプレートに、内側のプロトコルを含める
    L2TPならUDP/1701、IKEv2ならプロトコル4の送信許可。VPNの方式を変えるときは、必ず内側を見直す
  3. ネットワーク障害の切り分けでは、WiresharkとWFPを両方取る
    成功時と失敗時、どちらの状態でも2つセットで取ります。Wiresharkは「何が流れたか」を、WFPは「何が捨てられたか」を持っています。片方だけでは、今回の2件はどちらも解けませんでした

そして4つ目に、ログの使い分けがあります。

netsh wfp capture は情報量が最大で、どの規則が落としたかまで分かります。ただし取っている間しか記録されません。事象を再現できることが前提です。

一方、Firewallのドロップログ(netsh advfirewall set allprofiles logging droppedconnections enable で pfirewall.log に出力)は情報が薄く、規則名も出ません。しかし常時回っているので、再現できない事象や、いつから起きていたのかという時間軸を、事後に振り返れます。

4. ドロップログとWFPは、代替ではなく補完として持つ

再現できる障害はWFPで規則まで特定する。再現できない・間欠的な障害は、ドロップログでしか追えません。ただしドロップログは既定4MBで上書きローテーションするため、常時有効にするならサイズを上げておかないと、見たい時刻の記録が先に消えます

VPNが繋がるのに通らない。そのとき、消えたパケットの行方を知っているのは、捨てた本人だけです。境界の外から書かれた地図には、その場所は載っていません。


参考情報


✍ この記事を書いた人

蔀 啓介(シトミ・ケイスケ)

株式会社SITOP 代表取締役

官公庁・自治体のITインフラ・サイバーセキュリティの大型案件に参画し、時にはエンジニア、時にはPMとして様々な案件を手がけている。Zscaler / Entra ID / Intune を活用したゼロトラスト設計を専門とし、設計から運用移行まで一気通貫で対応。

エンドポイント構築・運用について、相談先をお探しでしたらSITOPまでご連絡ください。

お問い合わせはこちら ▶

関連記事