Kill switch と重複禁止の規則は逆方向を指しており、それが通常の VPN 設定で後者が決して表現されない理由である。Kill switch は落ちたトンネルに反応するのに対し、この要件は上がっているトンネルに反応し、アプリケーションを画面から外しておく。一つの設計判断が大部分を決める。アプリを停止するのか、起動を妨げるのか、それともネットワークアクセスだけを奪うのか。ファイアウォール規則やプロセスを殺すループに手を伸ばす前にその層を選ぶべきである。観測によって強制される規則は、起動のたびに窓を漏らすからだ。

神話:kill switch はプログラムの起動を止める

Kill switch はトラフィック制御であり、その点に正直である。トンネルの状態に応じてパケットを許可または拒否する。どれもプログラムの起動を拒否せず、どの実行ファイルがソケットを開いたかを検査しない。デスクトップのショートカット、スケジュールされたタスク、バックグラウンドのヘルパーは、アプリの名前を知る何かを通らずにネットワークに到達する。この二つの仕組みの距離こそ、ほとんどの混乱が住む場所である。

プログラムの起動可否を本当に決める仕組みはアプリケーション制御である。Windows では AppLocker か WDAC、管理された macOS ではデバイスプロファイルが強制する許可リストを意味する。どちらもトンネルとは独立しており、だから二つの要件は同じチケットにまとめられ、その後どちらも満たされない。

道具に名前をつける前にモードに名前をつける

規則を三つの状態を持つ状態機械として書く。通常使用、VPN 作業セッション、退出である。禁じられた重複は中間の状態に属し、クライアントソフトウェアのものではない。

状態を変える者は、順に三つの行動を持つ。アプリの作業を終え、通常の終了を要求し、トンネルが上がる前にインスタンスが消えたことを確認する。順序は反対側でも重要である。先に接続し後でプログラムを止める VPN は、すでに重複を許している。要件が接続確立を含むなら、接続済み表示を待つのは遅すぎる。

双方向の競合が実際にすること

本当に systemd が管理する二つのサービスでは、Conflicts= は対称である。一方を開始すると他方が停止する。ユニットのリファレンスはその挙動を記録し、一方が停止を終えてから他方が開始する必要がある場合には明示的な順序を別途要求する。その順序の記述がなければ、停止と開始が競争し、結果はタイミング次第になる。

これは拒否リストではない。依存関係を逆につなぐと、アプリの起動が代わりに VPN を止める。予測可能な瞬間にトンネルがひとりでに切断するとき疑うべき失敗はこれである。デスクトップアプリは systemd ユニットではなく、NetworkManager の接続もユニットではない。だからこのパターンは自分で包んだサービスにしか効かない。

最初の起動だけでなく遷移を確かめる

四つの遷移が要件の成否を決める。アプリを動かしたままセッションに入る、セッションの途中で再起動する、VPN の起動に失敗する、意図的に切断する、の四つである。それぞれを試し、結果をユニットファイルのそばに置く。以下のコマンドは現在の関係を読み、最も重要な遷移を試す。

systemctl show work-vpn.service -p Conflicts -p After
systemctl start work-vpn.service
systemctl is-active office-sync.service
nmcli connection show --active

三番目のコマンドはアプリを非アクティブのままにし、四番目はセッション実行中にトンネル接続だけを一覧するはずである。違う結果なら、その遷移はまったく強制されていない。

セッション中の再起動は、ラッパーに基づく設計を露呈させる事例である。デスクトップから起動されたショートカットは起動スクリプトに決して相談しない。この回避が重要なら、強制はアプリケーション制御に属し、VPN クライアントではない。セッションの終わりも記録し、入る際に止めたすべてのプロセスを開き直すのではなく、意図的な再開を選ぶ。各遷移の結果は、ユニットファイルを保管する同じメモに記す。

関連記事