ゲートウェイ列が空になるたびに、ルーティングテーブルは壊れていると読み違えられますが、実際にはその行はそれだけで完結しているのが普通です。via フィールドが現れるのは、カーネルがパケットをネクストホップのアドレスに渡すときだけで、インターフェースに紐づいたルートは、代わりにリンク層の解決やポイントツーポイントのピアを通じて宛先に到達します。列を左から右へ読めば、どちらのケースなのかが分かり、その読み取りは誰かがデフォルトルートを編集する前に済ませるべきものです。ゲートウェイがないというチケットの多くは、この区別で終わります。

ルート行を列ごとに読む

各エントリは宛先とそのプレフィックス長で始まり、固定の語彙 — via、dev、proto、scope、src、metric — で修飾子を加えます。198.51.100.0/24 dev tun0 proto kernel scope link src 198.51.100.2 のような行は密ですが完全に指定されています。何も欠けておらず、ルーターのアドレスも含意されていません。

興味深いのは via がないことです。ネクストホップがなければ、カーネルは指定されたインターフェース上で宛先を直接解決し、トンネルの場合、これはフレームをトンネルデバイスに渡し、カプセル化に引き継がせることを意味します。proto kernel は、アドレスが割り当てられたときにエントリが自動的にインストールされたことを記録しており、管理者が入力したものではありません。scope link は、そのリンク上でルーターを経由せずに宛先へ到達できることを示し、src は一致するトラフィックの送信元としてカーネルが優先するアドレスを示します。

次に、デフォルトルートも同じように読んでみましょう:default via 192.0.2.254 dev eth0 proto static metric 100。ここで via があるのは、パケットが実際にネクストホップを必要とするからであり、そのホップ自体が eth0 上で到達可能でなければなりません。この二つの行は互いの変種ではなく、トラフィックがどこへ向かうかについて別の問いに答えています。

混同されやすい二つのルート形状

トンネルのサブネットルートとデフォルトルートは、スクリーンショットでは似て見えますが、動作はまったく異なります。以下の表をフィールドを読む助けとして使い、ガイドのサンプルを信じるのではなく、デバッグしているマシン上で実際の数値を確認してください。

Piece of the lineWhat it settlesWhat it says nothing about
The destination and maskWhich packets are eligible to matchWhere those packets leave the host
via plus its addressWhich next hop receives them, and therefore that a router is involvedWhether that router is reachable or sane
devWhich interface carries the encapsulated or raw packetWhether the interface is up or has a carrier
proto and scopeWho installed the entry and how far the destination is considered to beWhether a firewall later drops the traffic

表が伝えられないのは意図です。トンネル経由でプライベート範囲への直接ルートは意図的なスプリットトンネルの設計であり、すべてを VPN 経由で送るべきホストで同じ形が現れるのは症状です。意図はそのエントリを生み出した設定の中に住んでいるので、カーネルが何か間違えたと結論づける前に、それをインストールしたツールを見てください。

同様に、ゲートウェイがないことは、それをでっち上げる許可ではありません。ルートが本当にネクストホップを必要とするなら、そのホップはそれを運ぶインターフェース上で到達可能でなければなりません、そしてポイントツーポイントのトンネルでは、ピアのアドレスはローカルアドレスと同じオブジェクトではありません。ローカルのトンネルアドレスを Ethernet ルーターとして扱うのは、正しく見えて何も転送しないルートを生む典型的な方法です。

カーネルに、実際にどの行を使うのかを尋ねる

テーブルを読むことはルックアップを実行することとは違い、カーネルは答える前にポリシールール、複数のテーブル、キャッシュされたエントリを参照するからです。本当のルックアップを行う動詞は ip route get で、その性質を持つパケットがたどるルートを出力します。

ip route get 203.0.113.37 from 198.51.100.2 iif tun0

通常のローカルルックアップは転送されるクライアントとは別の経路を選ぶことがあるので、本当に気にしている宛先に置き換え、トラフィックが送信元で選択される場合や転送される場合には from や iif を加えてください。応答はインターフェース、選択された送信元アドレス、そして任意のネクストホップを示し、それはその瞬間にパケットがルーティングされる情報と同じです。

応答に驚いたら、何かを変更する前にルールを出力してください:ip -4 rule show は優先順にそれらを一覧し、独自のテーブルやマークされたパケット用のルールをインストールする VPN クライアントはメインテーブルにはまったく現れません。すべてのテーブルを一覧すれば、その隙間は埋まります。

ip -4 route show table all | grep -E 'tun|default'

デフォルトを置き換える前にアンダーレイを確認する

トンネル自身のパケットは遠隔のエンドポイントに到達しなければならず、それは VPN が上がる前に存在していたルートを使って物理インターフェース経由で行われます。そのエンドポイントを固定せずにデフォルトルート全体を置き換えると、カプセル化されたパケットは自分たちが構築すべきトンネルの中へ送られ、接続は崩壊します。まずエンドポイントのアドレスだけのルックアップで経路を確認してください。

変更を行うときは、物理インターフェースに残すべきエンドポイントのルート、トンネルに入れるべきプライベート範囲、そして残りすべてを決めるデフォルトという三つを切り離しておいてください。その順に分解し、一度に一つずつ適用し、各手順の後にルックアップを再実行します。後で ping が失敗しても、権限、応答のルーティング、DNS、サービス自体のすべてが正しいルートの下流にあるため、それだけではほとんど何も証明しません。

編集の前に、その行が示した四つの値 — 宛先、ネクストホップまたはその不在、デバイス、選択された送信元 — を書き留めてください。後の変更でそのどれかが動いたなら、どの決定が実際に変わったのかが分かり、テーブル全体を推測する代わりに一つのエントリを復元できます。

関連記事