注意: この文書はかなり以前に書かれたものなので、 いまどきの Linux 環境にはあてはまらない箇所があります。 (JF Project)
このドキュメントは Linux 上で PPP や SLIP サーバデバイスとともに プロクシ ARP (Address Resolution Protocol) を使おうと考えている人 を対象にして書かれています。 他の文献では、プロクシ ARP を 「gracious ARP」 (愛想のよい ARP)などと 呼んでいることもあります。 プロクシ ARP を使いたいという要求はよく出ます。これが使えない場合、 ソフトウエアの不良だと考え、なぜ使えなくなってしまったのだろう、 といぶかる人達もいます。
このドキュメントが助けとなって、プロクシ ARP はどのようなときに有用で、 どのようなときには使わなくてもよいのかをよく理解してもらえるよう 願っています。
プロクシ ARP を使うと、「(プロクシ)サーバ」における経路テーブルさえ 変更すれば、他のシステムでは経路テーブルを変更する必要がありません。 このことは、リモートシステムの動的なネットワーク接続が可能になると いうことを意味しています。
ここで、「サーバ」と呼んでいるのは、ある意味では誤りかもしれません。 TCP/IP は、ピアーツーピアー(対等)のネットワーク環境だからです。 他のシステムでは、サーバーが資源を提供することで、「共有」され、 クライアントはこれを「利用」しますが、TCP/IP には、この手の クライアント/サーバー関係はありません。 とはいえ、「電話を取るコンピュータ」をサーバと呼び、 「電話を架けるコンピュータ」をクライアントと呼ぶのは便利ですよね。
Linux のネットワークソフトは プロクシ ARP を直接サポートしています ので、他のシステムで使われている proxyarpd のような特別なデーモン は必要ありません。
PPP をサポートするコード(pppd)と、SLIP をサポートするコード(の少 なくとも一つ、dip-uri)の両方が proxy ARP をサポートしているはずです。 これに加え、ネットワーク用プログラム ARP も経路テーブルを管理し、 表示することができるはずです。
プロクシ ARP がどのように動作し、どんな時に使われるのかを理解する ためには、一般的にネットワークがどのように機能するのかについて 基本的理解が必要です。 以下の3つの章では TCP/IP ネットワークがどのように機能し、ルーティングが どういう風に動作するのか、を簡単に述べます。
イーサネットやトークンリングを使ったネットワークはすべて MAC (Media Access Control) アドレスを使って実現されています。 これはそれぞれのコントローラーに割り当てられたハードウエアアドレス であり、それぞれの MAC アドレスは世界中で唯一(unique)のものです。 これはコントローラーのメーカが割り当てます。 ソフトウエアによって変更することも可能ですが、一般的な意味では ルール違反です。
IP アドレスは 「ARP キャッシュ」 と呼ばれる、ソフトウエア上の特別な テーブルによって MAC アドレスに変換されます。 ネットワークソフトが、 IP パケットを指定されたアドレスに送る時 には、MAC アドレスを知るためにこのキャッシュを検索します。 キャッシュの中になかった場合には、 IP アドレスから MAC アドレス に変換するために、ネットワークに接続されているすべてのシステムに 対して特殊な要求を発行します。 これが ARP (Address Resolution Protocol)要求と呼ばれているものです。
ARP 要求に対しては それに対応する MAC アドレスが返されます。 この MAC アドレスは、次には ARP を使わなくて済むように、キャッシュ に蓄えられます。
プロクシ ARP はこの仕組みを使って、リモート接続をうまく処理することが できるわけです。
キャッシュの中のエントリーを削除するルールもありますが、この ドキュメントではそれについては触れません。これに関しては IP ネットワークに関するドキュメントを参照して下さい。
(トークンリングは開発中で、テストベースでは利用可能ですが、 Linux の一般的なネットワーク媒体という意味ではやはりイーサネット です。ですからここから先、「イーサネット」という言葉を使います。 同様の機能はトークンリングでも使えます。トークンリングの ソースルーティングに関わりなく。)
目的は、ひとつのネットワークアダプタに対して、2つ以上の IP アドレスを割り当てることにあります。
これは、イーサネットコントローラのハードウエアアドレスに対応した、 追加の IP アドレスのエントリーを ARP キャッシュに生成することで 実現されます。 これによって、 IP アドレスをハードウエア (MAC) アドレスに変換する ARP 要求に対して Linux システムはうまく応答することができるわけ です。
[前もっておことわりしますが、ここでは、「スパンニング・ツリー (spanning-tree)」ルーティングについて述べており、IP パケットの 「ソース・ルーティング(source-routing)」ではありません。 トークンリングではソースルーティングが使われますが、これは IP の ソースルーティングではなく、(トークンリングの)MAC 層で行われて るものです。 トークンリングで MAC ソースルーティングを行っているのは、それが トークンリングによるパケットの配送に必要だからです。 一般的には IP ソースルーティングを使う事は推奨できません。]
プロクシ ARP についてもっと詳しく知るためには、IP パケットが ネットワーク上でどのようにルーティングされるのかを知る必要がありますが、 ここではあまり詳しく述べるつもりはありません。 詳しい情報を知りたい方には、深く解説された、たくさんの本があります。 (本が嫌いでしたら、RFC ドキュメントをお読みください。)
IP パケットは、それが経由するネットワークのそれぞれの段階で ルーティングされます。それぞれのホスト、ルーター、ゲートウエイ は、それぞれが経路テーブル情報のコピーを所有し、それに もとづいてそれぞれの IP パケットをどこに送ればよいかを決定します。
ルーティングは、「IP ネットワーク」 を使って行なわれます。 それぞれのネットワークインターフェースには、ユニークな IP ネットワークと、IP アドレス、ネットマスクが割り当てられています。 「IP ネットワーク」 とは、単純にIP アドレスと ネットマスクのビット ごとの積をとったものです。例えば、IP アドレス 10.124.35.40 で、 ネットマスクが 255.255.0.0 の場合には、「IP ネットワーク」 は、 10.124.0.0 となります。 この例ではバイト単位のネットマスクを使っていますが、バイト単位では ないネットマスク(訳注:例えばサブネッティングした時など)の場合でも 同様です。
Linux はネットマスクを経路エントリーと関連づけます。 システムに経路を付け加える時 (訳注: route コマンドなど) には、 そのIP アドレスと関連する行き先のデバイスを指定しますが、 この際にネットマスクを指定しなければ、ifconfig でそのデバイス を設定したときに指定したデフォールトネットマスクが使われます。
ルーティングに関しての理解を助けるために、次のような構成の システムを考えてみましょう。
Destination Netmask Gateway Flags Device
10.124.0.0 255.255.0.0 0.0.0.0 U eth0
10.125.0.0 255.255.0.0 0.0.0.0 U eth1
10.126.0.0 255.255.0.0 10.125.31.1 UG eth1
10.124.12.5 255.255.255.255 0.0.0.0 UH ppp0
0.0.0.0 0.0.0.0 10.124.25.1 U eth0
このシステムは3つのネットワークデバイスを持っています。 2つはイーサネットコントローラで、1つは PPP デバイスです。 これら3つのいずれからも IP パケットは到着し、さらにこのシステム を通じて、 3つのどのデバイスに対してもパケットは転送されます。
デフォールトの経路は、上のエントリーで示されている通り、 10.124.25.1 のゲートウエイデバイスです。 ゲートウエイに送るためには eth0 コントローラが使われます。
PPP デバイスが1つ接続されており、その IP アドレスは 10.124.12.5 です。
eth0 デバイスは IP ネットワーク 10.124.0.0 上にあり、eth1 デバイスは IP ネットワーク 10.125.0.0上にあります。
さらに、IP アドレス 10.125.31.1 のゲートウエイを通じて利用可能な IP ネットワーク 10.126.0.0 へのネット経路が存在します。
ルーティングがどのように行われるのかを理解するために、10.125.45.1 に送られる IP パケットを考えてみましょう。
Linux は経路テーブルを検索し、それぞれのエントリからネットマスクを 取りだし、ビットごとの積をとり、行き先の IP アドレスと比較します。 合致したら、パケットはそのデバイスに送られます。
結果として、IP アドレス 10.125.45.1 のパケットは、eth1 デバイスに 送られます。
同様に、 IP アドレス 10.124.12.6 のパケットは eth0 デバイスに送られ るのですが、IP アドレス 10.124.12.5 のパケットは ppp0 デバイスに 送られます。 なぜなら、ppp0 デバイスは 10.124.12.5 というただひとつの IP アドレスだけしか受け取ることができないからです。
10.126.31.4 宛のパケットの場合はちょっと異なります。 この場合には、このアドレスに接続された「ゲートウエイ」が存在する からです。 上で述べたようなのと同じ方法で検索されますが、ただ単に eth1 デバイス に送られるのではなく、10.125.31.1 という IP アドレスのシステムに 送られるのです。つまり、最終的な行き先のアドレス 10.126.31.4 ではなく、 ゲートウエイの IP アドレス (10.125.31.1) に対応する MAC アドレスに 送られるわけです。
10.125.31.1 のシステムに到着したら、そのシステムの経路テーブルを 使って、最終的な行き先の 10.126.31.4 に転送されます (たとえばその システムの eth3 インターフェースを使って)。
このようなルーティングでは、いろいろな誤りが発生し得ます。 それについてはここではあまり触れたくありませんが、たとえば、 10.126.31.1 が 10.126.31.4 のアドレスに対する経路を持っていなかった場合、 もともとの送り元に対して、ICMP (Internet Control Message Protocol) パケットを送り返し、「そのホストに対する経路が無い」ことを知らせます。
さて、基礎として必要な部分については説明が終わったので、このドキュメント の目的の部分に移ることにしましょう。
プロクシ ARP を実行している Linux が、IP アドレスおよび対応するハー ドウエア MAC アドレスのエントリを ARP キャッシュに格納することと、 このキャッシュが IP アドレスを MAC アドレスに変換するのに使われると いうことを思い出して下さい
リモートシステムが IP アドレス 10.124.12.5 に接続するときに、Linux はこの IP アドレスと、eth0 コントローラに対応する MAC アドレスを ARP キャッシュに格納します。
その後に IP アドレス 10.124.12.5 を MAC アドレスに変換する要求 (ARP) を受け取った場合、このテーブルから得たエントリーを要求元に返します。 その結果、この IP アドレスに送られたパケットは、いったんこのサーバに 送られ、サーバはそれをリモートシステム (10.124.12.5) に転送します。
これが プロクシ ARP の仕組みです。 サーバは リモートな IP アドレスに対する proxy (つまり、代理人、でしゃばり屋、 「表向きの」人などなど) として機能するわけです。 つまり、ARP 要求に応答することで、リモートな IP アドレスに対する パケットを受け付け、それらを転送するわけです。
ところで、プロクシ ARP がうまく動作するためには、リモートな IP アドレス (この例では 10.124.12.5) は、(訳注:サーバに接続されている) ネットワーク アダプタの IP ネットワークのうちの一つでなければなりません。
これには二つの理由があります。
一つ目の理由は、コントローラの MAC アドレスは、それに対応する IP アドレス の ARP キャッシュに格納されるからです。ARP キャッシュは、IP アドレス から MAC アドレスへの変換テーブルなので、ARP 割り当て (assignment) を おこなうためには、MAC アドレスが必要です。
二番目の理由は、ネットワーク上のすべてのシステムは、それぞれ独自に ルーティングをおこなっているという点です。 しかし、それぞれのシステムは少なくとも、リモートな IP アドレスに対して IP パケットを送るためには、「それと同じ線につながっている」サーバの ネットワークアダプタに送らなければならないことはわかっています。
(校正者注:リモート 10.124.12.5 に対する Proxy ARP をあてがう インターフェースは、10.124.0.0 ネットワークに接続されている必要がある、 ということでしょう。 ほかのネットワークにあるシステムが 10.124.12.5 にパケットを送る場合、 とりあえず 10.124.0.0 のネットワークまで要求を送り付けてくるはずなの で、インターフェースが 10.123.0.0 ネットワークなどにあっても、そもそ も ARP 要求があったことがわかりませんから。(ARP 要求はネットワークに 対するブロードキャストとして実行されるのではなかったかと思います。))
リモートの IP アドレスが、10.124.12.5 ではなくて、例えば 10.200.3.1 の 場合を考えてみましょう。
リモートシステムがわかっているのは、IP ネットワーク 10.124.0.0 に送る ためには eth0 に接続されているケーブルにパケットを送ればいい、という ことだけです。しかし、10.200.0.0 という IP ネットワークはありません。 この宛先のパケットをどこへ送ればいいのかわからないわけです。
これは、プロクシ ARP を使おうとしてもうまく動作しない場合に、最もよくある ケースです。宛先の IP アドレスが、自分に接続されているネットワーク インターフェースに割り当てられている、いずれの IP ネットワークアドレス とも異なるという場合です。
もう一度強調しておきますが、もし ARP 要求に対して複数の応答を 受け取った場合、BSD システムでは相当ひどいことになります。
これは、上で述べた問題のちょっとしたバリエーションです。ネットワーク 上にすでに存在するIP アドレスに対する プロクシ ARP を実行すると、 2つの応答が生成されることになります。 つまり、サーバーがリモートシステムとの接続にプロクシ ARP を 適用する場合に、現在ネットワークで使用中の IP アドレスを リモート接続に流用したりしてはいけない、ということです。
(校正者注:本来の IP アドレスのマシンへのコネクションをサーバが横取り して proxy ARP に使ってしまう、つまり本来のコネクションが成立しなく なる、ということではないかと思います。)
あなたが プロクシ ARP を使えない場合にはいくつかの代替手段があります。
もっとも簡単なのは、全てのリモートアドレスがそれぞれの IP ネットワーク アドレスを所有できるように、リモート IP アドレスをサブネット化してしまう という方法です。 そして、それぞれのルーター (すべてのホスト上で、ゲートウエイアドレスと して表示されているすべてのデバイスです。) 上にネットワーク経路を 付け加えるのです。
これによって、それぞれのリモート IP アドレスが接続されているサーバに 対してその IP ネットワーク宛の(パケットが)送られるようにできます。
(校正者注: リモートマシンのアドレスをまとめてサブネットに押し込む -> そのサブネットへの経路をゲートウェイ(サブネットへのゲートウェイマシンの、 元々のゲートウェイ)に書く。-> サブネット化したネットワークへの接続要求が、 サブネットのゲートウェイにくるようになる。ということでしょうか。)
この代わりに、ルーターと、サーバ上の gated を使うということも できます。
IP ネットワークをサブネット化したくない場合には、すべてのホスト経路を指定 してしまう、という方法もあります。 つまり、全てのリモート IP アドレスそれぞれに対して、それぞれのルーター エントリーを指定してしまうのです。
ゲートウエイとルーター上の情報をアップデートする必要はありますが、 ネットワーク上の全てのホストを変更する必要はありません。
それぞれのホストがルーターにパケットを送る時に使われるデフォールトルート を通じて、「ICMP re-direct パケット」が、要求を発行したホストに送られ、 その結果、それぞれのサーバ上にホスト経路が自動的に追加されるからです。
プロクシ ARP がどのように動作し、どのようなものか、を少しでも 説明できたことを願っています。
pppd や dip-uri を使う場合には、この機械のような手順を知っている必要は (幸運なことに)ありません。これらのソフトウエアが自動的に実行して くれるからです。
プロクシ ARP は万能の解決ではありません。いくつかの場合にうまく 機能する解決方法にすぎません。
あなたのネットワークの問題にこの機能が役に立つかどうか、自分で判断で きることを期待しています。
もっと情報が必要な方には、W. Richard Stevens 氏による 「TCP/IP Illustrated, volume 1」 "The protocols" (アジソンウエスレイ社刊) などがいいかもしれません。
読んでくれて、ありがとう!
これは、Linux MINI-HOWTO の、Proxy-ARP の翻訳です。 意訳も多くありますが、ご容赦ください。 また、誤訳や、もっとわかりやすい訳案などありましたら、 ぜひ訳者までフィードバックをお願い致します。
日本語訳 : 川島 浩 (kei@sm.sony.co.jp) 校正 : 堀江 誠一 さん (shorie@ibm.net) 鴨澤 眞夫 さん (k957134@sci.u-ryukyu.ac.jp) 中野 武雄 さん (nakano@apm.seikei.ac.jp)