接続済みでトレイのアイコンが緑でも、アドレスを返すページが事業者のアドレスを示しているなら、それは自動的に障害ではない。クライアントはトンネルを張ることと経路表を書き換えることという二つの別の仕事をする。片方はもう片方なしでも起こり得て、選択的ルーティングは二つ目を意図的に飛ばす設定である。

クライアントが実際に入れたもの

トンネルが上がっているかを尋ねる代わりに、実際の宛先へのパケットをどのインターフェースが運ぶかを尋ねる。その宛先への経路を持たないトンネルは、誰も通らない私道だ。

ip route get 9.9.9.9
Find-NetRoute -RemoteIPAddress 9.9.9.9
route print -4

最初のコマンドはLinuxとmacOSで答え、残る二つはWindowsでの等価物で、一つあれば足りる。答えが物理アダプターを名指しするなら、トンネルは上がっていてデフォルトルートは一度も動いていない。トンネルを使うべき宛先でもう一度調べるのは、遠隔と通常の二回の検索がどちらの設計が配備されているかを教えてくれるからだ。

選択的ルーティングの三つの形

全トンネルのプロファイルは通常、インターフェースを指すデフォルトルートを書くか、プレフィックス長で勝つ半範囲のプレフィックス対を書き、元のデフォルトは表に残る。選択的ルーティングはもう一方の選択で、いくつかの形がある。あるプロファイルはRDPサーバーのような単一のホストを経路に載せ、別のものは特定の場所から到達すべき公開範囲を載せ、三つ目は一つのアプリを意図的に除外する。三つとも正当で、どれも一般的なサイトが見るアドレスを変えない。

grep -nE "redirect-gateway|route-nopull|route " /etc/openvpn/client/*.conf
ip route show table main | head -20

決めるのはどのディレクティブか、プロファイルで読み、次にそれが生んだものを表で読む。押し出されたディレクティブはクライアント側で抑止されることもあるので、サーバーを責める前にプロファイルと表が一致していなければならない。

反対側は送信元アドレスを書き換える必要がある

ブラウザーからは同じに見える第二の故障がある。経路はトンネルへ向かい、サーバーはパケットを受け取り、クライアントのプライベートアドレスをそのままに転送する。次のホップにはそのアドレスへの戻り経路がないので、応答は消え、ページは止まる。サーバーはそもそも転送しなければならず、送信元をインターネットが戻せる何かに変換しなければならない。

sysctl net.ipv4.ip_forward
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
iptables -t nat -S | grep MASQUERADE

実際にインターネットに面しているインターフェースは、現代のディストリビューションでは常にeth0とは限らないので、それを名指しする。固定アドレスのホスト型サーバーなら、masquerade の代わりにそのアドレスへ明示的に変換できる。両方の半分が重要で、変換なしの転送は経路のない送信元を漏らし、転送なしの変換はパケットを永遠に見ない。

名前解決は独自の道を行く

名前を見つけた検索がローカルネットワークのリゾルバーへ行ったまま、通信だけがトンネルから出ることがある。見えるアドレスは同じでも問い合わせは違う、そしてその隙間こそが分割DNSの設計が選んでいるものだ。

resolvectl status | head -20
resolvectl query example.org

どのサーバーが答えたか、トンネル前の基準と違うかを見る。分割トンネルでは、アドレスに不満を言う人が変えたかった設定がこれで、しかも彼らが一度も見なかった設定でもある。

決着をつける四つの観察

トンネルを下ろした状態と上げた状態で出口アドレスを取る。両方の状態で宛先検索を実行し、毎回インターフェースを記録する。

curl -sS https://ifconfig.me/ip
ip route get 9.9.9.9

検索がトンネルの内側に落ち、それでも返答が事業者のアドレスを示すなら、出口の変換が欠けている。検索が物理アダプターに落ちるなら、プロファイルは選択的で公開アドレスは最初から対象外だった。信頼できる返答サービスに替えて、四つの観察をまとめて記録する。別々では逸話にすぎず、まとめればクライアントが二つの仕事のどちらを実際に果たしたかが分かる。

関連記事