natテーブルを利用したLinuxルータの作成習うより慣れろ! iptablesテンプレート集(2)(2/6 ページ)

» 2005年05月17日 00時00分 公開
[鶴長鎮一@IT]

テンプレート6
IPマスカレードによるLinuxルータ

テンプレート6の想定環境

サーバとして
・外部からの接続パケットは基本的にすべて破棄
・ただし接続済み通信のパケットは許可
・内部からの接続パケットは基本的にすべて許可
・ループバックアドレスに関してはすべて許可
・メンテナンスホストからのping、メンテナンスホストへのpingを許可
・メンテナンスホストからのssh(TCP 22)を許可
ルータとして
・Linuxサーバを経由して外部へ出ていくパケットのソースアドレスを変換
・内部アドレス→外部アドレス
・内部アドレスやプライベートアドレスが外部に漏れないようにブロック

 市販のブロードバンドルータと同じような働きをするLinuxルータを作ります。Linuxサーバに2枚のNICを組み込み、一方にはプロバイダなどから与えられたグローバルアドレス、もう一方にはプライベートアドレスを設定します(以下、グローバルアドレス側を外部ネット、プライベートアドレス側を内部ネットとします)。

 外部から内部ネットへの接続は一切許可しませんが、内部ネットから外部ネットへの接続に制限は設けません。また、忘れがちなサーバ自身のフィルタ設定は、第1回のテンプレート5からHTTPサービスを削除したものを利用します。

テンプレート6の解説

 3〜7行目で環境に合わせた値を設定します。

$trusthost メンテナンスホスト
$internal_ip 内部ネットワーク
$my_internet_ip Linuxルータの外部ネット側アドレス
$my_internal_ip Linuxルータの内部ネット側アドレス

です。メンテナンスホストが外部ネット側にある場合は、テンプレートの修正が必要になるので注意が必要です。その方法は後述します。

 Linuxをルータとして機能させるには、IPパケットをフォワード(転送)する必要があります。そこで、9行目の処理をLinux起動時に1度だけ実行します。

9 echo 1 > /proc/sys/net/ipv4/ip_forward

 14〜16行目でiptablesの初期化を行います。前回の処理に15行目を追加しています。

15 iptables -t nat -F

 「-t nat」でnatテーブルを指定し、「-F」で初期化を行います。このように、テーブルの指定には「-t」オプションを使用します。

 21〜28行目でデフォルトルールを設定します。基本は破棄(DROP)ですが、テンプレート5同様、内部からの接続(OUTPUT)には制限を設けず(ACCEPT)、Linuxルータ外部(外部/内部ネットを含めた、Linuxルータから見た外部のネットワーク)からの接続(INPUT)はパケットのステートフル性を確認し、「--state ESTABLISHED,RELATED」となっているものに通過許可(ACCEPT)を与えます。

27 iptables -A FORWARD -i eth1 -o eth0 -s $internal_ip -j ACCEPT
28 iptables -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT

 今回は、Linuxルータ自身が処理するパケットだけではなく、フォワードするパケットについてもデフォルトルールを設ける必要があります。今回は内部ネットから外部ネットへの接続つまり「eth1から入ってeth0へ出ていくパケット」は制限なしとし、27行目を追加します。それに合わせて、28行目で「eth0からeth1へ出ていくパケット」もステートフル性を確認できたものを許可するようにします。

 ここからがテンプレート6の要、IPマスカレードの設定です。基本はこの1行です。

55 iptables -t nat -A POSTROUTING -o eth0 -s $internal_ip -j MASQUERADE

-t nat natテーブルを使用
-A POSTROUTING POSTROUTINGチェインを使用し、内部ネットから外部ネットへ出ていくパケットのソースIPを書き換える
-o eth0 パケットが出ていくインターフェイスをeth0と指定
-s $internal_ip ソース側ネットワークアドレスは$internal_ip(192.168.0.0/24)
-j MASQUERADE IPマスカレードを行う

 内部ネット発のパケットが外部ネットでルーティングされるには、出ていくパケットのソースアドレスをプライベートアドレスからLinuxルータの外部ネット側(eth0)のアドレスに書き換える必要があります(SNAT)。そのためにPOSTROUTINGチェインを使用し、同時に「-j MASQUERADE」を指定し、複数のパケットが1つの外部アドレスを共有できるようにIPマスカレードを使用します。この1行でブロードバンドルータの役割のほとんどをこなしています。

 POSTROUTINGはnatテーブルでしか使用できません。また「-j MASQUERADE」もPOSTROUTINGチェインと一緒に用いる必要があります。PREROUTINGチェインに「-j MASQUERADE」を指定した場合、すなわちDNATとIPマスカレードを使用する場合はエラーを出力します。iptablesのテーブル/チェインの概念は、こうしたオプション指定ミスを減少させる働きもあります。

 60〜63行目では、「内部アドレスやプライベートアドレスが外部ネットワークに漏れないようにブロックする」を実施しています。

60 iptables -A OUTPUT -o eth0 -d 10.0.0.0/8 -j DROP
61 iptables -A OUTPUT -o eth0 -d 176.16.0.0/12 -j DROP
62 iptables -A OUTPUT -o eth0 -d 192.168.0.0/16 -j DROP
63 iptables -A OUTPUT -o eth0 -d 127.0.0.0/8 -j DROP

 マナーとしてプライベートアドレスを外部に漏出しないのは当然として、最近ではIPスプーフィングでソースIPにプライベートアドレスを使用するケースもあるため、そうしたパケットと同一視されないようにします。

 68〜72行目までが、テンプレート5と同じく破棄されるパケットのロギングです。FORWARDチェインに対してもロギングを設定しています。

68 iptables -N LOGGING
69 iptables -A LOGGING -j LOG --log-level warning --log-prefix "DROP:" -m limit
70 iptables -A LOGGING -j DROP
71 iptables -A INPUT -j LOGGING
72 iptables -A FORWARD -j LOGGING

 shスクリプトが用意できたら、前回のようにshスクリプトを実行して確認します。

# iptables -nL #filterテーブルの設定確認
# iptables -t nat -nL #natテーブルの設定確認

 市販のブロードバンドルータと同じというには、可用性やセキュリティ面で物足りなさが残ります。これらの機能についてはおいおい紹介していくことにします。

改造のヒント:メンテナンスホストが外部ネット側にある場合

 33〜50行目はテンプレート5と同じですが、環境によっては見直しが必要になります。前述した、「メンテナンスホストが外部ネット側にある場合」のことです。メンテナンスホストからのssh接続を許可している48〜50行目を見てみましょう。

48 iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
49 iptables -A INPUT -p tcp -m state --state NEW,ESTABLISHED,RELATED -s $trusthost -d $my_internal_ip --dport 22 -j ACCEPT
50 iptables -A OUTPUT -p tcp -s $my_internal_ip --sport 22 -d $trusthost -j ACCEPT

 メンテナンスホストのアドレス変数である$trusthostに対して、サーバのインターフェイスIPに使用されているのは内部ネット側のアドレス$my_internal_ipになっています。メンテナンスホストを外部ネットに設ける場合、$trusthostを単に書き換えても内部ネット側のアドレス$my_internal_ipには到達しません。そのような場合は、$my_internal_ipを$my_internet_ipに置き換え、Linuxルータの外部ネット側アドレスを参照するようにします。

48 iptables -A INPUT -p tcp ! --syn -m state --state NEW -j DROP
49 iptables -A INPUT -p tcp -m state --state NEW,ESTABLISHED,RELATED -s $trusthost -d $my_internet_ip --dport 22 -j ACCEPT
50 iptables -A OUTPUT -p tcp -s $my_internet_ip --sport 22 -d $trusthost -j ACCEPT
メンテナンスホストが外部ネット側にある場合

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。