分割トンネルのリストは三つのアプリから始まり、最終的にはマシンの大部分を覆い、新しい行はどれも誰かの例外である。その時点でリストは、手順が増えただけのデフォルトに静かになり変わっている。フルトンネルはその配置を逆にし、文書化された除外がない限りすべてがトンネルに入る。それが単純かどうかは、ゲートウェイと、壊してしまうローカルサービス次第である。

まず、維持しているルールを数える

エントリを数え、そのうち何件に名前の付いた所有者と最後に検証した日付があるかを数える。重要なのは二つ目の数であり、参照しているソフトウェアが改名されたり置き換えられたりしたとき、所有者のいない例外は評価できない。実行ファイルのパスに紐づいたルールは更新後に静かに失敗し、その失敗は古いルールではなくVPNが不安定なように見える。リストについて意見を持つ前に、書き出しておく。

各エントリは、それがなければ何が壊れるのか、誰がそう決めたのか、理由が失効したことをどう気づくのかという三つの問いに答えるべきだ。三つすべてに答えられないエントリは、移行ではなく削除の候補であり、先に削除しておけば後の比較が正直になる。

ほとんどのエントリがトラフィックの大きな割合をルーティングしているなら、あなたはすでに保守の負担を伴うフルトンネルを動かしている。判断はデフォルトをどこに置くかであり、デフォルトを持つかどうかではない。

ゲートウェイがデフォルトを支えられるか確認する

フルトンネルはすべてのパケットを一つの機器に集めるため、その機器のCPU負荷、conntrackテーブル、アドレス変換、上り帯域の要件が同時に変わる。いくつかの社内サブネットを快適に扱っていたゲートウェイは、利用者の閲覧全体に合わせて設計されていないかもしれない。平均ではなく、最初に壊れるのはピークだから、想定される同時セッション数の最大値を見る。

ip -s link show dev tun0
conntrack -C
ss -s

仕様から推論するのではなく、変更の前後で同じ作業負荷を測る。一台で半日ほど普通に使えば、ゲートウェイが限界に近いかどうかが分かり、月曜の朝にそれを発見するのに比べれば費用はゼロに等しい。

経路のMTUも端から端まで確認するのは、完全なデフォルトがすべてのアプリをトンネルの最大パケットサイズにさらすからだ。トンネルの外で動いていたアプリが、これまで考える必要のなかった断片化の挙動に依存するようになることがある。

ローカルサービスとプライベートDNSがまだ動くことを確認する

ローカルに残す必要があるものをアプリ名ではなくプロトコルで列挙すると、プリンタとディスプレイの検出プロトコル、スマートホームのブリッジ、ルーターの管理ページ、LANでしか解決しない名前で到達するローカル開発サーバーなどが挙がる。これらはデフォルトルートがトンネルを指し始めると壊れ、しかもクライアント側では何もエラーを記録しないため静かに壊れる。

プライベートDNSももう一つの依存先であり、内部名が以前トンネルのリゾルバで解決されていたなら何も変わらない。ローカルで解決されていたなら、完全なデフォルトはそれをゾーンを知るリゾルバへ運ぶ必要がある。リゾルバ一覧が残ったと仮定せず、変更後に内部名と公開名を一つずつ試す。

ローカルの例外は、それを所有するプロファイルに書き込む。誰かの記憶にだけ残された例外は、次の移行で最初に失われるものだ。

一つのプロファイルを移行し、境界を検証する

以前の実験が残した手動ルートの上に新しいデフォルトを重ねるのではなく、プロファイル自身の設定を通して変更する。その残ったルートこそ、動いているように見えて一日後に一貫しない挙動をする移行のよくある原因である。古いプロファイルを利用可能なままにして、切り戻しが再構築ではなく選択になるようにする。

次に二つの境界、つまり公開先とプライベート先の両方が機能することと、望まないトラフィックがトンネルの外に出ないことを別々に検証する。ページの読み込み成功は前者を証明するが、後者については何も語らない。

ip route get 203.0.113.10
ip route get 10.40.8.15
resolvectl query intranet.example
curl -sS -o /dev/null -w "%{remote_ip}\n" https://example.com

再接続の後と障害の後に同じ確認を繰り返すのは、切断中に通信を遮断するスイッチが、その後正しく復旧するルートとは別の性質だからだ。より単純な設計とは、アプリやネットワークが変わった後でも実際のカバレッジを説明できる設計である。

関連記事