ルールは正確に聞こえる。プライベートプロファイルではローカル通信を許可し、パブリックでは VPN 通信だけを許可する、というものだ。だがそうではない。ネットワークプロファイルはどのファイアウォールルールセットが適用されるかを選ぶだけで、どのアダプターがパケットを運んだかは何も語らない。プロファイル名を経路の要件として扱うのが、制限された出口の設計を、実際には未完成なのに完成したように見せる誤りだ。

まずフローを書き出し、そのうえで各フローを本当に強制できる仕組みを決める。そのフロー一覧だけが、次のルール変更を生き延びる成果物だ。

カテゴリが選ぶのはルールであり、経路ではない

Windows がネットワークをパブリックまたはプライベートに分類すると、ファイアウォールはそのプロファイル用に構成されたルールセットを適用する。分類はアダプターが接続したネットワークに従い、ルールセットはそこで何が許可されるかを決める。どちらの事実も、アプリケーションの通信がトンネルを使ったかどうかには依存しない。この独立性こそが難しさのすべてだ。

経路の選択を行うのはルーティングであり、インターフェースメトリックとトンネルがインストールするプレフィックスによる。したがって、プロファイルがパブリックと表示されていても、アプリケーションの接続が物理経路を通ることがあり、ファイアウォールはそれでもパブリックのルールセットが適用されたと報告する。

だからプロファイルに限定したルールはトンネルのみを意味できない。この二つの性質は別のコンポーネントが決めるもので、一方が他方を代わりにはできない。

FlowWhat decides itWhat a rule can enforce
VPN client to its endpointRouting plus the outer transportAllow the client process before the tunnel exists
Application to an internet hostInterface metric and prefix lengthBlock the process unless the tunnel interface is up
Application to a LAN hostLocal subnet routeAllow one destination, not the whole category

明示的なブロックは狭い許可より優先される

Microsoft のファイアウォールルールのガイダンスは、既定のブロック動作に対する許可の例外と、許可と衝突する明示的なブロックを区別している。明示的なブロックがその衝突に勝ち、送信ルールも同じ優先順位に従う。

つまり、すべてをブロックするルールを追加し、その上に置いた狭い許可に頼るという一般的な処方は、書き手が期待するようには動かない。Windows ファイアウォールは、管理者が割り当てたルール順で衝突を解決しない。ブロックが単に適用され、接続するアプリケーションはタイムアウトを報告する。例外に見えたルールは最初から競争に参加していなかった。

サポートされる形は、承認済みの許可ルールを伴う既定拒否のポリシーであり、各許可がプログラム、サービス、宛先をレビューできる程度に正確に指定する。その設計は監査に耐える。すべての例外が見え、どれも作成順に依存しないからだ。

互いに矛盾する二つのルールは一つのルールより悪い。結果の挙動が正しいと同時に説明不能になるからだ。

送信ポリシーに単一の所有者を与える

サポートされた VPN クライアントは、すでに独自のブロック動作と独自のエンドポイント例外を維持している。調整されていない手動ルールを追加すると、そのクライアントがセットアップに必要なトンネルの外に取り残されたり、誰も気づかない第二の経路が開いたままになったりする。

ルールを書く前に、送信ポリシーの所有者を決める。クライアント自身の構成、管理されたファイアウォールポリシー、所有者を明記した文書化されたローカル例外リストのいずれかだ。そのうえで、何かが接続するまで実験を積み重ねるのではなく、層を調整する。名前のある所有者は、二つの層が食い違ったときに尋ねる相手でもある。

何かを変える前に復旧経路を確保する。自分自身の管理経路から締め出された遠隔マシンは、閉じようとしていたポリシーの穴より悪い結果だ。復旧ルールは、あらかじめ書き留めておけば正当化しやすく、誰も好まない時間帯に変更が失敗したときに見つけやすい。

ラベルを読む代わりに四つの結果を試す

ポリシーは、区別できるケースの数だけの価値しかない。だからプロファイルのラベルは結果ではなく出発点として扱う。四つの結果が機能するかどうかを示す。意図した LAN 要求が成功し、対象に含まれるインターネット要求が成功し、禁止された直接要求が失敗し、トンネル障害のケースが静かに退避するのではなく設計どおりに振る舞う。四つの結果をルール変更の隣に書き留める。名前のある四つのケースからなるテスト計画は、毎回実行できるほど短く、大きな音で失敗するほど具体的だ。

Get-NetConnectionProfile | Select-Object Name,NetworkCategory,InterfaceAlias
Get-NetFirewallProfile | Select-Object Name,DefaultOutboundAction
Get-NetFirewallRule -Direction Outbound -Enabled True | Where-Object Action -eq Block |
  Select-Object DisplayName,Profile

最初のコマンドは、接続された各ネットワークがどう分類されているかを示す。これは多くの場合、ルールを書いた人が想定したものではない。二番目はプロファイルごとの既定の動作を示し、三番目は有効な送信ブロックを一覧する。狭い許可を静かに上書きするものも含まれる。

ネットワーク変更のあとで四つのケースをもう一度実行する。マシンが別のネットワークに参加するとプロファイルが再分類されることがあるからだ。プロファイルのラベルが一致することは、経路が意図したものだった証拠にはならない。

関連記事