緑の接続アイコンが二つあっても比較に見えるだけで、たいていは偶然だ。もし試験リクエストがどちらのトンネルを使えた可能性があるなら、その結果は最良でも片方だけを説明し、最悪ならどちらも説明していない。 すべての観察にネットワークの文脈、意図した宛先、試験を実行する前に書いた期待を与える。自分で管理する Linux では、名前付きネットワーク名前空間がその分離を手に入れる最も安い方法だ。

緑のランプが二つ点いても比較ではない

名前空間はルーティングテーブル、インターフェース、ネットワークスタックの状態を分離するので、一方の中で開始したリクエストはもう一方のトンネルを黙って借りることはできない。分離しないのは CPU、物理的なアップリンク、ホスト上で動くリゾルバのデーモンだ。まさにこの最後の隙間で、こうした試験の多くが誰にも気づかれないまま失敗する。名前空間を出てホストのリゾルバに問い合わせる検索は、試験中のトンネルと何の関係もない答えを返す。

この手順は、すでに用意され承認された二つの試験用名前空間、機能する外部接続、対応するクライアントを前提とする。何も作成せず、何も登録せず、どの設定も置き換えない。クライアントが完全なデスクトップセッションを必要とする場合や、その外での実行を拒む場合は、別々の仮想マシンが正直な選択だ。

最初の実行の前に期待を固める

文脈ごとに成功の形を決める。リゾルバ、サービス名、期待するアドレス、トンネルが落ちたときに求められる振る舞いだ。これらの計画値は専用の列に置く。計画と観察を混ぜた記録は時刻印の付いた作り話にすぎない。下のチェックリストが記録に必要な形であり、最初の接続の前にどの行も埋められる状態でなければならない。

TunnelOwnerClient interface inside the namespaceProof commandRequired on disconnect
vpn-athe identity that owns profile A, recorded by nameits own tun device, never the host'sip -n vpn-a -4 route get 10.55.10.20traffic stops; no host-side fallback
vpn-ba separate owner, even when both run on one boxits own tun device in its own namespaceip -n vpn-b -4 route get 10.55.20.20verified separately, never inferred from A

リゾルバの配線は、最も嘘をつきやすい項目なので、その記録で自分の行を持つべきだ。名前空間に結び付いたファイル、たとえば /etc/netns/vpn-a/resolv.conf は、コマンドが名前空間の中で実行されるとき慣れた経路に現れる(iproute2 の名前空間の解説 が述べるとおり)。しかし、名前サービスの切り替え設定とそれが起動するローカルのリゾルバは、検索をホスト側へ引き戻すことがある。

一度に一つのトンネル、もう一つは切断

B を落としたまま A を既存の所有者経由で接続し、管理用の文脈からポリシー、ルート、選択された経路を調べる。下のコマンドのうち三つは状態を読むだけで、名前サービスに触れるのは最後の一つだけであり、どれもアプリケーションの要求を送らない。

sudo ip -n vpn-a -4 rule show
sudo ip -n vpn-a -4 route show table all
sudo ip -n vpn-a -4 route get 10.55.10.20
sudo ip netns exec vpn-a getent ahostsv4 svc-a.lab.internal

ルート検索は宛先についての仮定の問いに答えるものなので、サービスが通信を受け入れることは示せない。この二種類の証拠は別の列に置く。拒否された接続の隣にある健全なルートは、現実によくある結果だからだ。次に実際のアプリケーションで無害な許可済みの要求を一つ送る。A の文脈で、その通常の非特権ユーザーとして起動し、証明書の検証とアプリケーションの認証はそのままにしておく。そしてサービスが見た送信元アドレスとともに結果を記録する。A をその所有者経由で切断し、B についても同じ基準線をすべて繰り返す。加えた設定変更は必ず記す。さもなければ二つの基準線は比較できなくなる。

両方上げてから、一度に一つ落とす

定常状態は簡単な部分だ。両方のトンネルが接続された状態で、各文脈の検索とアプリケーション要求を繰り返し、そのあと片方のトンネルを切って他方を確認する。接続の順序そのものが問いであるときは、逆の順序で再接続する。

sudo ip netns exec vpn-a tcpdump -ni any port 443 -c 5
sudo ip netns exec vpn-b getent ahostsv4 svc-b.lab.internal
sudo ip -n vpn-b -4 route get 10.55.20.20

キャプチャは、アプリケーションの結果では決着しない議論を決着させる。要求が期待したインターフェースから出たのか、まったく別のものを通ったのかを示す。遷移のたびに、所有者の操作、時刻印、ルートの結果、名前の結果、アプリケーションの結果を記録する。そのうえで、影響を受けた名前空間の中でフェイルクローズの要件を確認する。隔離はキルスイッチではないからだ。名前空間は二つのトンネルを分けておくが、プロファイルが通信を止めるべきだと述べているときに、どちらかが通信を運ぶのを防ぎはしない。

この記録が主張できることとできないこと

合格は、この配置について、このホストで、その時点の観察を証明する。二つのクライアントが一つのデスクトップ用ルーティングテーブルを共有する場合については何も言わないし、両方のトンネルが負荷を運んでいるときのスループットについても何も言わない。それらは別の試験を伴う別の問いであり、比較は各行に添えられた文脈の分だけしか良くならない。

失敗も成功の隣に記録し、その時点でどちらのトンネルが上がっていたかを付記する。測定時点の状態を隠すきれいなページは、それを示す見苦しいページより悪い。記録を後で再利用できるようにするのは、点数ではなく文脈だ。

一つのマシン上の二つのトンネルは正直に比較できるが、実際に制御した文脈の数の中だけでしかない。それを超えるものは、横に緑のアイコンが付いた願望にすぎない。

関連記事