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, プロトコル50 | UDP/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 stopwfp.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の中に隠れていて、区別がつきません。
だとすれば、打ち手はこうなります。
- 必要ポート一覧を、境界向けとエンドポイント内部向けの2種類に分けて管理する
公式の一覧は境界の外から書かれています。内部の地図は、自分で持つしかありません - FW規則テンプレートに、内側のプロトコルを含める
L2TPならUDP/1701、IKEv2ならプロトコル4の送信許可。VPNの方式を変えるときは、必ず内側を見直す - ネットワーク障害の切り分けでは、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が繋がるのに通らない。そのとき、消えたパケットの行方を知っているのは、捨てた本人だけです。境界の外から書かれた地図には、その場所は載っていません。
参考情報
- Microsoft Learn「Troubleshooting UWP App Connectivity Issues in Windows Firewall」(
netsh wfp captureの手順) - Microsoft Learn「Windows ファイアウォール規則」(既定設定の維持が推奨される理由)
- Microsoft Learn「Diagnose packet loss」(
Reason = 9(Inspection drop)の出力例) - Microsoft Learn「Packet Monitor (Pktmon)」(スタック内の複数地点での捕捉と破棄検出)
- Microsoft Learn「Audit Filtering Platform Packet Drop」(イベント5152 / 5157)
- DISA STIG「Windows Defender Firewall with Advanced Security」(送信接続は "Allow (default)")
- 「Npcap Users' Guide」(オフロードによりキャプチャと実際の送出が異なる件)
- IETF RFC 2003「IP Encapsulation within IP」(IPプロトコル4)
- IETF RFC 4303「IP Encapsulating Security Payload (ESP)」
- IETF RFC 7296「IKEv2」 / RFC 3948「UDP Encapsulation of IPsec ESP Packets」 / RFC 3193「Securing L2TP using IPsec」
✍ この記事を書いた人
蔀 啓介(シトミ・ケイスケ)
株式会社SITOP 代表取締役
官公庁・自治体のITインフラ・サイバーセキュリティの大型案件に参画し、時にはエンジニア、時にはPMとして様々な案件を手がけている。Zscaler / Entra ID / Intune を活用したゼロトラスト設計を専門とし、設計から運用移行まで一気通貫で対応。
エンドポイント構築・運用について、相談先をお探しでしたらSITOPまでご連絡ください。
