連載
» 2005年03月18日 00時00分 公開

習うより慣れろ! iptablesテンプレート集(1):ステートフルパケットフィルタを使ったサービスの公開 (2/6)

[鶴長鎮一,@IT]

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

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

・外部からの接続パケットは基本的にすべて破棄
・内部からの接続パケットは基本的にすべて破棄
・ループバックアドレスに関してはすべて許可
・メンテナンスホストからのping、メンテナンスホストへのpingを許可
・メンテナンスホストからのssh(TCP 22)を許可
・サーバからメンテナンスホストへのsshは許可しない

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

 テンプレート1の内容を説明します。適宜、以下のリンクでリストを表示させるかテンプレートをダウンロードしてください。

 

テンプレート1の解説

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

 5行目で不特定クライアントを指定します。これ以外にも不特定クライアントを表す方法はありますが、本連載ではこの表記を用います。

 10、11行目は、既存のiptablesの設定をリセットしています。

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

  • 送信先が受信したホスト自身であるパケット(INPUTチェイン)
  • ホスト自身で生成されたパケット(OUTPUTチェイン)
  • 受信したパケットの送信先が別のホストであるパケット(FORWARDチェイン)
図 INPUT、OUTPUT、FORWARDチェイン 図 INPUT、OUTPUT、FORWARDチェイン

 「チェイン」という言葉に戸惑うかもしれません。これは、「フィルタルールを集めてモジュール化したもの」と理解しておけばいいでしょう。チェインを用いることで、頻繁に使用される細かいルールをいちいち定義する必要がなくなります。

 15行目の「-P INPUT」は、INPUTチェインで定義されたパケットの破棄(DROP)を指定しています。同様に、16行目の「-P OUTPUT」でOUTPUTチェイン、17行目の「-P FORWARD」でFORWARDチェインの破棄を設定します。

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

 26、27行目は、メンテナンスホストからサーバへのpingを許可するルールの追加です。pingは、「request」(26行目)とそれに答える「reply」(27行目)が対で必要なことを忘れないようにしてください。

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

 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」で閾値を設け、閾値の範囲内で検出された不正パケットのログを出力します。limitのデフォルトは、同一パターンの不正パケットに対し、1時間に最大3回のログ出力、連続した場合には5回の出力を行います。

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

 44、45行目で、INPUTおよびOUTPUTチェインに対し、このLOGGINGが行われるように設定します。

フィルタの適用と確認

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

# sh template1.sh

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

# 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
Mar  4 20:34:12 localhost kernel: DROP:IN= OUT=eth0 SRC=192.168.XX.XX
 DST=XX.XX.XX.XX LEN=84 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=ICMP
 TYPE=8 CODE=0 ID=11786 SEQ=1
Mar  7 02:13:54 localhost kernel: DROP:IN=eth0 OUT= MAC=:XX:XX:XX:XX:
XX:XX:XX:XX:XX:XX:XX:XX:XX:XX SRC=192.168.XX.XX DST=192.168.XX.XX 
LEN=52 TOS=0x00 PREC=0x00 TTL=64 ID=13425 DF PROTO=TCP SPT=2825 DPT=22
 WINDOW=65535 RES=0x00 SYN URGP=0
(以下略)
注:「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のメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。