インクルード方式かエクスクルード方式か:スプリットトンネリングの既定値はどちらにすべきか
リストを作る前に既定値を決める。名前を挙げたものだけをトンネルに入れるのか、すべてをトンネルに入れて例外を切り出すのか。決めたら、誰もリストに入れていないアプリで試す。
VPN クライアントのルーティング設定を開くと、同じラベルをまとった形の異なる二つのコントロールが目に入る。一方はトンネルに入れる宛先を列挙させるもので、それ以外はローカルネットワークを使い続ける。もう一方はすべてがトンネル経由だと前提し、何を外へ戻すかを尋ねる。どちらも最初のテストではトンネルとして機能し、どちらもリストに行を足して維持するため、誰かが新しいものをインストールするまで両者の違いは見えないままだ。
これは機能ではなく既定値の選択だ。リストの項目が二十件になる前に決めておく。
既定値はパンフレットではなくクライアントから読み取る
WireGuard ではこの判断が異例なほど見えやすい——AllowedIPs はインクルードのリストそのもので、それ以外の意味はない。0.0.0.0/0, ::/0 を指定したピアはすべてをトンネルに入れ、10.20.0.0/16 を指定したピアはその範囲だけをトンネルに入れる。除外の書式は存在しないので、あるサブネットだけを外したいなら、他のすべてのプレフィックスを列挙するか、インターフェースの外側でポリシールーティングを追加するしかない。
OpenVPNは逆方向から同じ地点に達する——redirect-gateway def1 で全トンネルを張り、route ディレクティブで特定のプレフィックスを追加または上書きする。市販のクライアントは両方をチェックボックスと宛先テーブルの裏に隠していることが多いので、ラベルを信じる前にテーブルが実際にどちらを編集しているのかを確かめる。
尋ねるべきは、そのチェックボックスが何と呼ばれているかではない。どちらのリストにも載っていない宛先のパケットがどうなるかだ。それを文書に書き出せば、残りの設定はそこから導ける。この問いを飛ばすと、最初の原因不明の障害は、その日クライアントに一番近い人によって決められてしまう。
リストに載っていないアプリを追いかける
インクルード方式ならそのアプリはローカルネットワークとローカル DNS で直接出ていき、エクスクルード方式ならサーバーが許す範囲でトンネルを通る。新しい SaaS ツールが初日から動くか、VPN が壊したというチケットが上がるかの違いは、しばしばここで生まれる。
どちらの既定値も、それ自体がより安全というわけではない。インクルード方式はトンネルが運ぶ範囲を狭めてローカルネットワークを最も抵抗の少ない経路にし、エクスクルード方式はトンネルを通常の経路とみなして例外を例外として扱う点で、大半の企業ポリシーが実際に意図していることに近い。
| Question | Include-only | Exclude-only |
|---|---|---|
| Unlisted new app | goes direct | goes through the tunnel |
| A site that breaks over the VPN | add it to the list | carve it out |
| Internal names still resolve | only if routed and served | usually, until split DNS says otherwise |
| Upkeep | one entry per internal service | one entry per misbehaving public service |
プラットフォームが一覧するオブジェクトの種類に注目する
Android の VpnService.Builder は、許可アプリのリストと禁止アプリのリストを別々のモデルとして公開しており、アプリ単位のルールは宛先ではなくパッケージで選ぶ。そうしたリストに入れたブラウザは、開くすべての宛先を抱え込むことになり、ルートテーブルとは粒度が違うため、動いているアプリの中の壊れた一つのサイトだけを直すことはできない。
デスクトップ向けのクライアントはたいてい両方の種類を一つの画面に混在させるので、これから追加する行がパッケージなのか、ホスト名なのか、プレフィックスかを確かめる。両者は失敗の仕方も、解決する場所も違う。ホスト名の行はたいていルートと名前になり、パッケージの行はクライアント内部のポリシー判断になる。後でデバッグする人は反対のほうを前提にするので、どちらを追加したのかを書き残しておく。
失敗する状態を試す——うまくいく経路だけでは足りない
トンネルから外したアプリが、自動的にきれいな直接アクセスを得るわけではない。クライアントが VPN なしの通信を遮断する規則も同時に適用している場合、外した通信は丸ごと落とされることがあり、それはルーティングの判断ではなく壊れたアプリのように見える。利用者の報告から知るのではなく、その状況をわざと試す。
次に DNS と IPv6 を別々の項目として確認する——IPv4 しか通さないトンネルは、v6 対応のアプリに回り道を残す。split DNS は、そもそもトンネルを通らない通信で内部名が引けるかどうかを決める。一覧にあるアプリ、一覧にないアプリ、名前の解決、再接続を一度ずつ動かし、結果を設定と一緒に残す。
既定値は次の人が見つけられる場所に書く
選んだ既定値、例外、その持ち主をクライアントプロファイルと同じ場所に記録する。次の管理者はこの理屈を読まずに項目を足すからだ。日付と例外ごとの理由も添えておけば、その後直ったサイト向けの古い除外を自信を持って消せる——理由のないリストは際限なく育つ。
壊れた宛先が一つ報告されたら、基準ではなく例外のほうを変える。一つのサイトを直すために既定値を反転させると、一覧にないすべてのアプリが黙ってトンネルの反対側へ移る。