Linuxで作るファイアウォール[NAT設定編]
第4回 Linuxで作るファイアウォール[NAT設定編]今回からiptablesの具体的な設定を解説する。iptablesの使い方はやや複雑だが、理屈を理解すれば難しいものではない。前半で紹介する知識を利用して、まずはNATを実現しよう。
前回はiptablesを使用するためのカーネル再構築とルールの設計を行いました。これを基にファイアウォールを構築していきます。今回はiptablesの概要とNATの設定を行いましょう。
なお、前回紹介したルールはあくまでも参考なので、実際には自分の環境に合わせて作成してください。ただし、ルールの作成方法は基本的に変わらないので参考になると思います。
iptablesの仕組みと機能
これから本格的にファイアウォールを構築していくわけですが、その手段であるiptablesを理解していなければ目的を達することはできません。少々回り道になりますが、iptablesについて学んでおきましょう。
■iptablesを理解するための概念
iptablesを使うには、テーブルやチェインなどの概念を理解しておく必要があります。
iptablesには、3つの「テーブル」が用意されており、それぞれ「filter」「nat」「mangle」と呼びます。この中のfilterテーブルがデフォルトテーブルで、テーブルを指定せずにiptablesコマンドを使用した場合はこれが使われます。また、テーブルによって使用できる「チェイン」が異なります。
filter | INPUT、FORWARD、OUTPUT |
nat | PREROUTING、OUTPUT、POSTROUTING |
mangle | PREROUTING、OUTPUT |
表1 各テーブルの組み込みチェイン |
チェインは、パケットを検査する「ルール」のリストです。各チェインでルールに適合するかを調べ、次のチェインにパケットを渡します。このチェインのルールを変更・追加することでfilterテーブルやnatテーブルの設定が行われ、これによってファイアウォールを構築するわけです。natテーブルで使用するPREROUTING、OUTPUT、POSTROUTINGについては、NATの設定時にあらためて解説します。
INPUT | 入力(受信)パケット |
OUTPUT | 出力(送信)パケット |
FORWARD | フォワードするパケット |
PREROUTING | 受信時を変換するチェイン |
POSTROUTING | 送信時に変換するチェイン |
表2 組み込みチェイン |
コラム:ipchainsとiptables |
カーネル2.4から採用されたiptablesと、従来のipchains(カーネル2.4でもサポートされている)の違いの一部を紹介しましょう。
|
■iptablesコマンドのオプション
iptablesはコマンドにオプションを指定してルールを作成します。基本的な設定方法はipchainsと同じです。まず、ファイアウォールを構築するうえで最低限必要であろうと考えられるオプションについて説明します。より詳細な説明が必要と判断したものについては、その都度解説を加えていきたいと思います。
iptablesの「オプション」は、基本的にチェインの操作を行う際に使用します。表3はその一部です。
-A(--append) | 指定チェインに1つ以上の新しいルールを追加 |
-D(--delete) | 指定チェインから1つ以上のルールを削除 |
-P(--policy) | 指定チェインのポリシーを指定したターゲットに設定 |
-N(--new-chain) | 新しいユーザー定義チェインを作成 |
-X(--delete-chain) | 指定ユーザー定義チェインを削除 |
表3 iptablesのオプション |
チェイン内のルールを指定するのに使うのが「パラメータ」です。同じくパラメータの一部を表4に挙げておきます。
-p(--protocol) プロコトル | ルールで使うプロトコル(tcp、udp、icmp、all)を指定 |
-s(--source) IPアドレス[/mask] | 送信元アドレス。IPアドレスのほかにホスト名などでも指定できる |
-d(--destination) IPアドレス[/mask] | 接続先アドレス。IPアドレスのほかにホスト名などでも指定できる |
-i(--in-interface) デバイス | パケットが入ってくるインターフェイス(eth0、eth1など)を指定 |
-o(--out-interface) デバイス | パケットが出ていくインターフェイスを指定 |
-j(--jump) ターゲット | パケットがマッチしたときのアクション(ターゲット)を指定 |
-t(--table) テーブル | テーブル(filter、nat、mangle)を指定 |
! | -p、-s、-dなどで、条件を反転する。「! 192.168.0.1」とすると、「192.168.0.1以外」という意味になる |
表4 iptablesのパラメータ |
-jパラメータでは、「ターゲット」を指定する必要があります。これは、パケットがマッチした際のアクション(何を行うか)のことです。主なものを表5にまとめておきました。
ACCEPT | パケットの通過を許可 |
DROP | パケットを破棄 |
REJECT | パケットを拒否し、ICMPメッセージを返信 |
REDIRECT | 特定ポートにリダイレクト |
表5 ターゲット(-jパラメータで指定するアクション) |
また、ターゲットには「SNAT」と「DNAT」があります。表では説明しにくいので、以下で書式とともに挙げておきます。
●SNAT
SNAT --to(--to-source) <ipaddr>[-<ipaddr>][:port-port]
パケットの送信元アドレスを変換する。natテーブルとPOSTROUTINGチェインでのみ有効。ポートを指定すると、変換されたアドレスの指定されたポートで接続することになる。IPアドレス、ポート共にレンジ指定が可能。
●DNAT
DNAT --to(--to-destination) <ipaddr>[-<ipaddr>][:port-port]
パケットの送信先アドレスを変換する。natテーブルとPREROUTING、OUTPUTチェイン、これらのチェインから呼び出されるユーザー定義チェインのみで有効。ポートを指定すると、変換されたアドレスの指定されたポートあてに接続することになる。IPアドレス、ポート共にレンジ指定が可能。
一部のパラメータ(-pパラメータなど)では、パラメータ指定によってさらに拡張指定が行える場合があります。これを「マッチングの拡張」と呼びます。以下にその一部を紹介します。
●--sport
--sport(--source-port) [!] [port[:port]]
送信元ポートを指定する。ポートはレンジで範囲指定することも可能。パラメータ設定で「-p tcp」を指定したときに使用。
●--dport
--dport(--destination-port) [!] [port[:port]]
送信先ポートを指定する。ポートはレンジで範囲指定することも可能。パラメータ設定で「-p tcp」を指定したときに使用。
●--icmp-type
--icmp-type [!] typename
typenameにはICMPのタイプ(echo-requestやecho-replyなど)を指定する。パラメータ設定で「-p icmp」を指定したときに使用。
iptablesのオプションやパラメータはこれですべてではありません。適宜manページなどを参照してください。
NATの動作と設定
目的のホストやポートに接続するためには、そのポリシーに適合するルールを作成しなければなりません。今回はNATのルールを作成しましょう。
■デフォルト設定の確認
iptablesの設定を変更する前に、まずはデフォルトのルールを確認してみましょう。以下のように、すべての通信を許可するようになっていると思います。
# iptables -L -t
filter
|
デフォルトの適用ルール |
上記の結果は、何もルールが適用されていない状態を示しています。ちなみに、「-L -t filter」はfilterテーブル、「-L -t nat」はnatテーブルのルールをリストアップするオプションです。
■NATの動作
![]() |
図1 NATの動作 |
外部のホストから各サーバに接続する際、まずファイアウォールの外側のインターフェイス(eth0)に割り当てられた各サーバの仮想IPアドレスに対してアクセスしてきます。ファイアウォールを介して接続を許可するルールが存在しても、そのままのDestinationアドレス(あて先アドレス)では実体のサーバにはアクセスできません。そこで、ファイアウォールでDestinationアドレスを仮想IPアドレスから実IPアドレスに変換する必要があります(図1)。
におけるDestinationアドレスは172.16.0.10です。しかし、Webサーバの実IPアドレスは192.168.0.10であるため、172.16.0.10のままではWebサーバに到達できません。そこで、アドレスの変換を行います。すると、
におけるDestinationアドレスはWebサーバの実IPアドレスである192.168.0.10になります。これを行うのが、これから設定するNATというわけです。
動作が分かったところで、これをiptablesに行わせる方法を説明します。図1と前回の最後で紹介したNATルールを参考にしてiptablesのオプションに置き換え、natテーブルのチェインにルールを追加していきます。
コラム:ポートフォワードの併用 |
各チェインとも、ポートフォワードさせることも可能です。今回は使用しないので簡単な説明にとどめておきますが、次のようなことが考えられます。 「172.16.0.10:80/TCP」への接続要求があったとします。NATのみでは192.168.0.10にDestinationアドレスを変換するだけですが、ポートフォワードを加えると「192.168.0.10:8080/TCP」のように、あて先のポート番号を変更することが可能になるのです。 |
■PREROUTINGチェイン
前述したように、natテーブルは3つのチェインから成ります。ここであらためて詳しく解説します。
![]() |
|
図2 PREROUTINGチェイン:パケット受信時にあて先のアドレスを変換 |
PREROUTINGチェインはDestinationアドレスを変換するもので、基本的に外部から入ってくるパケット用と考えください。内部セグメントにはプライベートアドレスが割り当てられています。グローバルアドレスのままでは当然ながら内部セグメント上のホストへは到達できないので、Destinationアドレスを変換する必要があるのです。
■POSTROUTINGチェイン
![]() |
|
図3 POSTROUTINGチェイン:パケット送信時に送信元のアドレスを変換 |
POSTROUTINGチェインは送信元アドレスを変換するもので、基本的に外部へ出ていくパケット用です。内部ホストに割り当てられているプライベートアドレスのままでは、外部のホストに接続することはできません。PREROUTINGとは逆に、プライベートアドレスをグローバルアドレスに変換する必要があるのです。
■OUTPUTチェイン
![]() |
|
図4 OUTPUTチェイン:ローカルで生成されたパケットのDestinationアドレスを変換 |
OUTPUTチェインは、ローカルで生成されたパケットのDestinationアドレスを変換することができます。
■iptablesの記述方法
各チェインの役割を理解すれば、外部からの接続要求に対してどのような処理が必要であるか分かると思います。Destinationアドレスの変換を行う必要があるのですから、この場合はPREROUTINGチェインにルールを追加しなければなりません。WebサーバあてパケットのDestinationアドレスを172.16.0.10(Webサーバの仮想IPアドレス)から192.168.0.10(Webサーバの実IPアドレス)に変換するには、下記のようなオプション/パラメータを付けます。
# /sbin/iptables -t
nat -A PREROUTING -d 172.16.0.10 -i eth0 -j DNAT --to 192.168.0.10 |
Destinationアドレス変換ルール |
順番に説明すると、
-t nat |
でnatテーブルの使用を指定します。次に、
-A PREROUTING |
でPREROUTINGチェインに以下のルールを追加しています。
-d 172.16.0.10 |
は、
-j DNAT --to 192.168.0.10 |
と対になっています。もうお分かりだと思いますが、「Destinationアドレスが172.16.0.10であった場合は、これを192.168.0.10に変換する」という意味です。
-i eth0 |
はパケットを受け取るインターフェイスがeth0であることを指定しています。
少々くどくなりますが、iptablesの書式に慣れてもらうためにさらに換言してみましょう。eth0で受信したDestinationアドレスが172.16.0.10にマッチした場合(-d 172.16.0.10)は、-jで指定したターゲットを実行する。そのターゲットがDNATで、Destinationアドレスを192.168.0.10に変換するように指定されている。このルールを-A PREROUTINGでPREROUTINGチェインに追加する。1行でこれだけの処理を指定しているというわけです。
接続要求に対しては、それに対する応答パケットを返します。当然、応答のパケットもファイアウォールを通過するわけですが、NATに関しては特に定義する必要はありません。接続してきたパケットの送信元アドレスは変換させていないからです。応答パケットはファイアウォールを通過した後、もともと接続要求のあったアドレス(172.16.0.10)でクライアントに戻ります。
以上、Webサーバの場合を例にiptablesの記述方法を説明しました。ほかのサーバも同じようにルールを追加してください。
■パラメータ「-i」と「-o」の注意
最後に、インターフェイスを指定するパラメータ「-i」と「-o」の使い方を補足しておきます。これらのパラメータの使い方にはちょっとした注意が必要です。
上記の設定では「-i」を付けていますが、見方を変えれば次のようにも考えられます。
eth1のインターフェイスから出ていくIPアドレスを変換する
|
どうでしょうか? こう考えてしまった場合は「-o」を付けてしまうかもしれません。しかしながら、これでは間違いなのです。これは、考え方の違いではなくiptablesの仕様であるとお考えください。PREROUTINGチェインは受信インターフェイスのみ選択可能という制限があります。よって、「-o」を指定しまうとiptablesではエラーとなってしまいます。反対に、POSTROUTINGとOUTPUTは送信インターフェイスにしか指定できないので注意してください。