ゲスト VPN とホスト VPN:実際に勝つのはどのルートか
二つのクライアント、二つの既定ルート、そして一つの紛らわしい症状。ゲストの接続形態を記録し、その端点を外向きにたどり、それから一度に一つずつ変数を変えます。
二つのクライアントが同時に動いており、どちらも自分が既定ルートを所有していると信じているが、症状は奇妙な形で現れ、ゲストのあるアプリケーションは動作するのに別のアプリケーションは誤った場所に解決される。ゲスト内の VPN とホスト上の VPN は共存できるが、それは外側の経路と内側のポリシーが、誰が何を運ぶかについて一致している場合に限られる。両方を起動しても、それだけで連鎖ができるわけではない。まず接続形態を記録し、それから一度に一つだけ変える。
まずゲストの接続形態を記録する
ゲストは、ハイパーバイザーが与えた経路、つまりホストの背後にある NAT、物理セグメントへのブリッジ、あるいは上にルーティングを足したホストオンリーネットワークで自分の VPN サーバーに到達する。接続形態が変われば、ゲストに見えるものと、ホストがそのトラフィックに対してできることが変わる。NAT の下ではゲストのパケットはホストから来たように見えるため、ホスト自身のトンネルがゲストに何も知らせずにそれらを運ぶことがある。ブリッジの下では、ゲストはセグメント上に自前の存在と自前の既定ゲートウェイを持つ。
設定に触る前に、どのクライアントがどのアプリケーションを運ぶべきかとあわせて接続形態を書き留める。この一文がこうした案件の大半を解決するのは、二つのクライアントがたいてい異なる前提の上に作られているからだ。ホストのトンネルを使うことを期待されるゲストは、競合する既定ルートを自分でも持っていてはならない。
ゲストの端点を外向きにたどる
ゲスト VPN は、ほかの何かが動く前に、自分のサーバーへの使える経路を必要とする。ホストのトンネルが上がっていてゲストが NAT の背後にいる場合、ゲストのハンドシェイクはホストのトンネルを通って出ていくが、それが設計なのか、誰も記録していない事故なのかは分からない。ホストのトンネルが落ち、ゲストがそれに依存していた場合、ゲスト側に一つの変更もないままゲストは接続を失う。端点を外向きにたどれば、そのどちらなのかが分かる。
どちらの文脈でも、広いルートはもう一方のクライアントが期待していたトラフィックを捕まえる。ゲスト内の 0.0.0.0/0 ルートとフルトンネルのホストクライアントはどちらもすべてを主張し、最後に適用されたほうが勝つ。ゲストの仮想ネットワーク、ローカル LAN、リモートネットワークの重なりは、プライベートなプレフィックスについて同じ効果を生み、失敗は認証の問題のように見え、アドレス変換の振る舞いは コンテナネットワーク について説明されているものと同じだ。
変更前と変更後の記録を比べる
ホストのトンネルを切った状態、またはポリシーが許す任意の統制された状態で基準を取り、ゲストのルートとリゾルバーを記録する。そのうえで組み合わせた設定を適用し、二つの記録を比べるが、プライバシー要件は損なわない。直接の基準が適切でない場合は、比較を省くのではなく、その制約を記録に書き込む。
ip route get 10.20.30.41
ip rule show
resolvectl status --no-pager | head -12
ルート問い合わせは、特定の宛先を運ぶインターフェースと送信元アドレスを名指しする、この調査で最も役に立つ一行だ。ルール一覧は、ポリシールーティングが一部の宛先を二番目のテーブル経由で送っているかどうかを示す。リゾルバーの出力は、DNS がゲストのトンネルに従ったのか、ホストの経路にとどまったのかを示す。同じ三つのコマンドを変更の前と後に実行すれば、差分が犯人を名指しする。
再起動をまたいでも所有権を明確に保つ
ホストクライアントのローカルアクセス制限は、仮想 NAT やブリッジへのトラフィックを遮断することがあり、その制限はしばしばゲストの資格情報の問題と取り違えられる。テストを通すために制限を無効にするのではなく、クライアントの文書化された挙動を読む。サポートされた修正のあとで、ゲストのアプリケーションと必要な失敗ポリシーを再試験する。再接続に成功したホストは、ゲストのルートやリゾルバーについて何も証明しない。
既定ルートをどちら側が所有するかを決め、それを運用書に書く。ゲストの再起動や、所有権を静かに反転させるホストのネットワーク切り替えは、決して悪くなかった VPN についてのバグ報告を生む。その取り決めは、なぜ動いていたかを誰も覚えていないまま再起動を生き延びるべきだ。