1台のPiで2つのVPNホップ:どのルートがどのピアを運ぶか
1台のPiに2つのトンネルアドレスがあっても故障ではありません。各宛先には独自の搬送経路、独自の証明、そして外側ホップが死んだときの宣言済みフォールバックが必要です。
小さなボードにトンネルアドレスが二つあると誤りのように見え、反射的に一つを消したくなります。その反射は、整理しようとしたものを壊します。二つのホップを運ぶホストは接続ごとに一つのアドレスを保持し、各アドレスは異なるルートで選択されます。問う価値があるのは、どのルートがどの宛先に対してどの搬送経路を選ぶかであり、アドレスがいくつあるかではありません。
異なる搬送経路を必要とする三つの宛先
二ホップの連鎖は三つの宛先クラスが積み重なったもので、それぞれを異なる接続が運びます。外側のピアには物理リンク経由で到達する必要があります。内側のピアには外側トンネル経由で到達する必要があります。対象アプリケーションの宛先には内側トンネル経由で到達する必要があり、その内側トンネル自身の転送は外側が運びます。
| Destination class | View that names the carrier | Command that proves it | Symptom when the wrong carrier wins |
|---|---|---|---|
| Outer peer, 198.51.100.10 | the main table, by destination | ip route get 198.51.100.10 | the outer handshake never completes |
| Inner peer, 203.0.113.7 | the main table once the outer tunnel is up | ip route get 203.0.113.7 | the inner handshake leaves over the physical link |
| Application destination, 172.30.9.1 | the table the inner client's traffic is selected into | ip route get 172.30.9.1 from 10.8.0.2 | the exit address looks right and the traffic never crossed the outer hop |
| Parallel tunnels, one per source group | one policy per group, not the main table | ip rule show beside a marked test connection | both tunnels are up and one steals the other's traffic |
ルートに触れる前に読者の実際のアドレスで行を埋めてください、表は具体的になって初めて役に立つからです。機能する連鎖は四行すべてを同時に満たし、半分機能する連鎖は通常そのうち一つを誤った搬送経路で満たします。誤った行を故障として読むことが、ルーティングの問題を丸一日の編集作業に変えます。
アドレスには数ではなく役割がある
Linuxは一つのインターフェースに複数のアドレスを、一つのホストに複数のトンネルを許すので、数は正しさについて何も語りません。重要なのは、どのアドレスがどの接続に属するか、そして特定のピアのルートが意図した接続を選ぶかどうかです。三つのビューが三方向からそれに答えるので、毎回同じ順序で読む価値があります。
アドレス一覧は何が存在し、どの接続がそれを所有するかを示します。ルートテーブルは通常の宛先トラフィックについて搬送経路の問いに答えます。ポリシービューは送信元やマークで選択されたトラフィックについて再び答え、二つのクライアントが一つのホストを共有するときの通常の配置です。
ip -4 addr show
ip -4 route show table all
ip rule show
一覧が長く見えるからアドレスを消すと経路の一部が失われることがあり、冗長に見えるからルートを消すと同じことをより静かに行います。どちらもエラーを出さず、ピアは意図した経路で応答しなくなるだけで、別の経路では到達可能なままです。内側ピアの出口アドレスを報告するアプリケーションは、トラフィックが外側トンネルを通過したことを証明しません、直接アクセスでも同じ観測が得られるからです。観測と証明の間のこの隙間が、搬送経路をルーティング層で確認する理由です。
起動順序は固定の待機に勝る
内側のクライアントが外側のクライアントの提供するアドレスやルートに依存するなら、起動は遅延ではなくそのリソースを待つ必要があります。固定の待機は外側トンネルが遅い日に破綻し、誰も再現できない形で断続的に失敗します。依存関係に基づく順序は当て推量を除き、依存関係を一度記述する以外のコストをかけません。インターフェース名も順序の仕組みではありません。
カーネルはtun0やtun1のような名前を作成順に割り当て、その順序は再起動や再接続の間に変わることがあります。設定はツールが提供する識別子、または意図的に割り当てた名前に結び付けてください。自分で選ぶ名前は契約であり、カーネルが選ぶ名前は偶然です。
各クライアントの転送を相手のアプリケーションルートの外に保ち、OpenVPN 2.6のルーティングオプションが実際に何を約束するかを正確に把握してください。文書化された既定のリダイレクト機構は、クライアントが既存のゲートウェイ経由で自分の遠隔ピアに到達できる状態を保ち、特定の再帰ループを一つ断ちます。それは一つのクライアントを別のクライアントの搬送経路にするものではないので、連鎖の残りはあなたの設計のままです。連鎖がルートではなくポリシーを必要とする箇所では、明示的な送信元またはマークの規則を書き、一致させるべきトラフィックで試してください。
外側ホップが死んだときに何が起きるか
連鎖が完成とみなされる前に、外側ホップが消えたときに何が起きるかを決めてください。内側クライアントの転送はそれと共に死に、次の一手は技術ではなくポリシーの問いです、つまり失敗か、再試行か、物理リンク経由の直接再接続かです。考える価値があるのは三番目の結果です。利用者がまだカバレッジが無傷だと信じている瞬間に、二ホップの設計を一ホップの設計へ静かに変えてしまいます。
二ホップが必須なら、外側が消えたときに内側クライアントが直接経路を確立できてはならず、それを知る方法は外側ホップを壊して内側がどうするかを見ることです。承認されたフォールバックは正当な答えですが、文書化し、テストし、周知する必要があります。誰も文書化していないフォールバックは、インシデントレビューでは漏えいと区別できません。
DNSともう一方のアドレスファミリーも同じ決定に属します。ローカルで生成された問い合わせは転送されたクライアントのポリシーではなくホスト自身のポリシーに従うため、転送トラフィックで機能するリゾルバーがホスト自身の使うものとは限りません。
各層を構築した順序で受け入れる
連鎖を構築した順序、つまり外側トンネル単独、次に外側トンネル経由の内側クライアントの転送、次に内側トンネル経由のアプリケーションの順でテストします。各受け入れは既に開いていたページではなく新しい接続でなければなりません。その後、各層を個別に壊して復元し、次がどうするかを観察します。
フォールバックの結果はここで最も価値のある観測であり、公開IPのページが決して示さないものです。ピアの経路、それらが使うアドレス、その結果を設定のそばに保存してください、幸せな経路は後で問われる部分ではないからです。