ネスト VPN:外側の接続を運ぶのはどのトンネルか
内側のトンネルには、自分の端点までの外側の経路が必要だ。起動順序を誤った2つのクライアントは経路の衝突を生むので、まずネストを直す。
同時に動く二つの VPN クライアントはネストしたトンネルを作らず、作るのは二本のトンネルと経路をめぐる言い争いだ。ネストしたトンネルは、内側のクライアントが自分のサーバーへ向かう接続そのものを外側のトンネルが運ぶときに存在し、それは意図して組む配置である。うまくいけば内側のサーバーは外側のサーバーのアドレスを見るが、失敗すれば片方のクライアントがもう片方を黙って迂回して再接続する。ネストが本物か偶然かは三つの条件で決まる。
三つの条件がネストを決める
第一は、どの端点がどの経路を必要とするかだ。内側のサーバーのアドレスを書き、外側のサーバーのアドレスを書き、内側のサーバーは外側のトンネル経由でしか届かないと明示する。ほかのすべてはその一文から導かれ、どの経路がどの表に入るかも含まれる。
第二は、各層で経路を見られるかどうかだ。特定の宛先がどの経路を使うかをカーネルに問い合わせられないなら、最終的な出口 IP から連鎖を推測していることになり、それはネストと偶然を区別できない証拠そのものだ。
第三は、外側のトンネルが落ちたときに何が起きるかだ。内側のトンネルは一緒に止まることも、通常のネットワークで再接続することも、外側の経路が戻るまで塞がれたままになることもでき、どれも擁護できる方針だ。同じ方針ではなく、多くのクライアントの既定の振る舞いは二番目である。接続が健全だと表示しながら物理ネットワーク経由で端点に再接続するクライアントは、意図した連鎖が静かに無関係な二本のトンネルになる最もよくある道だ。
条件一:どの端点がどの経路を必要とするか
ip route get 203.0.113.10 はその問いに直接答え、経路、送信元アドレス、そしてカーネルが今その宛先に使うインターフェースを出力する。
内側のクライアントを起動する前に内側のサーバーで一回、起動後にもう一回実行して比べる。答えが物理インターフェースから外側のトンネルのインターフェースに変われば、その時点でネストは本物だ。変わらなければ、パネルが何と言おうと内側のクライアントは直接接続している。外側のサーバーのアドレスでも繰り返すが、こちらは今も物理インターフェース経由で解決される必要があるのは 両方の端点を再帰的に取り込む経路 は、機械をネットワークから完全に外す障害だからだという点だ。
条件二:各層で経路を調べる
現代のクライアントでは経路選択は主表だけではない。ポリシールールは印を付けたパケットを別の表へ送れるし、クライアントは自分のソケットをインターフェースに縛れるし、コンテナや名前空間は独自の表を持つ。ip rule と ip route show table all が、そのうちどれが効いているかを見つける手段だ。
自分のソケットに SO_MARK を付けるクライアントや、特定のデバイスに縛る設定のクライアントは、あなたが整えたつもりの既定の経路を迂回する。これは不具合ではなく機能で、信頼できる確認はクライアントと同じ名前空間で動くものだけだという意味になる。クライアントがコンテナで動いているなら、ホストではなくそのコンテナの中で確認を実行する。
条件三:外側のトンネルが落ちたときに何が起きるか
障害時の振る舞いは既定値ではなく決定を要する。外側のトンネルが消えたとき内側のトンネルをどうするかを書き、そのとおりにクライアントを動かす。
選択肢は具体的だ。外側の経路が消えたときに内側のクライアントを止めれば、清潔な連鎖と明らかな障害が得られる。そのまま直接再接続させれば可用性が得られ、連鎖が備えるはずだった性質は静かに失われる。外側の経路が戻るまで塞ぐのは最も厳しく、運用上も最も面倒で、外側のトンネルの揺れがすべて目に見える事故になる。
設定を読んでもどれになるか分からないので、無害な通信と意図的な外側の障害で三つとも試すこと。外側のトンネルを落とし、内側のクライアントが何をするかを見て、落ちている間に経路をもう一度確認する。そのあと外側のトンネルを戻し、内側のクライアントをその間に選んだ直接経路に残さず、連鎖が組み直されることを確かめる。
連鎖が与えないもの
層を増やせば端点、鍵、故障の種類が増えるが、匿名性の保証は増えず、外側の運用者にトンネルの存在を見せないようにもできない。ネストが何を守るかという主張は、どの観察者から守るのかを必ず名指ししなければならない。
成果物は動く接続ではなく、どの端点がどの経路を使うか、外側の障害で何が起きるか、現在の状態を示す三つのコマンドを書いた短い文書だ。strongSwan の転送についての文書 は、Linux ホスト上でトンネルの通信がインターフェース間でどう転送されるかを知るのに役立つ。あなたの連鎖を生んだ既定値は契約ではないので、クライアントの更新のたびに確認をやり直すこと。点検できないネストしたトンネルは、状態灯の付いた噂にすぎない。