Tripwireに続き、ネットワーク型IDSである「Snort」の導入方法を紹介する。Snortを導入することにより、ホスト型IDSでは対応できない攻撃も検出可能になる。
Snortは、以前紹介した(第7回 Linuxで使える侵入検知システム(IDS))ネットワーク型のIDSに分類されるツールです。ネットワーク型IDSは、ネットワーク上を流れる通信の内容を監視し、攻撃を受けているか否かを検出します。ポートスキャンなどは「攻撃」というよりも「攻撃のための事前調査」とした方が表現としては適切かもしれません。ネットワーク型IDSは、このポートスキャンなども検知できます。また、疑わしい通信を検出することで、侵入などの被害を未然に防ぐことが期待できるのです。
一般的に、ネットワーク型IDSは専用機を用意して、ネットワーク上を流れる通信を監視するものです。どこを監視対象とするかによって、設置場所は変わってきます。設置場所が変わることにより、攻撃の検出ルールも変わります。さらに、検出ルールによってログの量も増減しますので、運用面も含めてきちんと考え、設置場所を決定しましょう。
例えば、DMZが存在し、そのDMZ上のサーバに対する攻撃を監視したいのであれば、IDSはDMZ上に設置するべきでしょう。インターネット経由の攻撃を検出したいからといってインターネット側(何らフィルタリングされていないゾーン)に設置すると、大量のログが記録されて重要な情報が埋もれてしまうでしょう。DMZ上のサーバへ到達するにはファイアウォールを通過しなければなりません。つまり、DMZ上であれば流れるパケットのプロトコルやポートを限定できるのです。そうなれば、当然ログの量も変わってきます。
攻撃の傾向分析を行いたいのであれば、何もフィルタリングされていないゾーンに設置することになります。また、イントラネット(内部ネットワーク)上に存在する重要なサーバに対するアクセスを監視したいという場合もあるでしょう。
どのような方針で監視するかによって、IDSの設置場所は変わってきます。設置場所がきちんと決定されていないと、後のルールの設定も難しいものとなるでしょう。
ネットワーク型IDSは、検出方法によって「シグネチャマッチング型」と「異常検出型」に分類できます。今回紹介するSnortは、シグネチャマッチング型のIDSです。シグネチャマッチング型IDSは、あらかじめ用意されたシグネチャ(攻撃方法のパターン)とマッチした場合に異常を検出します。
Snortでは、「ルールセット」と呼ばれるサービスなどに分かれたシグネチャが用意されています。最初はこれを利用するとよいでしょう。このシグネチャは自由にカスタマイズできます。新たなワームなどが発生したときは、ルールセットを自分で作成することで柔軟に対応できます。
Snortをインストールするには、事前にlibpcapがインストールされている必要があります。
libpcap:http://www.tcpdump.org/
Snort:http://www.snort.org/
libpcapはすでにインストールされているものとして、以下にSnortのインストールの流れを挙げておきます。
$ tar -zxvf snort-1.8.6.tar.gz $ cd snort-1.8.6 $ ./configure $ make # make install
次に、Snortの設定を行います。Snortを展開したディレクトリに移動してください。
$ cd ~/snort-1.8.6
このディレクトリに、「snort.conf」や「xxx.rules」というファイルがあります。snort.confはSnortの設定ファイル、xxx.rulesはルールセットです。/etc/snortなどの適当なディレクトリを作成し、設定ファイルやルールセットを移動します。移動したらsnort.confを編集します。
まず、監視対象とするネットワークアドレスを指定します。
var HOME_NET 192.168.0.0/24
パケットの流れの向きに関係なく監視するのであれば「any」と指定しましょう。
var EXTERNAL_NET any
攻撃元と考えられるネットワークアドレスを指定します。通常は「any」でいいでしょう。
var SMTP $HOME_NET
SMTPサーバを指定します。SMTPサーバではなく$HOME_NET(監視対象ネットワークアドレス)を指定しても構いません。
同様に、HTTPサーバ、SQLサーバ、DNSサーバを指定します。以下のように「,」(カンマ)で区切ることで、複数のサーバを指定できます。
var SMTP [192.168.0.1,192.168.0.2] var RULE_SET ./
ルールセットが格納されているパスを指定します。ここではsnort.confと同じディレクトリに格納されているので、カレントディレクトリを指定しています。
設定ファイルの編集が完了したら、Snortを実行してみましょう。Snortを実行する前に、Snortを実行する専用ユーザーを作成します。
# groupadd -g 5000 snort # useradd -u 50001 -g 5000 -d /etc/snort -s /bin/false snort
次に、Snortの代表的なオプションを紹介しておきます。
Snortの起動には以下の3つのモードがあります。
●Sniffer Mode
単純なスニファとして動作すると考えてください。内容はコンソールに出力されます。以下のようにオプションを指定して実行します。
# /usr/local/bin/snort -v
●Packet Logger Mode
検出した内容をログとして保存することができます。これには、ログを保存するディレクトリを指定する必要があります。以下のようにオプションを指定して実行します。
# /usr/local/bin/snort -v -l /var/log/snort
●Network Intrusion Detection Mode
これが、今回の目的であるネットワーク型IDSとして機能させるモードです。ほかの2モードは、単にスニファと同様の機能しか利用していません。このモードでは、ルールに沿った攻撃を検知することが可能になります。次のようにオプションを指定してSnortを起動します。
# /usr/local/bin/snort -D -h 192.168.0.0/24 -c /etc/snort/snort.conf -l /var/log/snort -b -d -u snort -g snort
Snortを起動したら、psコマンドを使って確認してください。起動していないようであれば、/var/log/messagesに何らかのメッセージが出力されているでしょうから確認してください。
Snortの起動に成功したら、実際に攻撃を検知できるかどうかを確認しなければなりません。ポートスキャンを実行してみましょう。検知したログは/var/log/snort/alertファイルに出力されます。tailコマンドを使って、出力内容を見ながらポートスキャンを実行してみます。
[**] [100:1:1] spp_portscan: PORTSCAN DETECTED from 192.168.0.100 (THRESHOLD 4 connections exceeded in 0 seconds) [**] 05/07-20:59:34.027914
これまでは、デフォルトのルールセットでSnortを実行させていました。このままの状態でもネットワーク型IDSとして動作していますが、決して好ましい運用とはいえません。
前述したように、ネットワーク型IDSの検出ルールは設置場所によっても異なります。フィルタリング機能を有したデバイスの内側と外側に設置するのでは、通過するパケットの内容に当然のことながら違いが発生します。
発生することが想定されない通信に関する検出ルールについては、対象外とします。その代わり、通常なら発生しない通信が発生するようであれば、それを検知するような設定も必要になるでしょう。
ネットワーク型IDSの特徴といっても過言ではないものに、「誤検知」があります。誤検知が発生する原因としては、
などが挙げられます。そのほかにも、アプリケーションから通常の動作において送信されるにもかかわらず、検出されてしまうといったこともあります。
誤検知をどれだけ減らせるかによって、その後のネットワーク型IDSの運用が変わってきます。単純に考えれば、ログの量が多ければ多いほど、その解析に労力を割くことになります。あまりに大量のログが発生してしまうと、肝心のログを見落とすといった悲しい事態に陥る危険もあるのです。そこで、可能な限り誤検知を減らすのがネットワーク型IDSの運用における大きなポイントになるのです。Snortを利用してネットワークを監視するのであれば、監視対象となるネットワークを十分に把握しておかなければなりません。これは、使用しているOSやアプリケーション、発生する通信までも把握する必要があるということです。
実際にSnortの検出ルールの定義方法について説明します。xxx.rulesがルールセットと呼ばれるものであることはすでに紹介しました。「telnet.rules」であれば、Telnetサービスに関するシグネチャということです。このシグネチャにマッチすると、ログに保存されるなどの処理が行われます。
まず、Snortの設定ファイルであるsnort.confの内容を確認してください。ファイルの最後の方に、次のような記述があると思います。
include $RULE_PATH/bad-traffic.rules include $RULE_PATH/exploit.rules include $RULE_PATH/scan.rules include $RULE_PATH/finger.rules include $RULE_PATH/ftp.rules (中略) # include $RULE_PATH/icmp-info.rules # include $RULE_PATH/virus.rules # include $RULE_PATH/experimental.rules include $RULE_PATH/local.rules
ここで、利用するルールセットが指定されています。サービス単位で検出ルールとするか否かの設定はここで行うことができます。デフォルトの設定を見ると分かるとおり、検出ルールから外すのであれば、行頭に「#」を付けます。逆に、検出ルールとするのであれば、行頭の「#」を削除すればいいのです。
サービス単位ではなく、シグネチャ単位で設定する場合を説明しましょう。実際にルールセットの中を見てみましょう。ここでは、telnet.rulesを例にして説明します。
telnet.rulesの中に以下のような内容の記述があります。
alert tcp $HOME_NET 23 -> $EXTERNAL_NET any (msg:"TELNET login incorrect"; content:"Login incorrect"; flags: A+; reference:arachnids,127; classtype:bad-unknown; sid:718; rev:3;)
これは、Telnetでのログインに失敗すると検出されるシグネチャです。特定のシグネチャを検出ルールから対象外とするには、行頭に「#」を付けます。
まずは、実際にSnortを運用してみましょう。何が誤検知で、何が攻撃に関する内容かは実際にログを確認してみないと分かりにくいでしょう。次回は、そのログの内容を確認し、検出ルールの変更やシグネチャのカスタマイズといった運用上の注意点などについて説明したいと思います。
Copyright © ITmedia, Inc. All Rights Reserved.