Dev Study
← ネットワークの仕組み
レッスン 6 / 13·約 17 分·第2期 ネットワークの仕組み

経路は誰が決めるのか — 静的・動的とデフォルトゲートウェイ

リクエストがアプリケーションに届くまで
  1. ブラウザURL入力
  2. DNS名前→IP
  3. ルータ経路選択今ここ
  4. ロードバランサ振り分け
  5. Nginx受け口
  6. アプリ処理
  7. DB保存

前回と同じ「ルータ」の段を扱いますが、見る向きが逆になります。第18週は出来上がった表をどう引くかでした。今回は、その表がそもそもどうやって埋まるのかを見ます。

まず結論

ルーティング表の行は、人が手で書いたもの(静的)と、ルータどうしが会話して自動で作ったもの(動的)の2つの出所から埋まります。どちらを使うかは規格が決めることではなく、実務上の判断です。

そして複数の出所が同じ範囲の経路を持ち込んだとき、どちらを採用するかを決める仕組みは、標準化されていません。Ciscoのアドミニストレイティブディスタンスはベンダ独自の値で、Linux カーネルの経路表にはその概念自体がありません。

? 読む前に予測

「OSPFで学んだ経路のアドミニストレイティブディスタンスは110である」——この説明を、規格に基づく一般的な事実として扱ってよいでしょうか。

当てることが目的ではありません。外した予測ほど記憶に残るので、直感で選んでください。

抽象原理

前回は表の使い方、今回は表の作られ方

第18週では、ルーティング表を与えられたものとして扱いました。宛先に当てはまる行が複数あるとき、最長一致でどれが選ばれるか。そこでの関心はすべて「引く側」にありました。

今回は向きが逆になります。その表は、そもそも誰がどうやって埋めたのか。

同じルーティング表を、2つの向きから見る
第18週: 消費する側当てはまる行から1つ選ぶ = 最長一致
その表はどこから来たのか?
第19週: 生成する側行が表に載るまでの経緯
行の出所は大きく2つ
人が書いた静的経路
ルータが計算した動的ルーティング
  • ・最長一致の規則そのものは、行の出所を一切見ない
  • ・「どう選ぶか」と「どう載るか」は、完全に別の話

この分業が大事です。最長一致は、行が誰によって書かれたかを問いません。 人が手で書いた行も、OSPFが計算した行も、表に載ってしまえばプレフィックス長だけで比較されます。

では出所の違いはどこで効くのか。表に載る前です。同じ範囲の経路が複数の出所から持ち込まれたとき、どれを載せるかを決める段階があります。そして——ここが本レッスンの山場のひとつですが——その段階の規則は標準化されていません。

具体実物

静的経路 — 人が手で書く

いちばん単純な埋め方は、人が手で書くことです。

$ ip route show(出所つきで表示)コマンド出力
default via 192.168.1.1 dev eth0 proto dhcp metric 100
10.20.0.0/16 via 192.168.1.254 dev eth0 proto static
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.50

proto が出所を表します。kernel はアドレスを付けた時点でカーネルが入れた行、dhcp はDHCPクライアントが入れた行、static は人が明示的に追加した行です。

静的経路は書いた通りに動きます。それが長所であり、同時に短所です。経路の先で障害が起きても行はそのまま残り、誰も気づかなければパケットは壊れた経路へ流れ続けます。

抽象原理

動的ルーティング — ルータどうしが会話して表を埋める

経路が複数あり、トポロジが変わりうる場所では、手で書き続けるのは現実的ではありません。そこでルータどうしが情報を交換し、経路を自動で計算します。これが動的ルーティングです。

方式は大きく2つで、この違いは頻繁に取り違えられます。一行で正確に押さえます。

2つの方式の、本質的な違い表
方式 各ルータが持つもの 隣へ送るもの
リンクステート 全体の地図(全員同一) 自分のローカルな状態
距離ベクトル 宛先ごとの距離 宛先ごとの距離の一覧

リンクステート = 全員が同じ地図を持ち、各自が自分を起点に最短経路を計算する。 距離ベクトル = 隣人の言う距離を信じて足す。

具体実物

OSPFが実際にやっていること

対比の具体例の1つめとして、リンクステート型の代表である **OSPF(RFC 2328)**を見ます。RFC 2328 の記述は明快で、3点に尽きます。

各ルータが持つもの。「Each OSPF router maintains an identical database describing the Autonomous System's topology(各ルータは、ASのトポロジを記述する同一のデータベースを保持する)」。

何を配るか。「The router distributes its local state throughout the Autonomous System by flooding(自分のローカルな状態をフラッディングでAS全体に配る)」。

どう計算するか。「All routers run the exact same algorithm, in parallel ... each router constructs a tree of shortest paths with itself as root(全ルータが同じアルゴリズムを並行実行し、各ルータが自分自身を根とする最短経路の木を構成する)」。

OSPFで1本の経路が表に載るまで
ローカル状態の生成自分がどのリンクに繋がっているかを記述○ 自分の1ピースだけを作る
フラッディングそのピースをAS全体へ配る○ 全員が全ピースを受け取る
同一データベース各ルータの手元に同じ地図が揃う○ 全員が同じ絵を見ている
各自で最短経路計算自分を根とする木を構成する○ 自分専用の経路が出る
↓
計算結果がルーティング表の行になる。表に載った後は、第18週の最長一致で引かれるだけ
  • ・配っているのは地図ではなく「地図の1ピース」。地図は各自が組み立てる
  • ・全員が同じ地図を見るのに、出てくる経路は各自で違う(根が違うため)
✓ ここまでの確認

リンクステート型プロトコル(OSPFなど)が隣のルータへ送っているのは、次のうちどれですか。

抽象原理

複数の出所が競合したとき — ここが標準化されていない

静的経路とOSPFが同じ範囲の経路を同時に持ち込んだらどうなるでしょうか。プレフィックス長が同じなので、最長一致では決着しません。

この決着のためにCiscoが持つのがアドミニストレイティブディスタンス(AD)です。Cisco公式の説明は「AD is a value used to rank the trustworthiness of routing information sources(経路情報の出所の信頼度を順位付ける値)」。小さいほど信頼されます。

ここで、Cisco自身が書いている決定的な一文に注目してください。

「OSPFのADは110です」を規格に基づく一般則として述べてはいけない理由が、ここにあります。それは特定ベンダの特定製品の既定値です。

Cisco 以外の例として、Linux などで動くルーティングスイート FRR の zebra も AD を持ち、既定値は Static 1 / EBGP 20 / OSPF 110 / RIP 120 / IBGP 200 などです。FRR の文書は、これは主観的な順序付けであり「other routing suites have chosen(他のルーティングスイートが選んだ)」のと同じ値を選ぶよう注意した、と書いています。値が揃っているのは規格だからではなく、慣習に合わせた結果です。

⇄ 2つを見比べる
具体例 A

OSPF — 状態を配り、判断は各自

各ルータは自分のローカル状態だけをフラッディングし、全員が同一の地図を持ちます。しかし経路の計算は各ルータが自分を根として行うので、出てくる答えはルータごとに違います。中央の管制官が全員ぶんの経路を計算して配っているのではありません。

OSPFにおける分散表
分散しているもの 各ルータが担当する範囲
状態の生成 自分が繋がっているリンクだけ
状態の配布 フラッディングで全員へ(同一DB)
経路の計算 自分を根とする木を、自分で計算
具体例 B

DNS — 名前空間を委任で分ける

DNSでは、上位のゾーンが下位のゾーンへ権限そのものを委ね、下位の中身には関与しません。上位が知っているのは「この先は誰に聞け」だけです。名前解決は上位から下位へ辿ることで成立しています(第25週で詳しく扱います)。

DNSにおける分散表
分散しているもの 各サーバが担当する範囲
権威 自分のゾーンの中身だけ
委任情報 「この下は誰が権威か」の指し示し
解決の実行 問い合わせ側が上から順に辿る

OSPFとDNSは、どちらも中央に全知の管理者を置かずに全体を成立させています。分散のさせ方は、この2つでどう違うでしょうか。そしてその違いは、何から生まれているでしょうか。

「他の参加者が持っている情報を、自分も持っているか」を比べてみてください。OSPFの各ルータは全体の地図を持ちますが、DNSの各サーバは他ゾーンの中身を持ちません。

具体実物

Linuxのカーネルには、そもそもADという層が無い

「ADは普遍的な仕組みではない」を、手元で体感できる形にします。Linux カーネルの経路表(ip route)には、経路の出所を信頼度で順位付ける仕組みが存在しません。 あるのは metric だけです。(FRR などのルーティングデーモンを動かせば、カーネルに経路を入れる前の段階でデーモン自身の AD が使われます。ここで扱うのはカーネルの層です。)

「出所で優先度を決める層」の有無表
出所の信頼度ランキング 優先度を決めるもの
Cisco IOS ある(AD。ベンダ独自) AD → その後メトリック
Linux カーネル 無い metric のみ(小さいほど優先)

ip-route(8) が metric について書いているのはこれだけです。「the preference value of the route. NUMBER is an arbitrary 32bit number, where routes with lower values are preferred(任意の32ビット整数で、小さい値ほど優先される)」。

出所を表す protocol RTPROTO(redirect / kernel / boot / static / ra など)は別のフィールドで、記録用にすぎません。

$ ip route show default(有線とWi-Fiが両方繋がっている状態)コマンド出力
default via 192.168.1.1 dev eth0 proto dhcp metric 100
default via 192.168.1.1 dev wlan0 proto dhcp metric 600

同じ 0.0.0.0/0 が2本あり、決着を付けるのは metric の 100 と 600 だけです。出所はどちらも dhcp で同じなので、仮にADのような仕組みがあっても決着しません。

「経路をどう選ぶか」の一部は、実装ごとに設計が違う。 ADは広く使われている考え方ですが、普遍的な仕組みではありません。

抽象原理

デフォルトゲートウェイの正体 — 第18週からの自然な帰結

ここが本レッスンの山場です。デフォルトゲートウェイは、特別な設定項目ではありません。

設定画面では独立した入力欄として現れるので、経路表とは別の何かに見えます。しかし実体はプレフィックス長0の経路(0.0.0.0/0)の next hop、それだけです。

RFC 4632 の言い方が正確です。「the degenerate route to prefix 0.0.0.0/0 is used as a default route and MUST be accepted by all implementations(0.0.0.0/0 への退化した経路がデフォルトルートとして使われ、すべての実装が受け入れなければならない)」。

degenerate route(退化した経路)という語に注目してください。別種の何かではなく、普通の経路の特殊ケースとして扱われています。Linux の man ip-route も default を「equivalent to IP 0/0」と定義しています。

宛先 8.8.8.8 の照合(第18週と全く同じ規則で動く)
192.168.1.0/2424ビット一致を求める× そもそも一致しない
10.20.0.0/1616ビット一致を求める× そもそも一致しない
0.0.0.0/00ビット一致を求める○ 当てはまる。そして他に候補が無い
↓
0.0.0.0/0 の next hop へ転送 = 「デフォルトゲートウェイへ送る」
  • ・0.0.0.0/0 は常に照合され、常に当てはまっている
  • ・他に当てはまる行があれば必ず負ける。長さ0だから

つまりこうです。0ビットの一致でよいので全宛先に当てはまる。しかし他のどんな行も1ビット以上を求めるので、最長一致では必ず負ける。 結果として「他のどれにも当てはまらなかったときだけ残る」という振る舞いになります。

✓ ここまでの確認

デフォルトゲートウェイが「他のどれにも当てはまらなかったとき」に使われるのは、なぜですか。

抽象原理

静的と動的、どちらを使うか — これは実務判断

最後に使い分けです。ここは規格ではなく実務判断だと明示しておきます。RFCに「この場合は静的を使え」とは書かれていません。

動的ルーティングの目的は2つ。トポロジ変化への自動追随と、冗長経路の再計算です。どれかが落ちたときに別の経路へ切り替わってほしい——これが動機です。

代償もはっきりしています。プロトコル自体のトラフィック、CPU負荷、設定の複雑さ、そして障害時の切り分けの難しさ。経路が自動で変わるとは、調査中に「今どうなっているか」が刻々と動くということでもあります。

選択を決めるのは、経路が何本あるか表
状況 動的に追随する余地 現実的な選択
拠点から本社へのアップリンク1本 無い(代替経路が無い) 静的 + デフォルトルート
経路が複数あり切替が要る ある 動的ルーティング

経路が1本しかない末端では、変化に追随する余地がそもそもありません。 拠点から出ていく線が1本なら、それが落ちたときに選べる別経路は存在せず、動的プロトコルを走らせても計算する対象がありません。だから静的経路とデフォルトルートで十分です。逆に言えば、動的ルーティングが価値を持つのは選択肢が実際に存在する場所だけです。

この章のまとめ

  • 第18週は表を引く側、今回は表が埋まる側。最長一致は行の出所を一切問わないので、この2つは完全に分業している。
  • 行の出所は静的(人が書く)と動的(ルータが計算する)の2つ。どちらを使うかは規格ではなく実務判断で、経路が1本しかない末端では静的+デフォルトルートで足りる。
  • リンクステートは全員が同じ地図を持ち各自が自分を根として最短経路を計算する。距離ベクトルは隣人の言う距離を信じて足す。「リンクステートは経路表を丸ごと隣に送る」は距離ベクトルとの取り違え。
  • アドミニストレイティブディスタンスはRFCで定義されていない。 Cisco公式の「AD is a local value and is not advertised in routing updates」が根拠——広告されないから標準化する必要がなく、ベンダが自由に決めてよい。「OSPFは110」を一般則として述べてはいけない。
  • Linux カーネルの経路表には AD 相当の概念が無い(FRR などのデーモンは独自に持つ)。カーネルにあるのは metric(小さいほど優先)だけで、出所を表す proto は記録用であり優先度決定には使われない。
  • デフォルトゲートウェイは特別な設定項目ではなく、プレフィックス長0の経路の next hop。 長さ0なので全部に当てはまり、最長一致で必ず負ける。「最後に使われる」は例外規則ではなく第18週の最長一致からの自然な帰結。

自分の現場で確かめる

読んだだけでは身につきません。手元の環境で実際に見てみてください。

環境:

理解度チェック

読んだ直後は「分かった」と感じやすいものです。実際に解いて確かめてください。

問題 1 / 4正解: 0

アドミニストレイティブディスタンス(AD)について、最も正確な説明はどれですか。

用語集(6語)
静的経路 (static route)
人が手で書いてルーティング表に入れた経路。書いた通りに動き、トポロジが変わっても自動では追随しない。経路が1本しかない末端では、これで十分なことが多い。
動的ルーティングプロトコル
ルータどうしが情報を交換し、経路を自動で計算して表を埋める仕組み。OSPFなど。トポロジ変化への追随と冗長経路の再計算が目的で、代償としてプロトコルのトラフィック・CPU・設定の複雑さ・障害時の切り分けの難しさが生じる。
リンクステート型
各ルータが自分のローカル状態をフラッディングで配り、全ルータが同一の地図(リンクステートデータベース)を持つ方式。各ルータは自分を根とする最短経路の木を計算する。OSPF(RFC 2328)がこれ。
距離ベクトル型
隣接ルータが申告する「宛先までの距離」を受け取り、自分までの距離を足して伝播させていく方式。地図は持たず、隣人の言う距離を信じる。Bellman-Ford が基礎。
アドミニストレイティブディスタンス (AD)
同じ宛先範囲の経路が複数の出所から入ってきたとき、どの出所を信頼するかを順位付けるベンダ独自の値。RFCに定義は無い。Cisco公式は「ローカルな値でルーティング更新では広告されない」と説明している。Linux カーネルの経路表にはこの概念自体が存在しない(FRR などのルーティングデーモンは独自に持つ)。
デフォルトゲートウェイ
0.0.0.0/0 という経路の next hop。特別な設定項目ではない。プレフィックス長が0なので全宛先に当てはまるが、最長一致では他のどの行にも負ける。