トンネルに接続してip routeを実行しても、元のデフォルトゲートウェイはそのまま残っています。次に思うのはクライアントがルートを引き継げなかったのではないかということなので、デフォルトを手動で削除すると接続を完全に失います。そのエントリは残るべきものです。redirect-gateway def1を指定すると、OpenVPNは通常のデフォルトを置き換えるのではなく、それを上回る二つのより具体的なルートをインストールします。古いゲートウェイは残り、テストしていたトラフィックを運ばなくなります。

def1が実際に行うこと

このフラグは0.0.0.0/1と128.0.0.0/1を追加し、どちらもトンネルを指します。0.0.0.0/1は最初のオクテットが0から127までのすべてのアドレスをカバーし、128.0.0.0/1は128から255までをカバーするため、すべてのIPv4宛先には古いデフォルトより具体的な一致があります。どのルートが勝つかはメトリックではなくプレフィックス長で決まります。

元のデフォルトをそのままにしておくのは意図的です。クライアントは何を置き換えたかを覚えておく必要がなく、VPNサーバーへの自身の接続を運ぶルートを書き換えることもありません。切断時に二つの半ルートを削除し、テーブルは元の状態に戻ります。

なぜ/0ではなく/1なのか

ルーティングは最小メトリックではなく最長一致プレフィックスを選ぶため、デフォルトのメトリックが何と言おうと/1は/0に勝ちます。一つの/1は空間の半分しかカバーしないため両方の半分が必要であり、0.0.0.0/1だけが存在すると128.0.0.0以上のすべてが古いデフォルトに従い続け、一部のサイトは動き他は動かないという紛らわしい症状が生まれます。

古いデフォルトのメトリックを上げ下げしても何も変わらず、別のインターフェースのより低いメトリックのデフォルトもトラフィックを奪いません。まずプレフィックス長が決め、同じプレフィックスのときだけメトリックに戻ります。

実際のルーティングテーブルを読む

接続済みのホストは三つのエントリを同時に表示でき、トンネルが半分を運び、元のゲートウェイはまだ一覧にあります。アドレスはコピーすべき設定ではなく例であり、インターフェース名、トンネルのトポロジ、追加ルートはプラットフォームとクライアントによって異なります。

default via 192.168.50.1 dev wlan0
0.0.0.0/1 via 10.8.0.1 dev tun0
128.0.0.0/1 via 10.8.0.1 dev tun0

重要なのは関係であり、一つの一般的なデフォルトの上に二つの具体的な半分があることです。古いゲートウェイの行は何も置き換えていないので残ります。

パケットが実際に通るルートを確認する

より具体的なルートが勝つこともありますが、それはプライベート範囲、ローカルサブネットへのルートやVPNサーバー自身のアドレスが/1より長いためです。トンネルはサーバーへの外側の経路を必要とし、その接続をトンネルに戻すと即座に壊れます。Linuxではテーブルを目で読む代わりにカーネルに尋ねれば、関心のある宛先を指定したip route getが、選ばれたルート、インターフェース、送信元を出力します。ポリシールーティングが設定されている場合は、メインテーブルが見られる前にルールが別のテーブルを選べるため、ルールも確認してください。

IPv4の一部だけが不調なら、両方の半分がインストールされたことを確認し、次に失敗する宛先に一致する例外を探します。古いデフォルトを削除することは解決策ではなく、クライアントがトンネルをきれいに畳むのに必要なルートを奪います。

def1がカバーしないこと

二つのIPv4エントリはIPv6について何も語りませんが、IPv6接続のあるホストは、何かがそのファミリーを別途リダイレクトするまで自身のデフォルトを使い続けるため、デュアルスタックネットワークでは一部のトラフィックがトンネルを迂回しているように見えます。他のクライアントやネットワークマネージャーはフルトンネルルーティングを別の方法で実装しており、それらのテーブルは一致しません。ここで説明するdef1の動作はOpenVPNの文書化されたフラグのものであり、マシン上のすべてのVPNのものではありません。

キルスイッチは別の問い、つまりトンネルが落ちたときマシンが何をするかに答えます。ルートの優先順位はトンネルが上がっている間のトラフィックの行き先を決めますが、その後にファイアウォールが何をするかは決めません。作業順序は、テーブルを読み、両方の半分が存在することを確認し、失敗する宛先に対してip route getを実行し、ポリシールールを確認し、その後IPv6を別に見ることです。古いデフォルトはそのままにしておきます。

関連記事