先にも述べたように、 TCP/IP は多層構造になっている。ということは、或る層でひとつの機能を働かせながら、別の層で別の機能を働かせ、そしてまた別の層で...ということが可能なわけだ。レイヤー構造を持つ意義は、考えてみれば単純だ。
多層構造となっている最も大きな理由は、拡張を容易にするため。例えばアプリケーション層に新たな機能を追加したい時にも、わざわざ TCP/IP スタックのコードを書き直したり、アプリケーション側に TCP/IP スタックの一切合切を装備しなくても済む。同様に、新しいネットワークインターフェースカードを創るたびにプログラムを逐一書き直すなんてことも必要ない。各レイヤーは独立して働けるように、他のレイヤーのことには必要最小限だけ関知していればいいようになっているのだ。
カーネルの備える TCP/IP プログラミングコードについて語る時、実はそれは TCP/IP スタックのことを言っている場合が多い。 TCP/IP スタックとは、ネットワークアクセス層から表層のアプリケーション層に至るまでの、サブレイヤー一切合切のことである。 |
レイヤーの話をする時、大元となる構造定義がふたつある。ひとつは OSI (Open Systems Interconnect) 参照モデルで、これは TCP/IP を 7 層に分けている。ただし、我々の興味はどちらかというと TCP/IP 階層モデルのほうにあるので、ここではざっと眺める程度にしておこう。しかし、歴史的な意味から、OSI参照モデルにも興味深い点はある。特に、さまざまな種類の異なるネットワークを扱わなければならない場合だ。 レイヤーは OSI参照モデルの の一覧に示した通りだ。
どちらの参照モデルが広く使われているかについては、意見が分かれている。ただ、どちらかといえば OSI 参照モデルのほうが未だに優勢なように見える。とはいえ、事情は国によっても異なる。US および EU の大多数の国においては、技術者や営業の会話の中で使うなら OSI を基本と考えるほうがいいようだ。 しかしながら当文書では、特に断りのない限り、一貫して TCP/IP 参照モデルのほうで話を進める。 |
アプリケーション層 (Application layer)
プレゼンテーション層 (Presentation layer)
セッション層 (Session layer)
トランスポート層 (Transport layer)
ネットワーク層 (Network layer)
データリンク層 (Data Link layer)
物理層 (Physical layer)
我々がひとつのパケットを送ったとすると、そのパケットはリストの上方から下方へと進み、それぞれのレイヤーが、カプセル化 (encapsulation) と呼ばれる段階で各々独自のヘッダ一式をくっつける。そして目的地へ行き着くと、今度はリストを逆順に辿り、パケットからヘッダが一個一個取り除かれていく。取り除かれる際、各ヘッダは、パケット内のデータから目的のホストの得るべき情報を全て渡していく。そうして遂に、送信目的だったアプリケーションあるいはプログラムに辿り着くわけだ。
もうひとつの、そして我々にとって、より重要な意味を持つレイヤーモデルが、 TCP/IP構造モデルだ。それを一覧にしたのが下記の TCP/IP 構造リスト。 TCP/IP構造モデルの階層数については、これといった共通認識は存在しない。とはいえ、3 ないし 5 層から成るというのが一般的な認識となっていて、図解や説明がなされる時には、たいてい 4 層として扱われているようだ。混乱を避けるため、このドキュメントでも、一般的な 4 層モデルのみを対象に話を進める。
アプリケーション層 (Application layer)
トランスポート層 (Transport layer)
インターネット層 (Internet layer)
ネットワークアクセス層 (Network Access layer)
見ての通り、 TCP/IP の構造は OSI参照モデルとそっくりだ。だが、まだそう断じるのは早計だ。入る時、出る時に、ヘッダをくっつけたり取り去ったりするのは OSI参照モデルの時と同じだ。
では、最近よくコンピュータネットワーキングの比喩に用いられるスネイルメールの手紙に喩えてみよう。[訳者註: snail-mail: 昔ながらの紙の手紙のこと。 eメールの普及によって逆に最近生まれた言葉]。物事にはすべて順序がある。 TCP/IP も同じだ。
ご機嫌伺いの手紙を送ろうとしているとしよう。まず初めに、内容あるいは質問する事柄を考えなければならない。実際のデータで言えば、これはアプリケーション層に置かれることになる。
そうしたら次に、便箋に内容を書いて封筒に入れ、どこの会社あるいはどこの家の誰かさん宛てだという旨を封筒に書くはずだ。例えばだが、おそらくこんな風に:
ジョン・ドー 様
これは TCP/IP で言うところのトランスポート層にあたる。トランスポート層で、今仮に TCP を相手にしているとすれば、必ずというわけではないがこれは何らかのポートナンバー (例えば 25 など) かもしれない。
ここで、今度は封筒に受取人の住所を書く。こんな具合だ:
V. Andersgardsgatan 2
41715 Gothenburg
これはインターネット層にあたる。インターネット層は、 TCP/IP ネットワーク上のどこへ行けば受取人つまりホストへ行き着けるかを示す情報を格納する。ちょうど、封筒に書く宛名と同じ。つまり、'192.168.0.4' といった IPアドレスがこれにあたる。
そして最後のステップは、この封筒に収まった手紙をポストへ投函する作業だ。これとほぼ同義なのが、パケットをネットワークアクセス層へ送り込むこと。ネットワークアクセス層は、パケットの搬送される物理的なネットワークにアクセスするための、機能や手順を含有している。
受取人は、封書を受け取ったら、封筒から手紙を取り出すだろう (つまり非カプセル化(decapsulate))。受け取った手紙には返事が必要かもしれないしそうでないかもしれない。いずれにしろ、返信するとすれば、受け取った人は、手紙に書いてあった宛先と差出人を逆にして送るだろう。差出人が宛先に、宛先だった人が差出人になるようにするわけだ。
ここで頭に入れておかなければならないのは、 iptables はインターネット層 とトランスポート層 のヘッダに作用するべく作られているということだ。確かに、基本的フィルタの中にもアプリケーション層 やネットワークアクセス層 で使えるものがある。しかし、こうした事柄は iptables の設計意図から外れるものだし、 iptables はそういう用途に向くようには作られていないのだ。 例えば string マッチを使ってパケットの中の文字列、例えば "GET /index.html" でパケットを捕まえるとしよう。これはうまくいくだろうか? 普通は YES だ。だが、パケットのサイズが非常に小さい時にはそうはいかない。これは iptables がパケット単位で作用するように作られているからで、もしも文字列が複数のパケットへと分断されていたとしたら、 iptables はそれを一続きの文字列として検出することができない。そうした理由から、アプリケーション層 でのフィルタリングを行うという用途であれば、プロキシなど別のものを使うほうがずっとずっと確実だ。こうした問題については、 IPフィルタリングとはで詳しく考察する。 |
iptables および netfilter の活動の舞台は主にインターネット層 とトランスポート層 なので、当チャプターのこれ以降のセクションでも、主としてそれらの層に焦点を当てていく。インターネット層 の配下には、 IP プロトコルという無視しがたい存在がある。その他に、例えば GRE プロトコルのように、言及すべきものもなくはないが、そうしたプロトコルに出会う機会は限られている。また、 iptables は (その名が示す通り) その種のプロトコルを上手に扱うようには作られていない。上に挙げた様々な理由から、このドキュメントでは主に、インターネット層 の IP プロトコルと、トランスポート層 の TCP, UDP, ICMP に焦点を当てていく。
ICMP プロトコルは、実はふたつのレイヤーが混じり合ったものだ。 ICMP パケットはインターネット層 で活動するものでありながら、 IP プロトコルと全く変わらないヘッダを持ち、その他幾つかのヘッダに加え、カプセルのすぐ内側にはデータも格納している。これについては ICMPの特徴 の中でもっと詳しく述べることにする。 |