VPN 経由の Dante SOCKS:フルトンネルと送信元ルーティングの比較
SOCKS プロキシだけをトンネルに通す二つの方法、デフォルトルートを置き換えるか、送信元アドレスを専用テーブルに割り当てるか。失敗の仕方が異なります。
SOCKS プロキシの通信だけを VPN から出し、ホストの残りは通常の経路を保ちたいとします。これを実現する設計は二つあり、何か問題が起きたときに壊れる範囲が異なります。一方はデフォルトルートをトンネルに押し込み、それを回避します。もう一方はメインテーブルに手を付けず、一つの送信元アドレスを二つ目のテーブルへ送ります。後者のほうがすっきりしており、独自の落とし穴もあります。
二つの設計、二つの異なる影響範囲
フルトンネル設計は、ほとんどの VPN クライアントが既定で行う方式です。デフォルトルートを置き換えてすべてをトンネルに従わせ、その後で従わせたくないものを除外します。考え方は簡単ですが狭く保つのは難しく、追加したローカルサービスは除外するまでトンネルを引き継ぎます。故障の規模は広く、一本の誤ったルートがホスト自身の接続も巻き込みます。
送信元で選ぶ設計は逆方向に進みます。メインテーブルはそのままにし、一つのポリシールールが特定のローカルアドレスからのパケットを、トンネルのデフォルトを持つテーブルへ送ります。他は何も変わらないため、影響範囲は一つのアドレスです。
この狭さが制約でもあります。プロキシの送信パケットが本当にそのアドレスを持つ場合にしか、この設計は機能しません。
Dante の external 設定が行うこと
external 設定は、プロキシが外向き接続に使うアドレスを選びます。カーネルのルーティングポリシーには触れません。この分離が二つ目の設計を可能にし、同時に文書を読み違えやすい箇所でもあります。external をトンネルのアドレスに向けると、プロキシはそのアドレスを送信元として接続し、あとはルーティングテーブルがそのパケットの行き先を決めます。
リスナーは別の関心事です。internal はプロキシを使うべきクライアントだけに限定し、認証を必須にし、ポートをファイアウォールで閉じてください。開いたリスナーは VPN 出口の機能ではありません。
設定したアドレスが、プロキシのネットワーク名前空間内で本当にトンネルに属していることを確認してください。
送信元で選ぶテーブルの構築
TUN アドレスが 10.90.0.2/24、到達可能なピアが 10.90.0.1 で、他が使っていないテーブル番号を使う場合、構成は次のようになります。
ip -4 route add table 100 10.90.0.0/24 dev tun0 src 10.90.0.2
ip -4 route add table 100 default via 10.90.0.1 dev tun0 metric 10
ip -4 route add table 100 unreachable default metric 32760
ip -4 rule add priority 1000 from 10.90.0.2/32 lookup 100到達不能ルートこそ、多くの人が飛ばす部分です。これがないと、トンネルのルートが消えたテーブルは通常のデフォルトに落ち、プロキシは WAN から静かに出てしまいます。これがあれば検索は失敗し、静かな漏洩ではなく目に見える故障になります。ルールの優先度も、その送信元に一致する他の何よりも前に置く必要があります。
これらの値は一つのトポロジーを表します。ポイントツーポイントのピア、net30 アドレッシング、異なるプレフィックスを配るクライアントは、それぞれ独自のルートを必要とします。アドレスではなく形をコピーしてください。
送信元ルールが漏れる箇所
送信元アドレスに一致するルールは、プロキシだけでなく、それを使うすべてのプロセスに影響します。別のデーモンが同じアドレスを束縛すれば、その通信もトンネルを通り、故障は無関係なサービスの問題に見えます。プロキシに他が使わないアドレスを与えるか、範囲はプロセスではなくアドレスだと受け入れてください。
DNS ももう一つの漏れです。リゾルバのソケットは必ずしもプロキシの external なデータ接続の送信元を使わないため、名前解決は依然として WAN から出られます。解決を接続確立とは別に試し、その結果を受け入れられるか決めてください。
IPv6 には独自のルールとルートが必要です。IPv4 の構成はそれについて何も証明しません。
許容できる故障で選ぶ
ホスト全体を守るべきで除外リストを維持できるなら、フルトンネルを選んでください。ホストが自前の経路を保つべきで、一つのサービスだけを迂回させるなら、送信元ベースのルーティングを選んでください。どちらも正当です。誤りは、一方を選んでからもう一方であるかのように試すことです。
どちらを選んでも、両側から検証してください。プロキシ経由のリクエストとホストからの直接リクエストを行い、それぞれで観測された出口アドレスを記録します。
トンネルが落ちた場合に、プロキシを失敗させるのか退避させるのかを事前に決め、ルーティングテーブルにその決定を表させてください。