Linux 2.4 NAT HOWTO Rusty Russell, mailing list netfilter@lists.samba.org $Revision: 1.18 $ $Date: 2002/01/14 09:35:13 $ 日本語訳:yomoyomo (ymgrtq@ma.neweb.ne.jp) v1.18j 2002 年 02 月 01 日 この文書は、2.4 系 Linux カーネルにおける、IP マスカレード、透過プロク シ、ポートフォワーディング他の、ネットワークアドレス変換の動作について 記述するものです。原文は にあります。 ______________________________________________________________________ 目次 1. はじめに 2. 公式ウェブサイトやメーリングリストはどこにありますか? 2.1 ネットワークアドレス変換とは何ですか? 2.2 どうして NAT が必要なのですか? 3. NAT の二つのタイプ 4. 2.0、2.2系カーネルからの手っ取り早い移行 4.1 僕は IP マスカレードを使いたいだけなんです! 助けて! 4.2 ipmasqadm はどうしたの? 5. 何に NAT を行うかを制御する 5.1 iptables を利用した単純な選択 5.2 どのパケットを料理するか選択する賢いポイント 6. パケットの料理法の解説 6.1 送信元 NAT 6.1.1 IP マスカレード 6.2 宛先 NAT 6.2.1 リダイレクション 6.3 突っ込んだマッピング 6.3.1 ある範囲の複数のアドレスからの選択 6.3.2 NAT 不使用マッピングの生成 6.3.3 標準的な NAT の動作 6.3.4 暗黙の送信元ポートマッピング 6.3.5 NAT が失敗すると何が起こるか 6.3.6 複数のマッピング、重複、そして衝突 6.3.7 ローカルに生成されたコネクションの宛先の変更 7. 特殊なプロトコル 8. NAT に関する注意 9. 送信元 NAT とルーティング 10. 同一ネットワーク上での宛先 NAT 11. 謝辞 ______________________________________________________________________ 1. はじめに 読者の皆さん、ようこそ。 あなた方は今まさに NAT(Network Address Translation:ネットワークアド レス変換)の魅力的な(そして時にぞっとするような)世界を探求しようとし ています。この HOWTO は、2.4 系以降の Linux カーネルに関する的確な手引 書となるでしょう。 Linux 2.4 において、`netfilter' という名称の、パケットを料理する基盤が 導入されました。これの上部のレイヤーで NAT 機能が提供され、以前のバー ジョンのカーネルでの NAT も完全に再実装されました。 (C) 2000 Paul `Rusty' Russell. Licensed under the GNU GPL. 2. 公式ウェブサイトやメーリングリストはどこにありますか? 三つの公式サイトがあります: o Filewatcher に感謝。 o Samba チームと SGI に感謝。 o Harald Welte に感謝。 経由でラウ ンドロビン DNS を利用して、上に挙げたサイトのすべてにアクセスできま す。 公式な netfilter のメーリングリストに関しては、 netfilter List を参照ください。 2.1. ネットワークアドレス変換とは何ですか? 通常、ネットワーク上のパケットは、送信元(例:家にあるコンピュータ)か ら宛先(例:www.gnumonks.org)まで、たくさんのいろいろなリンク(オース トラリアの僕のいるところからだと 19 個くらい)を通って届きます。こうし たリンクは、パケットの中身を変えたりはしません。ただ先へ送信するだけで す。 これらのリンクのどれかが NAT を行うとすると、パケットが通過するたび に、それの送信元か宛先を書きかえることになります。お分かりでしょうが、 それはシステムが本来行うのに望ましい動作ではなく、従って NAT は常にか なりの厄介者なのです。一般に NAT を行うリンクは、パケットをどのように 料理したのかを覚えているので、反対方向からリプライのパケットが返ってき たときには、そのパケットに行きと反対の操作を行い、それで全てが上手くい くわけです。 2.2. どうして NAT が必要なのですか? 完全な世界だったら必要ないでしょう。必要な主たる根拠としては: インターネットへのモデム接続 大抵の ISP は、ダイヤルアップ時に単一の IP アドレスを付与しま す。お好みの送信元アドレスをつけてパケットを送出することも可能で すが、 ISP から付与された IP アドレスを送信元アドレスとするパ ケットに対してしかリプライは届きません。もし複数のマシンを(ホー ムネットワークなどで)一個のリンクを通してインターネットに接続し たいのでしたら、 NAT が必要になります。 これが今日 NAT の利用法として最も一般的なもので、Linux 界では 「IP マスカレード」として知られています。これは最初に送出される パケットの送信元アドレスを変換するものなので、僕はこれを SNAT と 呼んでいます。 複数のサーバ あなたが管理しているネットワーク宛てのパケットについて、その行き 先を変更したいことがあります。これは大抵(上記の通り)一個しか IP アドレスを持ってないからで、それでもその「本当の」IP アドレス を持つ NAT ボックスの背後にある端末にまで入れるようにしたいので す。入ってくるパケットの宛先を書き換えれば、これを実現することが できます。この種の NAT は、Linux の以前のバージョンではポート フォワーディングと呼ばれていました。 これの一般的なバリエーションとして負荷分散があり、これはいくつか のマシン群に対してマッピングを施し、パケットをそれらのマシンに振 り分けます。もしあなたがこれをかなりの規模で行っているなら、以下 のページを見る必要があるかもしれません。 Linux Virtual Server 透過プロクシ Linux ボックスを通過するパケットが、その Linux ボックス自身に向 けたパケットであるかのように見せかけたいときがあります。これは透 過プロクシを構築することで実現されます −プロクシは、内部ネット ワークと外界の間に立つプログラムで、分けられた二つのネットワーク を繋いで通信できるようにします。透過と呼ばれるのは、内部ネットワ ークはプロクシと通信していることにさえ気付かないからです。もちろ ん、プロクシがちゃんと動作していれば、の話ですが。 Squid はこのように動作するように設定可能で、Linux の以前のバー ジョンではリダイレクションとか透過プロクシとか呼ばれています。 3. NAT の二つのタイプ 僕は NAT を二つのタイプに分けています −送信元 (Source) NAT(SNAT)と 宛先 (Destination) NAT(DNAT)です。 送信元 NAT とは、最初のパケットの送信元アドレスを変換するもので、つま りはコネクションの送信元を書き換えるのです。送信元 NAT は常にルーティ ングの後、パケットが回線にのる直前に行われます。 IP マスカレード は、SNAT を特化させたものです。 宛先 NAT とは、最初のパケットの宛先 IP アドレスを変換するもので、つま りはコネクションの行き先を書き換えるのです。宛先 NAT は常にルーティン グの前、パケットを回線から取り出したときに行われます。ポートフォワー ディング、負荷分散、そして透過プロクシは、全て DNAT に含まれます。 4. 2.0、2.2系カーネルからの手っ取り早い移行 2.0 系(ipfwadm)から 2.2 系(ipchains)への移行の後遺症を未だ抱えてい る方には申し訳ありませんが、良いニュースと悪いニュースがあります。 まず第一に、これまで通り ipchains と ipfwadm をそのまま使えます。そう するには、最新の netfilter ディストリビューションの中の、ipchains.o も しくは ipfwadm.o カーネルモジュールを組み込む必要があります。これら二 つのモジュールは(知っての通り)互いに排他的なので、他のいかなる netfilter モジュールとも一緒に使うべきではありません。 一旦モジュールが組み込まれれば、これまで通り ipchains や ipfwadm を利 用できますが、以下の相違点があります: o ipchains -M -S や ipfwadm -M -s でマスカレードのタイムアウトを設定 しても意味がありません。というのも、これらのタイムアウト時間は新し い NAT の内部で用いられているタイムアウトより長いので、これらのタイ ムアウト時間は適用されることがありません。 o 冗長なマスカレードリストにおける、init_seq, delta, そして previous_delta フィールドが常に 0。 o `-Z -L' で、カウンタのゼロ化とリスト表示を同時に行うことはできませ ん −カウンタが 0 にならないからです。 o 下位互換性レイヤは、多数のコネクションにあまりうまく追従できませ ん。あなたの会社のゲートウェイには、それを利用しないでください! ハッカーの人達は以下のことにも注意してください: o 現在は、IP マスカレードをしていても、61000-65095 番ポートを bind 可 能です。以前の IP マスカレードは、この範囲のポートを占有することは 正当と考えて作られていたので、他のプログラムが使うことはできません でした。 o (ドキュメント化されてなかった)`getsockname' をハックして透過プロ クシに用い、コネクションの本当の宛先がどこであるか知るということは もうできなくなりました。 o (ドキュメント化されてなかった)未知のアドレスへの bind のハッキン グもできません。この手法は透過プロクシの錯覚を完璧にするのに用いら れました。 4.1. 僕は IP マスカレードを使いたいだけなんです! 助けて! これこそ大部分の人が求めるものでしょう。もし PPP ダイヤルアップで動的 に IP アドレスを割り当てられているのでしたら(分からないとしても、あな たのはそうなっています)、内部ネットワークからの全てのパケットが、 PPP ダイヤルアップボックスからのパケットであるかのようにしたいのです。 # Load the NAT module (this pulls in all the others). modprobe iptable_nat # In the NAT table (-t nat), Append a rule (-A) after routing # (POSTROUTING) for all packets going out ppp0 (-o ppp0) which says to # MASQUERADE the connection (-j MASQUERADE). iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE # Turn on IP forwarding echo 1 > /proc/sys/net/ipv4/ip_forward ここでは全くパケットをフィルタリングしてないことに注意してください。パ ケットフィルタリングに関しては、Packet Filtering HOWTO の中の、 「Mixing NAT and Packet Filtering(NAT とパケットフィルタリングの混 合)」を参照してください。 4.2. ipmasqadm はどうしたの? これはずっと範囲の狭いユーザベースのためのものなので、他の機能と同じほ どには下位互換性を気にかけていませんでした。ポートフォワーディングをや るなら、`iptables -t nat' でだってできます。ですから例えば Linux カー ネル 2.2 系でやってきた: # Linux 2.2 # Forward TCP packets going to port 8080 on 1.2.3.4 to 192.168.1.1's port 80 ipmasqadm portfw -a -P tcp -L 1.2.3.4 8080 -R 192.168.1.1 80 の代わりに今なら: # Linux 2.4 # Append a rule before routing (-A PREROUTING) to the NAT table (-t nat) that # TCP packets (-p tcp) going to 1.2.3.4 (-d 1.2.3.4) port 8080 (--dport 8080) # have their destination mapped (-j DNAT) to 192.168.1.1, port 80 # (--to 192.168.1.1:80). iptables -A PREROUTING -t nat -p tcp -d 1.2.3.4 --dport 8080 \ -j DNAT --to 192.168.1.1:80 5. 何に NAT を行うかを制御する NAT を行うには、どのコネクションに変換をかけ、どのように変換を行うかに ついてカーネルに指示する NAT ルールをつくる必要があります。この行うた め、とても融通が利く iptables ツールを利用し、`-t nat' オプションを指 定することで、NAT テーブルを変更するよう指示します。 NAT ルールのテーブルは、`chains' と呼ばれる三種類のリストからなりま す。いずれのルールについても、どれかが適合するまで順に調べられます。二 種類の chain には、PREROUTING(パケットを受信するたびに、宛先 NAT を行 うのに利用)、そして POSTROUTING(パケットを送信するたびに、送信元 NAT を行うのに利用)があります。三番目のリスト(OUTPUT)はここでは無視されま す。 僕にいくらかでもアーティスティックな才能があったら、下図は三種類の chain を説明するものになるんですがね: _____ _____ / \ / \ PREROUTING -->[Routing ]----------------->POSTROUTING-----> \D-NAT/ [Decision] \S-NAT/ | ^ | | | | | | | | | | | | --------> Local Process ------ 上図のどのポイントにおいても、パケットが通過すると、関連するコネクショ ンを調べることになります。もしそれが新しいコネクションならば、それにど ういう処理を行うか知るために、NAT テーブルの中の関連するチェインを調べ ることになります。そこから得られる答えが、当該コネクション上の以後全て のパケットに適用されます。 5.1. iptables を利用した単純な選択 iptables は、以下に列挙するたくさんの標準的なオプションを利用しま す。iptables が別の利用可能なオプションと区別可能であるうちは、二重 ダッシュ '--' で始まるオプションにはすべて略語指定が使えます。もしあな たのマシンのカーネルがモジュールとして iptables をサポートしているな ら、まず `insmod ip_tables' で ip_tables.o モジュールをロードする必要 があります。 ここで最も重要なオプションは、テーブル選択オプションである `-t' です。 あらゆる NAT の動作に関して、NAT テーブルに `-t nat' を使うことになる でしょう。二番目に重要なオプションは、チェインの最後に新たなルールを追 加する `-A' オプション(例:`-A POSTROUTING')か、チェインの最初にルー ルを挿入する `-I'オプション(例:`-I PREROUTING')です。 NAT を行いたいパケットの送信元(`-s' か `--source')や宛先(`-d' か `--destination')も指定可能です。これらのオプションには、単一の IP ア ドレス(例:192.168.1.1)、名前(例:www.gnumonks.org)、もしくはネッ トワークアドレス(例:192.168.1.0/24 や 192.168.1.0/255.255.255.0)が 後に続きます。 適合する受信インタフェース(`-i' か `--in-interface')か送信インタフェ ース(`-o' か `--out-interface')を指定することも可能ですが、指定可能 かどうかは、ルールを加えようとするチェインに依存します ―PREROUTING で は受信インタフェースのみ選択可能ですし、POSTROUTING では送信インタフェ ースのみ選択可能です。もしこれを間違うと、iptables はエラーを出しま す。 5.2. どのパケットを料理するか選択する賢いポイント 送信元アドレスや宛先アドレスを指定可能であると前に書きました。送信元ア ドレスオプションを省略した場合、あらゆる送信元アドレスについて適用され ます。宛先アドレスオプションを省略した場合、あらゆる宛先アドレスについ て適用されます。 TCP や UDP などの特定のプロトコルは、`-p' か `--protocol' で指定可能 で、そのプロトコルのパケットのみに対してルールが適用されます。こうする 主な理由は、TCP や UDP といったプロトコルを指定することで、そのプロト コルに対しオプションを追加できることにあります −具体的には、 `--source-port' や `--destination-port' オプション(`--sport' や `--dport' と省略可能)です。 これらのオプションにより、特定の送信元、宛先ポート番号を持ったパケット のみをルールに適合させることが可能になります。これはウェブリクエスト (TCP ポート番号80番や8080番)をリダイレクトして、他のパケットを無視す るのに使えます。 これらのオプションは、`-p' オプション(そのプロトコルに関する共有ライ ブラリ拡張をロードする副作用がある)の後に続かなくてはなりません。ポー ト番号か、 /etc/services ファイルに記述された名前を使用可能です。 パケットに選択できるあらゆる性質が、マニュアル(man iptables)にいやに なるほど詳細に記述されています。 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 6.1.1. 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 6.2.1. リダイレクション リダイレクションと呼ばれる宛先 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 にはいくつかあり ます。ここでは好奇心の強い人のためにドキュメント化しておきます。 6.3.1. ある範囲の複数のアドレスからの選択 ある範囲の IP アドレスが与えられ、使用する IP アドレスを、そのマシンが 通信したうち最も最近利用された IP アドレスをもとに選択します。これによ り原始的な負荷調整が行えます。 6.3.2. NAT 不使用マッピングの生成 全く NAT を用いないコネクションを張らせる指定として `-j ACCEPT' があり ます。 6.3.3. 標準的な NAT の動作 デフォルトでは、ユーザによって与えられたルールの制約内で、コネクション の変更を出来る限り小さくするべきです。つまり、その必要がなければ、ポー ト番号を再マッピングしてはならないということです。 6.3.4. 暗黙の送信元ポートマッピング たとえあるコネクションに 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 番に変えるので、二つは衝突しません。 この暗黙の送信元マッピングに関して、ポートは三つのクラスに分けられま す: o 512番以下のポート o 512〜1023番のポート o 1024番以上のポート 元のポートと異なるクラスのポートに暗黙のうちにマッピングされることは決 してありません。 6.3.5. NAT が失敗すると何が起こるか ユーザが要求するコネクションを一意にマップすることができない場合、その 接続要求は廃棄されます。また、パケットが正しく構成されていなかったり、 NAT ボックスのメモリが不足しているなどの理由で、どのコネクションの一部 とも分類できなかったパケットも同様に破棄されます。 6.3.6. 複数のマッピング、重複、そして衝突 様々なアドレスを属性にしているパケットに対して、ある一つのアドレスを マッピングする 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 6.3.7. ローカルに生成されたコネクションの宛先の変更 NAT のコードは、OUTPUT チェインの中に DNAT ルールを挿入することを許可 しますが、カーネル 2.4 では完全にはサポートされていません (可能ではあ るのですが、新しい設定オプション、ある程度のテスト、そしてかなりのコー ディングが必要になります。それは誰かが Rusty にそうしたものを書くと請 け負ってくれない場合の話ですが、僕としては、すぐにそうなるとは期待して いません)。 現在ある制限は、宛先をローカルマシンにしか変更できないことで (例:`j DNAT --to 127.0.0.1')、他のどのマシンにも変更できず、そうでないとリプ ライが正しく転送されないのです。 7. 特殊なプロトコル NAT には適さないプロトコルも存在します。こうしたプロトコルについては、 二つの拡張がなされなくてはなりません −そのプロトコルのコネクションの 追跡に関する拡張と、NAT そのものの拡張です。 netfilter ディストリビューションの中には、現在 FTP 用のモジュール −ip_conntrack_ftp.o と ip_nat_ftp.o があります。これらのモジュールを カーネルに組み込めば(さもなくばモジュールではなくカーネル自体に組み込 めば)、 FTP コネクションに対してどの種類の NAT も使う事ができます。も しモジュールを組み込まなければ、パッシブモードでしか FTP を利用できま せんし、単純な送信元 NAT 以外に何かしようとしても、確実に動作してくれ ないかもしれません。 8. NAT に関する注意 一本のコネクション上で NAT を行う場合、両方向(ネットワークの中へ/ ネットワークの外へ)の全てのパケットが、NAT ボックスを通過しなければな らず、そうでないと確実には動作しません。特に、コネクション追跡を行うコ ードが断片化されたパケットの再構成も行っているため、コネクション追跡が 不確実になるだけではなく、断片化されたパケットが全て留まってしまい再構 成されず、パケットが全く通らなくなってしまうかもしれません。 9. 送信元 NAT とルーティング SNAT を行う場合、SNAT されたパケットの宛先になるどのマシンも、そのリプ ライを NAT ボックスにちゃんと送り返すようにしたいはずです。例えば、特 定の送信パケットに対して、送信元アドレスを 1.2.3.4 にマッピングする設 定を行う場合は、NAT ボックスの外側にあるルータが、リプライ・パケット (宛先が 1.2.3.4)を、この NAT ボックスに送り返すようにしなくてはなり ません。これは以下のような方法で実現されます: 1. (ルーティングなど諸々が既に稼動している)NAT ボックス自身のアドレ スに SNAT マッピングしているなら、あなたは何もする必要はありませ ん。 2. ローカル LAN 上で利用されていないアドレスに SNAT マッピングするなら (例えば、1.2.3.0/24 ネットワーク上で、空き IP アドレスである 1.2.3.99 にマッピングする)、NAT ボックスは、自分自身のアドレスに対 する ARP リクエストに加え、そのマッピングしたアドレスに対する ARP リクエストにもレスポンスを返す必要が出てきます。これを行うには、以 下の例のように IP alias を作成するのが最も簡単な方法です。 # ip address add 1.2.3.99 dev eth0 3. 全く異なるアドレスに SNAT マッピングするなら、SNAT されたパケットを 受信するマシンが、パケットを NAT ボックスにルーティングをすることに なります。これは、NAT ボックスがデフォルト・ゲートウェイに設定され ていればそのままでうまくいきますが、そうでなければ(ルーティング・ プロトコルを動かしている場合)経路を広告するか、さもなくば関連する マシン毎に経路を手動で追加してやる必要があります。 10. 同一ネットワーク上での宛先 NAT 同一ネットワーク内の通信でポートフォワーディングする場合、出て行くパ ケットと戻ってくるパケットの両方がちゃんと NAT ボックスを通過する (よってそれらパケットは内容に変更が加えられる)ようにする必要がありま す。NAT のコードは現在(2.4.0-test6 以降)、 NAT されたパケットが入っ てきたのと同じインタフェースに出て行く際に送信される ICMP リダイレクト をブロックしますが、受信するサーバは、(リプライを認識できない)クライ アントに直接リプライしようとし続けます。 その典型的な例は、内部にある端末があなたのところのネットワークで「外部 に公開している」ウェブ・サーバーにアクセスしようとする場合で、実際には 以下のような設定により、パブリック・アドレス(1.2.3.4)から内部のマシ ン(192.168.1.1)に DNAT されてしまいます。 # iptables -t nat -A PREROUTING -d 1.2.3.4 \ -p tcp --dport 80 -j DNAT --to 192.168.1.1 やり方の一つとして、公開用ウェブ・サイトの本当の(内部での) IP アドレ スを知っている内部用 DNS サーバを動かし、それ以外の名前解決要求は全て 外部用 DNS サーバに転送するようにする方法があります。つまり、ウェブ・ サーバのログを取ってみれば、内部にある端末の IP アドレスが正しく記録さ れているのが分かるでしょう(訳注:内部にある端末からウェブ・サーバへの パケットが、 IP アドレス変換されることなく、NAT ボックスを経由せずに、 直接サーバへ届くことをいっている)。 別のやり方としては、そうしたコネクションに関しては送信元 IP アドレスも NAT ボックス自身の IP アドレスにマップするように設定して、サーバをだま して NAT ボックスにリプライを返させるようにする方法があります。この例 では、以下のように設定することになります(NAT ボックスの内側の IP アド レスを、192.168.1.250 と仮定します): # iptables -t nat -A POSTROUTING -d 192.168.1.1 -s 192.168.1.0/24 \ -p tcp --dport 80 -j SNAT --to 192.168.1.250 PREROUTING ルールが最初に実行されるので、上記ルールが実行される時には 既に、パケットの宛先は内側にあるウェブ・サーバに向けられています。どの パケットが内側から送出されているかは、送信元 IP アドレスにより識別可能 です。 11. 謝辞 僕が netfilter に取り組んでいる間、netfilter のアイデアを信用してくれ て僕をサポートしてくれた、WatchGuard 社と David Bonn にまず感謝しま す。 そして NAT の醜さについて知るたびに僕がわめき散らすのに我慢してくれた みんな、特に僕の日記の読者に感謝します。 Rusty. 訳者謝辞 本日本語訳について、以下の方々が誤訳・誤記の指摘をして下さいました。心 から感謝します。 o office さん(office@office.ac) o Shiro Kawai さん(shiro@lava.net) o 克さん(YRA05647@nifty.ne.jp) o 武井伸光さん(takei@webmasters.gr.jp) o 山森浩幸さん(h-yamamo@db3.so-net.ne.jp) o 水原文さん(mizuhara@acm.org)