次のページ 前のページ 目次へ

6. パケットの料理法の解説

ここまでくれば、料理するべきパケットを選別する方法は分かっています。ルール を完全なものにするため、パケットに対してやるべきことを正確にカーネルに指示 する必要があります。

6.1 送信元 NAT

送信元 NAT を行うということは、送信元アドレスを何か別のものに変換するという ことです。これは POSTROUTING チェインのもとで、最終的にパケットが送信される 直前に行われます −これは重要な点で、というのも Linux ボックス自身の上で 行われる他のどんな操作(ルーティング、パケットフィルタリング)も、パケットは 書き換えないということを意味するからです。それはまた、`-o' (送信インタフェース)オプションで実現可能であるということでもあります。

送信元 NAT は、`-j SNAT' を使って指定し、`--to-source' オプションにより、 特定の IP アドレス、IP アドレスの範囲、そして(UDP, TCP プロトコルの場合 のみ)特定のポート番号やポート番号の範囲を指定します。

## Change source addresses to 1.2.3.4.
# iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to 1.2.3.4

## Change source addresses to 1.2.3.4, 1.2.3.5 or 1.2.3.6
# iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to 1.2.3.4-1.2.3.6

## Change source addresses to 1.2.3.4, ports 1-1023
# iptables -t nat -A POSTROUTING -p tcp -o eth0 -j SNAT --to 1.2.3.4:1-1023

IP マスカレード

IP マスカレードと呼ばれる送信元 NAT の特殊なケースがあります。これは、 標準的なダイヤルアップ接続などの、IP アドレスが動的に割り当てられる場合 にのみ利用すべきものです(静的に IP アドレスが割り当てられるなら、上記の SNAT を使ってください)。

IP マスカレードをやるのに、送信元アドレスを明示的に指定する必要はありません。 IP マスカレードは、パケットが出て行くインタフェースの送信元アドレスを利用 します。ですがもっと重要なのは、そのリンクが落ちた場合に、(切られてしまった) そのコネクションが忘れられてしまっても、新たに IP アドレスが割り当てられて コネクションが復帰したときに、ほとんど誤動作が起きないということです。

## Masquerade everything out ppp0.
# iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE

6.2 宛先 NAT

これは PREROUTING チェインのもとで、パケットが入ってきたその時に行われます  −これは、Linux ボックス自身の上で行われる他のどんな操作(ルーティング、 パケットフィルタリング)も、パケットはその「本当の」宛先を指しているところで 行うからです。それは `-i'(受信インタフェース)オプションで実現可能であると いうことでもあります。

宛先 NAT は、`-j DNAT' を使って指定し、`--to-destination' オプションにより、 特定の IP アドレス、IP アドレスの範囲、そして(UDP, TCP プロトコルの場合のみ) 特定のポート番号やポート番号の範囲を指定します。

## Change destination addresses to 5.6.7.8
# iptables -t nat -A PREROUTING -i eth0 -j DNAT --to 5.6.7.8

## Change destination addresses to 5.6.7.8, 5.6.7.9 or 5.6.7.10.
# iptables -t nat -A PREROUTING -i eth0 -j DNAT --to 5.6.7.8-5.6.7.10

## Change destination addresses of web traffic to 5.6.7.8, port 8080.
# iptables -t nat -A PREROUTING -p tcp --dport 80 -i eth0 \
        -j DNAT --to 5.6.7.8:8080

リダイレクション

リダイレクションと呼ばれる宛先 NAT の特殊なケースがあります −受信 インタフェースのアドレスへの DNAT を行うのと全く同じ効果があり、 簡単便利なものです。

## Send incoming port-80 web traffic to our squid (transparent) proxy
# iptables -t nat -A PREROUTING -i eth1 -p tcp --dport 80 \
        -j REDIRECT --to-port 3128

squid が透過型プロキシとして動作するよう設定する必要があるのに注意すること!

6.3 突っ込んだマッピング

ほとんどの人には全く関係ない、巧妙なテクニックが NAT にはいくつかあります。 ここでは好奇心の強い人のためにドキュメント化しておきます。

ある範囲の複数のアドレスからの選択

ある範囲の IP アドレスが与えられ、使用する IP アドレスを、そのマシンが通信 したうち最も最近利用された IP アドレスをもとに選択します。これにより原始的 な負荷調整が行えます。

NAT 不使用マッピングの生成

全く NAT を用いないコネクションを張らせる指定として `-j ACCEPT' があります。

標準的な NAT の動作

デフォルトでは、ユーザによって与えられたルールの制約内で、コネクションの 変更を出来る限り小さくするべきです。つまり、その必要がなければ、ポート番号 を再マッピングしてはならないということです。

暗黙の送信元ポートマッピング

たとえあるコネクションに NAT が設定されていなくても、 先に張られた別のコネクションがその新たなコネクションにアドレス が重なるようにマッピングされている場合には、 送信元ポート変換が暗黙のうちに行われることがあります。 IP マスカレードのケースを考えると、これはかなり一般的なことです:

  1. IP アドレス 192.1.1.1 の端末によって、ウェブコネクションがポート1024 番から www.netscape.com のポート80番に確立されているとします。
  2. この接続はマスカレードボックスの送信元 IP アドレス(1.2.3.4) を使用してマスカレードされています。
  3. 次にマスカレードボックス自身が、(外部インタフェースの IP アドレスである) 1.2.3.4 のポート 1024 番から、www.netscape.com のポート 80 番にウェブコネクションを確立しようとしたとします。
  4. この時 NAT のコードは、二番目のコネクションの送信元ポート番号を 1025 番に変えるので、二つは衝突しません。

この暗黙の送信元マッピングに関して、ポートは三つのクラスに分けられます:

元のポートと異なるクラスのポートに暗黙のうちにマッピングされることは 決してありません。

NAT が失敗すると何が起こるか

ユーザが要求するコネクションを一意にマップすることができない場合、 その接続要求は廃棄されます。また、パケットが正しく構成されていなかったり、 NAT ボックスのメモリが不足しているなどの理由で、どのコネクションの一部とも 分類できなかったパケットも同様に破棄されます。

複数のマッピング、重複、そして衝突

様々なアドレスを属性にしているパケットに対して、ある一つのアドレス をマッピングする NAT ルールを設定することは可能です −NAT のコードは衝突を回避するように周到に書かれています。従って、 送信元アドレスとして 192.168.1.1 と 192.168.1.2 の両方に対して 1.2.3.4 をマップしても大丈夫です。

更にはマッピングするマシンを通過しないと到達できないアドレスでさえあれば、 実際に使用されてる IP アドレスの上に重ねてマッピングすることも同様に可能です。 つまりインターネット用のアドレス (1.2.3.0/24) が割り当てられてはいるが、 実際の内部ネットワークはこれらのアドレスと同時に 192.168.1.0/24 のとプライベート・インターネット・アドレスを使っていたとしても、 192.168.1.0/24 のソースアドレスを 1.2.3.0 のネットワークに単純に マッピングするだけで、衝突の恐れなしに NAT 可能です:

# iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth1 \
        -j SNAT --to 1.2.3.0/24

同じ理屈が、NAT ボックス自身により使用されるアドレスにもあてはまります  −これこそが (マスカレードされるパケットと、ボックス自身から来る「本当の」 パケットの間でインタフェースのアドレスを共有することによる)IP マスカレード の動作なのです。

その上、同じパケットを幾つもの異なるターゲットにマップ可能で、そのマッピング は共有されます。例えば、IP アドレス 1.2.3.5 にマッピングをしたくない場合は、 以下のようにすれば可能です:

# iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth1 \
        -j SNAT --to 1.2.3.0-1.2.3.4 --to 1.2.3.6-1.2.3.254

ローカルに生成されたコネクションの宛先の変更

NAT のコードは、OUTPUT チェインの中に DNAT ルールを挿入することを許可 しますが、カーネル 2.4 では完全にはサポートされていません (可能ではあるのですが、新しい設定オプション、ある程度のテスト、 そしてかなりのコーディングが必要になります。 それは誰かが Rusty にそうしたものを書くと請け負ってくれない場合の話ですが、 僕としては、すぐにそうなるとは期待していません)。

現在ある制限は、宛先をローカルマシンにしか変更できないことで (例:`j DNAT --to 127.0.0.1')、他のどのマシンにも変更できず、 そうでないとリプライが正しく転送されないのです。


次のページ 前のページ 目次へ