2つのゲートウェイ、1つのVPN:OpenVPNが誤ったアップリンクを選ぶ理由
トンネルは正常です。ソケットが誤ったWANから出ています。稼働中のピアアドレスを読み、ホストルートを固定し、まずポリシールールを確認してください。
ふたつのアップリンク、ひとつのトンネル、そしてトラフィックは選んでいない方から出ています。プライベートサブネットには到達でき、ログは接続成功を報告し、従量制の回線がそれを運んでいます。OpenVPNの出力にはゲートウェイの記述がないのは、クライアントが一度も選んでいないからです。リモートアドレスにソケットを開き、そのアドレスへの経路はカーネルに任せていました。
トンネルのアドレスはエンドポイントではない
どのセッションにもふたつの異なる経路があります。外側の経路は暗号化されたトランスポートをサーバーの公開アドレスまで運びます。内側の経路はサーバーがトンネルに押し込むものすべてを運び、一方のルーティングルールは他方に影響しません。
プロファイルのremoteエントリは外側の宛先を示すので、固定すべきはそのアドレスです。ホスト名の解決結果が変わったときや、プロファイルに複数のremoteが並ぶときにも変わる値でもあります。
クライアントが実際に発信したアドレスを見つける
設定ファイルではなく稼働中のソケットを読みます。ソケットテーブルはプロセスが実際に接続したピアを示し、例外はその値に一致しなければなりません。プロファイルはセッション開始後に編集できるため、何に発信したかを示す唯一の証拠はソケットです:
ss -tunp | grep -i openvpn
journalctl -u openvpn-client@work --no-pager | grep -i "Peer Connection Initiated"
ログ行は接続時点のピアアドレスとポートを示します。プロファイルと食い違うなら、クライアントの手前で何かが接続開始前に宛先を書き換えています。
アドレスファミリーも確認します。デュアルスタックのプロファイルはIPv6で接続できる一方、例外がIPv4しか対象にしていないと、トラフィックは書いたルールとは別のルールに従います。エンドポイントの代わりに応答するプロキシも同じです。どちらの場合も、ルートが何もしていないのにトンネルは動いてしまいます。
エンドポイントを固定し、ポリシーの順序を読む
ホストルートはどのデフォルトルートよりも具体的です。そのためピアアドレスの/32は、それを含むテーブル内で優先されます。通常の書式はゲートウェイとデバイスを明示します:
ip route add 203.0.113.40/32 via 192.168.10.1 dev eth0
そのルートは、検索がそのテーブルに届く場合にしか役立ちません。ポリシールールは順に評価され、最初の一致が決定するため、すべてをふたつ目のテーブルへ送るルールはmainのホストルートを迂回します。ルートが権威的だと決めつける前にルールを読んでください:
ip rule show
ip route get 203.0.113.40
ポリシーが依存する場合は、クライアントが使う同じ送信元アドレスやマークを付けてふたつ目のコマンドを問い合わせます。カーネルが選ぶルートを報告するもので、検索についての証拠ではあっても、稼働中のソケットがその経路を使っている証明ではありません。
エンドポイントが移動するとき
複数のアドレスに解決されるホスト名では、応答が変わった時点で恒久的な/32は無効になります。複数のremote行を持つプロファイルも同じ問題を抱え、クライアントはどれにでも着地し得ます。手で追加するのではなく、クライアント自身のライフサイクルフックからルートを更新します。ネゴシエートされたピアを読むupスクリプトがホストルートを設定すれば例外は現実と一致し、対応するdownスクリプトがそれを削除します。
更新はホストの他のルーティング設定と同じ場所に記録します。次の再起動までしか存在しないルートはテストであり、修正ではありません。
内側のポリシーは分けておく
外側の経路を動かしても、新しいプライベートサブネットへのアクセスは得られず、サーバーがトンネルに押し込む宛先も変わりません。下層のルートが回線を選び、押し込まれたルートがトンネルに入るものを選びます。このふたつの決定を分けておくことが、分割を予測可能にします。
目的が暗号化トランスポートを従量制回線から遠ざけることだけなら、デフォルトルートはそのままにして、単一のホスト例外を追加してください。VPN接続をひとつ動かすためにマシン全体のデフォルトを置き換えると、ホスト上の他のすべてのアプリケーションが壊れます。
結果は、ソケットのローカルアドレスとデバイス、そしてプライベート宛先が解決されるルートというふたつの独立した観察で確認します。両方が意図と一致すれば、分割は本物です。OpenVPN 2.6のマニュアルは、クライアントがどのアドレスに発信するかを決めるremoteとローカルバインドのオプションを扱っています。