パケットがファイヤーウォールに入ると、まずハードウェアに行き当たり、次にカーネルの持つしかるべきデバイスドライバ に渡される。それから、目的の (ローカル上の) アプリケーションに送られるとか、別のホストに送られるなど、某かの沙汰を受けるまでに、パケットはカーネル内の一連の行程を通過していく。
まず、我々のローカルホスト に宛てたパケットについて見てみよう。受信すべきアプリケーションに辿り着くまでに、パケットは以下のような道のりを旅する。
Table 6-1. ローカルホスト (我々のマシン) を宛先とするパケット
行程 | テーブル | チェーン | コメント |
---|---|---|---|
1 | 通信ケーブル上。 例) インターネット | ||
2 | インターフェースに入る。 例) eth0 | ||
3 | raw | PREROUTING | このチェーンは、コネクション追跡の発動する手前でパケットを処理する時に使用する。例えば、特定のコネクションにコネクション追跡が働かないようにするといった使い方がある。 |
4 | ステート機構 チャプターで述べるコネクション追跡が機能するのがここ。 | ||
5 | mangle | PREROUTING | このチェーンは通常、パケットの改変 (mangle) に使う。例えば TOS の変更などだ。 |
6 | nat | PREROUTING | 主に DNAT に使用するチェーン。このチェーンはバイパスされる場合もあるので、ここでのフィルタリング処理は御法度。 |
7 | ルーティング判断。例) ローカルホスト宛か、フォワードされるならどこへ | ||
8 | mangle | INPUT | この時点で、mangle の INPUT チェーンにぶつかる。ルーティング後、且つ、マシン上の実際のプロセスに送られる前の、パケット改変に使用する。 |
9 | filter | INPUT | ローカルホスト宛のパケットに対してフィルタリングを行うのは、すべてここ。ローカルホスト宛の進入パケットは、インターフェースや入ってきた方向に関わらず、必ずこのチェーンを通る。 |
10 | ローカルプロセス/アプリケーション。 例) サーバ/クライアントプログラム |
今回は FORWARD チェーンでなく INPUT チェーンを通ってくるという点を憶えておいてていただきたい。極めて論理的だ。おそらく最初は、論理的に見えることといったらテーブルとチェーンを巡ってくることくらいしかないかもしれないが、しばらく考察していけば、じきにはっきりしてくるはずだ。
では次に、我々のローカルホスト から出ていくパケットとその通り道を見てみよう。
Table 6-2. ローカルホスト (我々のマシン) を送信元とするパケッ ト
行程 | テーブル | チェーン | コメント |
---|---|---|---|
1 | ローカルプロセス/アプリケーション。 例) サーバ/クライアントプログラム | ||
2 | ルーティング判断。どういった送信元アドレスを使用するか、出口はどのインターフェースかなど必要な情報の収集。 | ||
3 | raw | OUTPUT | ローカルで発生したパケットにコネクション追跡が働く前に処理を施すならここ。例えば、特定のコネクションに追跡が働かないようマークを付けるといったことができる。 |
4 | ローカルで発生したパケットにコネクション追跡が働くところ (ステートの変化など)。それについては ステート機構 チャプターで詳しく述べる。 | ||
5 | mangle | OUTPUT | パケットを改変するところ。副作用を避けるため、フィルタリング処理はすべきでない。 |
6 | nat | OUTPUT | ファイヤーウォールから出ていくパケットに NAT をかけるのはここ。 |
7 | ルーティング判断。ここでルーティング判断が必要なのは、パケットに求められるルーティング方針が、前の mangle と nat によって変更された可能性があるからだ。 | ||
8 | filter | OUTPUT | ローカルホストから出ていくパケットをフィルタリングするのがここ。 |
9 | mangle | POSTROUTING | mangle テーブルの POSTROUTING チェーンは、パケットがホストを離れる前、且つ、ルーティング判断がなされた後で、パケット改変をしたい場合に使う。ファイヤーウォールを通過中のパケットも、ファイヤーウォールで作られたパケットも、ともにこのチェーンにぶつかる。 |
10 | nat | POSTROUTING | 前に説明した SNAT が行われるのはここ。副作用を避けるため、ここではフィルタリングを行うべきでない。デフォルトポリシーを DROP にしても、ある種のパケットはここを擦り抜けてしまう。 |
11 | いずれかのインターフェースから出ていく。例) eth0 | ||
12 | 通信ケーブル上。 例) インターネット |
この例では、パケットは他ネットワーク上の他ホストに宛てられたものだとする。パケットは今までとは異なった下記のような道のりを巡る。
Table 6-3. フォワードパケット
行程 | テーブル | チェーン | コメント |
---|---|---|---|
1 | 通信ケーブル上。 例) インターネット | ||
2 | インターフェースに入る。 例) eth0 | ||
3 | raw | PREROUTING | ここで、特定のコネクションがコネクション追跡処理されないようにしておくことができる。 |
4 | ローカル以外で発生したコネクションにコネクション追跡が作用するのがここ。 ステート機構 チャプターで詳しく述べる。 | ||
5 | mangle | PREROUTING | このチェーンは通常、パケットの改変に使われる。例えば TOS の変更などだ。 |
6 | nat | PREROUTING | 主として DNAT に使うチェーン。SNAT は後で行う。パイパスされる場合もあるのでフィルタリングは避けるべき。 |
7 | ルーティング判断。例) ローカルホスト宛か、フォワードならどこへ | ||
8 | mangle | FORWARD | 次にパケットは mangle テーブルの FORWARD チェーンに送り込まれる。極めて特殊な用途でのパケット改変に使用する。ここでの改変は、最初のルーティング判断の後であり、且つ、パケットが送出される直前の最終ルーティング判断の前となる。 |
9 | filter | FORWARD | パケットは FORWARD チェーンに送られる。ここを通るのはフォワードされたパケットだけで、そのフィルタリングはここで行う。フォワードされたパケットは (進行方向にかかわらず) 必ずここを通るので、ルールセットを書く際には、ここを検討しよう。 |
10 | mangle | POSTROUTING | すべてのルーティング判断を経た後だが、まだパケットがマシン上にあるうちに施す、特殊なタイプのパケット改変処理をしたい場合にこのチェーンを使う。 |
11 | nat | POSTROUTING | SNAT を行うならここをおいて他にない。ある種のパケットはカスりもせずに擦り抜けてしまうので、フィルタリングに使ってはならない。ここはマスカレード を行う行程でもある。 |
12 | 出口インターフェースから出る。 例) eth1 | ||
13 | 再び通信ケーブル上へ。 例) LAN |
ご覧の通り、かなりたくさんの行程を通って行く。パケットを止めるのは iptables のどのチェーンでもできるし、壊れたパケットはさらに他のどこでも止めることができる。しかし、何より注目すべきは、iptables 全体を貫くこの流れだ。インターフェースなどの違いによって使い分けるような特定のチェーンやテーブルなど一切ないという点に注目していいただきたい。このファイヤーウォール/ルータを通ってフォワードされるパケットは、もれなく FORWARD を通るのだ。
フィルタリングを行うのに、前のシナリオに出てきた INPUT チェーンを使ってはいけない! INPUT は、他ならぬローカルホストを行き先とするパケット専用にできているのだ。 |
シナリオが異なればパケットの通ってゆくチェーンも三者三様であることが分かっただろう。それを上手にマップにまとめると、こんな風になる:
図の意味を明確にするため、こんな場合を考えてみよう。ローカルマシン以外に宛てたパケットが、最初のルーティング判断に入ってきたとすると、そのパケットは FORWARD チェーンを通るよう誘導される。一方、ローカルホストが聞き耳を立てている IP アドレスに宛てられたパケットは、 INPUT チェーンを通してローカルマシンに送られる。
もうひとつ注目すべきは、パケットが他でもないローカルマシンに宛てたものだとしても、 PREROUTING チェーンで NAT することにより、宛先を変更できるという事実だ。この変更は最初のルーティング判断より前に行われるため、パケットはそれ以降、変更された宛先を反映した形で扱われる。この方法により、ルーティング判断の前にパケットの誘導方針が変更できるのだ。パケットは、図中のどれかひとつの経路を必ず通ることにも注目してほしい。もし、パケットがやってきたのと同じネットワークへ DNAT してやれば、最終的にネットワークをおさらばするまで、パケットはチェーンの残り部分をさらに旅し続ける。
もっと詳しく知りたくなったなら、rc.test-iptables.txt を使うといい。このスクリプトを使えば、テーブルとチェーンをパケットがどのように通っていくか試すための実験に必要なルールが出来上がるはずだ。 |