Windowsファイアウォールが単独でキルスイッチとして機能するかを尋ねると、自信に満ちた相容れない二つの答えが返ってきます。一方はインターフェース種別の規則がすべてを担うと言い、他方はスクリプトなしでは動かないと言います。どちらも同じ仕組みの半分を説明しているだけです。ファイアウォールは遮断を表現できますが、結果が本当にフェイルクローズになるかは三点にかかっています:Windowsがトンネルアダプターをどう分類するか、エンドポイントの例外が生き残るか、そして名前解決とIPv6が覆われているかです。どれか一つを誤ると、機械は漏えいするか接続をすべて失います。

三つの条件、この順序で

第一の条件は分類であり、望む規則がそもそも表現できるかどうかを決めます。Windowsファイアウォールの規則はインターフェース種別で絞り込めます:有線、無線、リモートアクセスです。物理種別で外向き通信を遮断しつつトンネルを許可する方針は、Windowsがトンネルをリモートアクセスと認識する場合にのみ機能します。

第二の条件はエンドポイントの例外です。トンネルが存在する前に、クライアントは物理アダプター経由でVPNサーバーに到達しなければならず、そのアダプターを一律に遮断すると、遮断を不要にするはずの接続そのものを妨げます。例外はサーバーとそのポートを名指ししなければならず、パケットはまだ上がっていないトンネルではなく物理ゲートウェイから出る必要があります。

第三は網羅性です。IPv4を遮断してIPv6を忘れる規則群、またはエンドポイント検索のためにローカルリゾルバーを許可し、結果として他のあらゆる検索も許可する規則群は、キルスイッチが存在する理由であるまさにその窓でオープンに失敗します。これはファイアウォールの不具合ではなく設計の隙間です。それは机の上でのあらゆる試験を生き延びる隙間でもあります。

分類が最初の関門です

一つの規則も書く前に、Windowsがアダプターをどう見ているかを確認します。Windows標準のVPN接続は通常リモートアクセスとして現れます。独自の仮想アダプターを作るサードパーティ製クライアントは有線として現れることが多く、有線アダプターに限定した遮断はトンネルも遮断することを意味します。

Get-NetConnectionProfile | Select-Object Name,InterfaceAlias,NetworkCategory
Get-NetAdapter | Select-Object Name,InterfaceDescription,Status,ifIndex
Get-NetFirewallProfile | Select-Object Name,Enabled,DefaultOutboundAction

三番目のコマンドは、既定の外向き遮断がすでに有効かを示し、設計の形全体が変わります。既定がすでに遮断なら、緩い基準への例外ではなく許可の規則を書くことになり、はるかに筋道立てて考えられます。

トンネルアダプターが有線として報告されるなら、フェイルクローズ設計にファイアウォール単体は適切な道具ではなく、規則をどう調整しても変わりません。あらゆるフォーラムの第二の意見が正しいのはこの場合です。

エンドポイントの例外には規則だけでなく経路も必要です

分類が機能すると仮定します。例外は二つの部品からなり、それらは別のサブシステムに住んでいます。ファイアウォールの規則は通信を許可し、ホストの経路はトンネルが落ちている間に正しいインターフェースから出るようにします。

New-NetFirewallRule -DisplayName "VPN endpoint allow" -Direction Outbound -Action Allow \
  -Protocol TCP -RemoteAddress 203.0.113.9 -RemotePort 443 -InterfaceType Wired,Wireless
New-NetRoute -DestinationPrefix 203.0.113.9/32 -InterfaceIndex 12 -NextHop 192.168.1.1
Get-NetRoute -DestinationPrefix 203.0.113.9/32

経路がなければ、エンドポイントの例外は既定経路がまだ物理ゲートウェイを指している間しか役立ちません。クライアントが独自の既定経路を入れて停止すると、許可されたパケットの行き先がなくなり、接続を再確立できません。その失敗は壊れたクライアントに見えますが、実体は欠けた経路です。

例外はクライアントが許す限り狭く保ちます。一つのアドレスと一つのポートはレビューできますが、プロバイダーのネットワーク全体を覆う範囲はできません。その広い規則は同じプロバイダーでホストされる他のすべても許可し、たいてい意図より広くなります。

DNSとIPv6がオープンに失敗する場所です

名前解決は古典的な漏えいです。エンドポイントがホスト名なら、クライアントはトンネルが存在する前にそれを解決する必要があり、物理アダプターにリゾルバーへの到達を許すことになります。同じ許可はトンネルが落ちている間の他のあらゆる検索も外に出し、一度の検索でこれから訪れる先が明らかになります。

IPv6が二つ目です。IPv4向けに書かれた規則はもう一方のファミリーを覆わず、多くのクライアントはIPv4経路しか入れません。そのためネイティブなIPv6接続を持つ機械は、IPv4側が固く遮断されていてもインターネットと話し続けられ、キルスイッチはその間ずっと成功を報告します。

GapWhat leaksControl
Resolver permitted for endpoint lookupEvery name queried while downPin the endpoint as an address, or block non-tunnel DNS
Rules only for IPv4Full IPv6 connectivityAdd the same rules for the other family
Application bound to physical interfaceIts own trafficFirewall cannot fix this; change the binding

三行目は回避するのではなく理解する価値があります。ファイアウォールはパケットについて決めますが、アプリケーションがどのインターフェースを使いたいかについては決めませんし、明示的にバインドするプログラムは制御しにくいことがあります。これはアプリケーションの下で動くクライアント側キルスイッチを支持する論拠であり、規則を増やす根拠ではありません。

ケーブルを抜くのではなく、クライアントを止めて試験します

意味のある唯一の試験は、守ろうとしている失敗を模倣するものです。サービスを止めるか、プロセスを終了するか、クライアントが作ったアダプターを無効にしてから、インターネットと名前への到達を試します:

Stop-Service -Name "YourVpnService" -Force
Test-NetConnection -ComputerName 1.1.1.1 -Port 443
Resolve-DnsName example.com
Test-NetConnection -ComputerName 2606:4700:4700::1111 -Port 443

三つとも失敗するはずです。一つ目が成功すれば遮断は効いておらず、一つ目が失敗したのに二つ目が成功すればDNS漏えいがあり、三つ目が成功すればIPv6が覆われていません。それぞれの結果は上の隙間のちょうど一つを指します。

スリープと復帰の後に試験を繰り返します:Windowsがネットワークをパブリックかプライベートか判断するとファイアウォールプロファイルが変わり、プロファイルに限定した規則はそれに従うからです。机の上で持ちこたえ列車で失敗する設計は、一度だけ試験された設計です。

分類の関門やDNSの要件でファイアウォール単体の手法が使えないなら、クライアント側のキルスイッチが正直な答えです。トンネルが代わりにルーターで終わるなら、方針はルーターが持つべきです:そこでの一つの規則が背後のすべての機器を覆い、Windowsがアダプターをどう呼ぶかに依存しないからです。

関連記事