スタティックなパケットフィルタリングiptablesテンプレート集 改訂版(1)(3/4 ページ)

» 2009年12月01日 00時00分 公開
[鶴長鎮一@IT]

テンプレートの使い方

 本連載ではLinuxディストリビューションごとの癖に左右されにくい、「シェルスクリプトを使用する方法」を採用しました。設定の適用は、以下のサイクルで行います。シェルスクリプトを使用するたびに、iptablesをリセットするのを忘れないようにしましょう。

設定適用のサイクル 設定適用のサイクル

 また、シェルスクリプトの実行にはコンソールを使用しましょう。ネットワークを介したリモート作業(例えばssh接続など)では、設定に失敗した場合、作業が一切行えなくなる危険性があるためです。

テンプレート1
特定ホストからのsshのみを許可(送信元IPアドレスで制限)

受信パケットは基本的にすべて破棄(1)
送信パケットは基本的にすべて破棄(2)
ループバックアドレスに関してはすべて許可(3)
メンテナンスホストからのping、メンテナンスホストへのpingを許可(4)
メンテナンスホストからのssh(TCP 22)を許可(5)
サーバからメンテナンスホストへのsshは許可しない(6)

 サーバに接続する端末をメンテナンスホストとして固定して、そこからのssh接続のみを許可するようにします。ssh以外に、サーバの死活を監視する運用上の目的でpingを使用する可能性があるため、併せて許可します。

テンプレート1の解説

 3、4行目でメンテナンスホスト($trusthost)とサーバ($myhost)のIPアドレスを指定します。これらの値は何度も使用するため、シェルスクリプトの利点を生かしてパラメータとして埋め込みます。この2行は皆さんの環境に合わせて、適宜書き換えてください。

 9〜11行目で既存のiptablesの設定をリセットしています。

 15行目からようやく設定らしくなります。iptablesの基本は、いったんネットワークをふさいだ後、用途に応じて穴を開けるようにルールを追加していくことです。まず、すべての送受信パケットを破棄(DROP)します。ここでは、次の3つのタイミングでパケットを破棄します。

  • パケットが入ってくるタイミング(INPUTチェイン)
  • パケットが出て行くタイミング(OUTPUTチェイン)
  • パケットが転送されるタイミング(FORWARDチェイン)
図3 パケット送受信とINPUT/OUTPUT/FORWARDチェインが処理されるタイミング 図3 パケット送受信とINPUT/OUTPUT/FORWARDチェインが処理されるタイミング

 15行目の「-P INPUT」は、INPUTチェインで受信パケットの破棄(DROP)を実行しています。同様に、16行目の「-P OUTPUT」で送信パケットを破棄し、17行目の「-P FORWARD」で転送パケットの破棄を実行します。

 21、22行目で、ループバックインターフェイスを経由するすべての送受信パケットの通過を許可します。「-i」で受信側インターフェイス、「-o」で送信側インターフェイスを指定します。これでサーバからサーバ自身へのローカル接続をすべて許可することができます。

 26、27行目は、メンテナンスホストからサーバへのpingを許可するルールの追加です。pingでは、「request」(26行目)とそれに応える「reply」(27行目)がセットで必要になります。

 31、32行目は、サーバからメンテナンスホストへのpingを許可するルールです。26、27行目と比べると、送信元と送信先が入れ替わっています。送信元(ソース)ホストを指定するには「-s ホストまたはネットワーク」とし、送信先(ディスティネーション)ホストを指定するには「-d ホストまたはネットワーク」とします。

 36、37行目が肝心のsshの設定です。今回は、単に送信元IPアドレスで制限します。

36  iptables -A INPUT -p tcp -s $trusthost -d $myhost --dport 22 -j ACCEPT
37  iptables -A OUTPUT -p tcp -s $myhost --sport 22 -d $trusthost -j ACCEPT
-p tcp			 	プロトコルがTCP  
-s $trusthost	 	送信元IPアドレスが$trusthost  
-d $myhost		 	送信先IPアドレスが$myhost  
--dport 22		 	送信先サービスポートが22  
--sport 22		 	送信元サービスポートが22   	
-j ACCEPT		 	ACCEPT(許可)する

 41行目以降で運用監視のための設定を行います。37行目までの設定のどれにも合致しなかったパケットに関しては、不正なパケットと判断し、ログファイルに記録した後、破棄します。そのために41行目のような「LOGGINGチェイン」を独自に定義します。

 42行目では、「--log-level」でログレベルをwarningに設定し、「--log-prefix」でログ出力時に「DROP:」とプレフィックスを付けるようにしています。このままでは無効な全パケットを記録してしまい、絶え間なく攻撃を受けたときなど、ログの出力だけでサーバの負担になる可能性があります。そこで、「-m limit」で制限します。立て続けに攻撃を受けたとしても、最初に5パケット分のログを5行出力した後は、20分置きにログを1行ずつ出力するようになります。

 ログ出力の後にパケットを破棄(DROP)するよう、43行目で無効なパケットの破棄を実行します。

フィルタの適用と確認

 シェルスクリプトの準備ができたら、既存設定のリセットを含めてフィルタを適用します。

# sh template01.sh

 設定内容をチェインごとに表示することもできます。シェルスクリプトで設定したとおりになっているかどうかを確認します。

# /sbin/iptables -nL
Chain INPUT (policy DROP)
target     prot opt source               destination 
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0 
ACCEPT     icmp --  192.168.10.100       192.168.20.200      icmp type 8 
ACCEPT     icmp --  192.168.10.100       192.168.20.200      icmp type 0 
ACCEPT     tcp  --  192.168.10.100       192.168.20.200      tcp dpt:22 
LOGGING    all  --  0.0.0.0/0            0.0.0.0/0 Chain FORWARD (policy DROP)
target     prot opt source               destination Chain OUTPUT (policy DROP)
target     prot opt source               destination 
ACCEPT     all  --  0.0.0.0/0            0.0.0.0/0 
ACCEPT     icmp --  192.168.20.200       192.168.10.100      icmp type 0 
ACCEPT     icmp --  192.168.20.200       192.168.10.100      icmp type 8 
ACCEPT     tcp  --  192.168.20.200       192.168.10.100      tcp spt:22 
LOGGING    all  --  0.0.0.0/0            0.0.0.0/0 Chain LOGGING (2 references)
target     prot opt source               destination 
LOG        all  --  0.0.0.0/0            0.0.0.0/0           limit: avg 3/hour burst 5 LOG flags 0 level 4 prefix `DROP:' 
DROP       all  --  0.0.0.0/0            0.0.0.0/0

 ログは/var/log/messagesに出力されます。dmesgコマンドで確認することもできます。

# tail /var/log/messages | grep DROP
Oct  6 19:47:01 localhost kernel: DROP:IN=eth0 OUT= MAC=○○ SRC=○○ DST=○○ LEN= ...省略
注:「DROP」はテンプレート中で指定したプレフィックス。

改造のヒント:ネットワーク単位の指定方法

 テンプレート1では、メンテナンスホストを1台のクライアントに限定しています。これを、192.168.10.0〜192.168.10.255のようにネットワーク単位で指定することも可能です。その場合は、3行目を次のように変更します。

3   trusthost='192.168.10.0/24'

 このほか、ホストの指定にホスト名を使うこともできますが、ホスト名解決のためにDNSを利用できるようにiptablesの設定を修正する必要があります。また、ホスト名偽装の危険性やサーバの負担も生じるため、IPアドレスを使用する方が望ましいでしょう。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

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

メールマガジン登録

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