22.2. ゲートウェイと経路

寄稿: Gryphon Coranth [FAMILY Given].

あるマシンがネットワーク上で他のマシンをみつけることができるようにするには、 あるマシンから他のマシンへどのようにたどり着くかを記述する適切な仕組みが必要です。 この仕組みをルーティングと呼びます。 経路 (route) は 送信先 (destination) と ゲートウェイ の 2 つのアドレスの組で定義します。この組合せは、この 送信先 へたどり着こうとする場合は、その ゲートウェイ を通じて通信することを示しています。 送信先には個々のホスト、サブネット、デフォルト の 3 つの型があります。 デフォルトルート は他のどの経路も適用できない場合に使われます。 デフォルトルートについてはのちほどもう少し詳しく述べます。 また、ゲートウェイには、個々のホスト、インタフェース (リンク とも呼ばれます)、 イーサネットハードウェアアドレス (MAC アドレス) の 3 つの型があります。

22.2.1. 例

以下に示す netstat の例を使って、ルーティングのさまざまな状態を説明します。

% netstat -r
Routing tables

Destination      Gateway            Flags     Refs     Use     Netif Expire

default          outside-gw         UGSc       37      418      ppp0
localhost        localhost          UH          0      181       lo0
test0            0:e0:b5:36:cf:4f   UHLW        5    63288       ed0     77
10.20.30.255     link#1             UHLW        1     2421
example.com      link#1             UC          0        0
host1            0:e0:a8:37:8:1e    UHLW        3     4601       lo0
host2            0:e0:a8:37:8:1e    UHLW        0        5       lo0 =>
host2.example.com link#1             UC          0        0
224              link#1             UC          0        0

最初の 2 行はデフォルトルート (次節で扱います) と、 localhost への経路を示しています。

localhost に割り当てるインタフェース (Netif 欄) としてこのルーティングテーブルが指定しているのは lo0 で、これはループバックデバイスともいいます。 これは結局のところ出たところに戻るだけなので、 この送信先あてのトラフィックは、LAN に送られずに、すべて内部的に処理されます。

次の行では 0:e0: から始まるアドレスに注目しましょう。 これはイーサネットハードウェアアドレスで、MAC アドレスともいいます。 FreeBSD はローカルなイーサネット上の任意のホスト (この例では test0) を自動的に認識し、 イーサネットインタフェース ed0 にそのホストへの直接の経路をつけ加えます。 この種の経路には、タイムアウト時間 (Expire 欄) も結びつけられており、 指定された時間内にホストからの応答がないことを判断するのに用いられます。 その場合、そのホストへの経路情報は自動的に削除されます。 これらのホストは RIP (Routing Information Protocol) という、 最短パス判定に基づいてローカルなホストへの経路を決定する仕組みを利用して認識されます。

さらに FreeBSD ではローカルサブネットへの経路情報も加えることができます (10.20.30.25510.20.30 というサブネットに対するブロードキャストアドレスで、 example.com はこのサブネットに結びつけられているドメイン名)。 link#1 という名称は、 このマシンの一つ目のイーサネットカードのことをさします。 これらについては、 何も追加インタフェースが指定されていないことがわかります。

これら 2 つのグループ (ローカルネットワークホストとローカルサブネット) は、両方とも routed というデーモンによって自動的に経路が設定されます。 routed を動かさなければ、静的に定義した (つまり明示的に設定した) 経路のみが存在することになります。

host1 の行は私たちのホストのことで、 イーサネットアドレスで示されています。送信側のホストの場合、 FreeBSDはイーサネットインタフェースへ送るのではなく、 ループバックインタフェース (lo0) を使います。

2 つある host2 の行は、 ifconfig(8) のエイリアスを使ったときにどのようになるかを示す例です (このようなことをする理由については Ethernet の節を参照してください)。 lo0 の後にある => は、 インタフェースが (このアドレスがローカルなホストを参照しているので) ループバックを使っているというだけでなく、 エイリアスになっていることも示しています。 このような経路はエイリアスに対応しているホストにのみ現れます。 ローカルネットワーク上の他のすべてのホストでは、 それぞれの経路に対して単にlink#1 となります。

最後の行 (送信先サブネット 224) はマルチキャストで扱うものですが、これは他の節で説明します。

最後に Flags (フラグ) 欄にそれぞれの経路のさまざまな属性が表示されます。 以下にフラグの一部と、それが何を意味しているかを示します。

UUp: この経路はアクティブです。
HHost: 経路の送信先が単一のホストです。
GGateway: この送信先へ送られると、 どこへ送ればよいかを明らかにして、 そのリモートシステムへ送られます。
SStatic: この経路はシステムによって自動的に生成されたのではなく、 手動で作成されました。
CClone: マシンに接続したときにこの経路に基づく新しい経路が作られます。 この型の経路は通常はローカルネットワークで使われます。
WWasCloned: ローカルエリアネットワーク (LAN) の (Clone) 経路に基づいて自動的に生成された経路であることを示します。
LLink: イーサネットハードウェアへの参照を含む経路です。

22.2.2. デフォルトルート

ローカルシステムからリモートホストにコネクションを張る必要がある場合、 既知の経路が存在するかどうかを確認するためにルーティングテーブルをチェックします。 到達するための経路を知っているサブネットの内部にリモートホストがある場合 (Cloned routes)、 システムはそのインタフェースから接続できるかどうか確認します。

知っているパスがすべて駄目だった場合でも、 システムには最後の手段として デフォルト ルートがあります。このルートはゲートウェイルート (普通はシステムに 1 つしかありません) の特別なものです。そして、 フラグ欄には必ず c が表示されています。このゲートウェイは、LAN 内のホストにとって、どのマシンでも外部へ (PPP リンク、DSL、ケーブルモデム、T1、 またはその他のネットワークインタフェースのいずれかを経由して) 直接接続するために設定されるものです。

外部に対するゲートウェイとして機能するマシンでデフォルトルートを設定する場合、 デフォルトルートはインターネットサービスプロバイダ (ISP) のサイトのゲートウェイマシンになるでしょう。

それではデフォルトルートの一例を見てみましょう。 一般的な構成を示します。

ホスト Local1 とホスト Local2 はあなたのサイト内にあります。Local1 はダイアルアップ PPP 接続経由で ISP に接続されています。 この PPP サーバコンピュータは、その ISP のインターネットへの接続点に向けた外部インタフェースを備えた他のゲートウェイコンピュータへ LAN を通じて接続しています。

あなたのマシンのデフォルトルートはそれぞれ次のようになります。

ホストデフォルトゲートウェイインタフェース
Local2Local1Ethernet
Local1T1-GWPPP

なぜ (あるいは、どうやって) デフォルトゲートウェイを、Local1 が接続されている ISP のサーバではなく、T1-GW に設定するのか という質問がよくあります。

PPP 接続で、あなたのサイト側の PPP インタフェースは、 ISP のローカルネットワーク上のアドレスを用いているため、 ISP のローカルネットワーク上のすべてのマシンへの経路は 自動的に生成されています。 つまりあなたのマシンは、どのようにして T1-GW に到達するかという経路を既に知っていることになりますから、 ISP サーバにトラフィックを送るのに、 中間的な段階を踏む必要はありません。

一般的にローカルネットワークでは X.X.X.1 というアドレスをゲートウェイアドレスとして使います。ですから (同じ例を用います)、あなたの class-C のアドレス空間が 10.20.30 で ISP が 10.9.9 を用いている場合、 デフォルトルートは次のようになります。

ホストデフォルトルート
Local2 (10.20.30.2)Local1 (10.20.30.1)
Local1 (10.20.30.1, 10.9.9.30)T1-GW (10.9.9.1)

デフォルトルートは /etc/rc.conf ファイルで簡単に定義できます。この例では、 Local2 マシンで /etc/rc.conf に次の行を追加しています。

defaultrouter="10.20.30.1"

route(8) コマンドを使ってコマンドラインから直接実行することもできます。

# route add default 10.20.30.1

経路情報を手動で操作する方法について詳しいことは route(8) のマニュアルページをご覧ください。

22.2.3. デュアルホームホスト

ここで扱うべき種類の設定がもう一つあります。 それは 2 つの異なるネットワークにまたがるホストです。 技術的にはゲートウェイとして機能するマシン (上の例では PPP コネクションを用いています) はすべてデュアルホームホストです。 しかし実際にはこの言葉は、2 つの LAN 上のサイトであるマシンを指す言葉としてのみ使われます。

2 枚のイーサネットカードを持つマシンが、 別のサブネット上にそれぞれアドレスを持っている場合があります。 あるいは、イーサネットカードが 1 枚しかないマシンで、 ifconfig(8) のエイリアスを使っているかもしれません。 物理的に分かれている 2 つのイーサネットのネットワークが使われているならば前者が用いられます。 後者は、物理的には 1 つのネットワークセグメントで、 論理的には 2 つのサブネットに分かれている場合に用いられます。

どちらにしても、 このマシンがお互いのサブネットへのゲートウェイ (inbound route) として定義されていることが分かるように、 おのおののサブネットでルーティングテーブルを設定します。このマシンが 2 つのサブネットの間のルータとして動作するという構成は、 パケットのフィルタリングを実装する必要がある場合や、 一方向または双方向のファイアウォールを利用したセキュリティを構築する場合によく用いられます。

このマシンが二つのインタフェース間で実際にパケットを受け渡すようにしたい場合は、 FreeBSD でこの機能を有効にしないといけません。 くわしい手順については次の節をご覧ください。

22.2.4. ルータの構築

ネットワークルータは単にあるインタフェースから別のインタフェースへパケットを転送するシステムです。 インターネット標準およびすぐれた技術的な慣習から、 FreeBSD プロジェクトは FreeBSD においてこの機能をデフォルトでは有効にしていません。 rc.conf(5) 内で次の変数を YES に変更することでこの機能を有効にできます。

gateway_enable=YES          # Set to YES if this host will be a gateway

このオプションは sysctl(8) 変数の net.inet.ip.forwarding1 に設定します。 一時的にルーティングを停止する必要があるときには、 この変数を一時的に 0 に設定しなおせます。

次に、トラフィックの宛先を決めるために、 そのルータには経路情報が必要になります。 ネットワークが十分簡素なら、静的経路が利用できます。 また、FreeBSD は BSD の標準ルーティングデーモンである routed(8) を備えています。これは RIP (バージョン 1 および 2) および IRDP を扱えます。 BGP バージョン 4、OSPF バージョン2、 その他洗練されたルーティングプロトコルは net/zebra package を用いれば対応できます。 また、より複雑なネットワークルーティングソリューションには、 GateD® のような商用製品も利用可能です。

このように FreeBSD を設定したとしても、 ルータに対するインターネット標準要求を完全に満たすわけではありません。 しかし、通常利用に関しては十分といえます。

22.2.5. 静的な経路の設定

寄稿: Hoang Al [FAMILY Given].

22.2.5.1. 手動による経路の設定

以下のようなネットワークが存在すると仮定します。

    INTERNET
      | (10.0.0.1/24) Default Router to Internet
      |
      |Interface xl0
      |10.0.0.10/24
   +------+
   |      | RouterA
   |      | (FreeBSD gateway)
   +------+
      | Interface xl1
      | 192.168.1.1/24
      |
  +--------------------------------+
   Internal Net 1      | 192.168.1.2/24
                       |
                   +------+
                   |      | RouterB
                   |      |
                   +------+
                       | 192.168.2.1/24
                       |
                     Internal Net 2
	

このシナリオでは、FreeBSD マシンの RouterA がインターネットに向けられたルータとして動作します。 ルータは外側のネットワークへ接続できるように 10.0.0.1 へ向けたデフォルトルートを保持しています。 RouterB はすでに適切に設定されており、 どこへ向かう必要があるか、 行き着く方法を知っていると仮定します (この例では、図のように簡単です。 192.168.1.1 をゲートウェイとして RouterB にデフォルトルートを追加するだけです)。

RouterA のルーティングテーブルを確認すると、 以下のような出力を得ます。

% netstat -nr
Routing tables

Internet:
Destination        Gateway            Flags    Refs      Use  Netif  Expire
default            10.0.0.1           UGS         0    49378    xl0
127.0.0.1          127.0.0.1          UH          0        6    lo0
10.0.0/24          link#1             UC          0        0    xl0
192.168.1/24       link#2             UC          0        0    xl1

現在のルーティングテーブルでは、RouterA はまだ Internal Net 2 には到達できないでしょう。 192.168.2.0/24 の経路を保持していないからです。 解決するための一つの方法は、経路を手動で追加することです。 以下のコマンドで RouterA のルーティングテーブルに 192.168.1.2 を送り先として、Internal Net 2 ネットワークを追加します。

# route add -net 192.168.2.0/24 192.168.1.2

これにより、RouterA は、 192.168.2.0/24 ネットワーク上のホストに到達出来ます。

22.2.5.2. 永続的な設定

上記の例は、 起動しているシステム上に静的な経路を設定する方法としては完全です。 しかしながら、FreeBSD マシンを再起動した際にルーティング情報が残らないという問題が一つあります。 静的な経路を追加するには、/etc/rc.conf ファイルにルートを追加してください。

# Add Internal Net 2 as a static route
static_routes="internalnet2"
route_internalnet2="-net 192.168.2.0/24 192.168.1.2"

static_routes の設定変数は、 スペースによって分離される文字列のリストです。 それぞれの文字列は経路名として参照されます。 上記の例では static_routes は一つの文字列のみを持ちます。 その文字列は internalnet2 です。その後、 route_internalnet2 という設定変数を追加し、 route(8) コマンドに与えるすべての設定パラメータを指定しています。 前節の例では、以下のコマンド

# route add -net 192.168.2.0/24 192.168.1.2

を用いたので、 "-net 192.168.2.0/24 192.168.1.2" が必要になります。

上記のように static_routes は一つ以上の文字列を持つことが出来るので、 多数の静的な経路を作ることができます。 以下の行は 192.168.0.0/24 および 192.168.1.0/24 ネットワークを、 仮想ルータ上に静的な経路として追加する例です。

static_routes="net1 net2"
route_net1="-net 192.168.0.0/24 192.168.0.1"
route_net2="-net 192.168.1.0/24 192.168.1.1"

22.2.6. ルーティングの伝搬

外部との経路をどのように定義したらよいかはすでに説明しました。 しかし外部から私たちのマシンをどのようにして見つけるのかについては説明していません。

ある特定のアドレス空間 (この例では class-C のサブネット) におけるすべてのトラフィックが、 到着したパケットを内部で転送するネットワーク上の特定のホストに送られるようにルーティングテーブルを設定することができるのは分かっています。

あなたのサイトにアドレス空間を割り当てる場合、 あなたのサブネットへのすべてのトラフィックがすべて PPP リンクを通じてサイトに送ってくるようにサービスプロバイダはルーティングテーブルを設定します。 しかし、国境の向こう側のサイトはどのようにしてあなたの ISP へ送ることを知るのでしょうか?

割り当てられているすべてのアドレス空間の経路を維持する (分散している DNS 情報とよく似た) システムがあり、 そのインターネットバックボーンへの接続点を定義しています。 バックボーン とは国を越え、 世界中のインターネットのトラフィックを運ぶ主要な信用できる幹線のことです。 どのバックボーンマシンも、 あるネットワークから特定のバックボーンのマシンへ向かうトラフィックと、 そのバックボーンのマシンからあなたのネットワークに届くサービスプロバイダまでのチェーンのマスタテーブルのコピーを持っています。

あなたのサイトが接続 (プロバイダからみて内側にあることになります) したということを、 プロバイダからバックボーンサイトへ通知することはプロバイダの仕事です。 これが経路の伝搬です。

22.2.7. トラブルシューティング

経路の伝搬に問題が生じて、 いくつかのサイトが接続をおこなうことができなくなることがあります。 ルーティングがどこでおかしくなっているかを明らかにするのに最も有効なコマンドはおそらく traceroute(8) コマンドでしょう。 このコマンドは、あなたがリモートマシンに対して接続をおこなうことができない (たとえば ping(8) に失敗するような) 場合も、同じように有効です。

traceroute(8) コマンドは、 接続を試みているリモートホストを引数にして実行します。 試みている経路が経由するゲートウェイホストを表示し、 最終的には目的のホストにたどり着くか、 コネクションの欠如によって終ってしまうかのどちらかになります。

より詳しい情報は、traceroute(8) のマニュアルページをみてください。

22.2.8. マルチキャストルーティング

FreeBSD はマルチキャストアプリケーションとマルチキャストルーティングの両方にネイティブ対応しています。 マルチキャストアプリケーションを動かすのに FreeBSD で特別な設定をする必要は一切ありません。 アプリケーションは普通はそのままで動くでしょう。 マルチキャストルーティングに対応するには、 下のオプションを追加してカーネルをコンパイルする必要があります。

options MROUTING

さらに、/etc/mrouted.conf を編集してルーティングデーモン mrouted(8) を設定し、トンネルと DVMRP を設置する必要があります。 マルチキャスト設定についての詳細は mrouted(8) のマニュアルページを参照してください。

本文書、および他の文書は ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/ からダウンロードできます。

FreeBSD に関する質問がある場合には、 ドキュメント を読んだ上で <questions@FreeBSD.org> まで (英語で) 連絡してください。

本文書に関する質問については、 <doc@FreeBSD.org> まで電子メールを (英語で) 送ってください。