サーバとして
・外部からの接続パケットは基本的にすべて破棄
・ただし接続済み通信のパケットは許可
・内部からの接続パケットは基本的にすべて許可
・ループバックアドレスに関してはすべて許可
・メンテナンスホストからのping、メンテナンスホストへのpingを許可
・メンテナンスホストからのssh(TCP 22)を許可
ルータとして
・Linuxサーバを経由して外部へ出ていくパケットのソースアドレスを変換
・内部アドレス→外部アドレス
・内部アドレスやプライベートアドレスが外部に漏れないようにブロック
市販のブロードバンドルータと同じような働きをするLinuxルータを作ります。Linuxサーバに2枚のNICを組み込み、一方にはプロバイダなどから与えられたグローバルアドレス、もう一方にはプライベートアドレスを設定します(以下、グローバルアドレス側を外部ネット、プライベートアドレス側を内部ネットとします)。
外部から内部ネットへの接続は一切許可しませんが、内部ネットから外部ネットへの接続に制限は設けません。また、忘れがちなサーバ自身のフィルタ設定は、第1回のテンプレート5からHTTPサービスを削除したものを利用します。
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.