本連載ではLinuxディストリビューションごとの癖に左右されにくい、「シェルスクリプトを使用する方法」を採用しました。設定の適用は、以下のサイクルで行います。シェルスクリプトを使用するたびに、iptablesをリセットするのを忘れないようにしましょう。
また、シェルスクリプトの実行にはコンソールを使用しましょう。ネットワークを介したリモート作業(例えばssh接続など)では、設定に失敗した場合、作業が一切行えなくなる危険性があるためです。
・受信パケットは基本的にすべて破棄(1)
・送信パケットは基本的にすべて破棄(2)
・ループバックアドレスに関してはすべて許可(3)
・メンテナンスホストからのping、メンテナンスホストへのpingを許可(4)
・メンテナンスホストからのssh(TCP 22)を許可(5)
・サーバからメンテナンスホストへのsshは許可しない(6)
サーバに接続する端末をメンテナンスホストとして固定して、そこからのssh接続のみを許可するようにします。ssh以外に、サーバの死活を監視する運用上の目的でpingを使用する可能性があるため、併せて許可します。
3、4行目でメンテナンスホスト($trusthost)とサーバ($myhost)のIPアドレスを指定します。これらの値は何度も使用するため、シェルスクリプトの利点を生かしてパラメータとして埋め込みます。この2行は皆さんの環境に合わせて、適宜書き換えてください。
9〜11行目で既存のiptablesの設定をリセットしています。
15行目からようやく設定らしくなります。iptablesの基本は、いったんネットワークをふさいだ後、用途に応じて穴を開けるようにルールを追加していくことです。まず、すべての送受信パケットを破棄(DROP)します。ここでは、次の3つのタイミングでパケットを破棄します。
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.