Snortにリアルタイム警告を実装する(3/3)

前回は、Snortを使ってサーバ/センサのハイブリッドを構成する方法について見てきた。しかし、大規模な組織では、分散型の3層スキーマにSnortを配置したほうが便利だろう。最終回である今回は、その方法を解説する。

この記事は、Jack Koziolの新著『 Intrusion Detection with Snort 』からの一部抜粋である。

3層スキーマでSnortをセットアップする場合は、各センサに電子メール用アプリケーション(sendmailなど)とswatchをインストールするのは、時間とリソースの無駄だ。しかし、複数のセンサ間で swatchsendmailの構成に変更を加えるのは、混乱や誤りを招きかねない。この問題を解決するには、センサからSnortサーバへ安全に警告を転送できるよう、syslog-ngと Stunnel を利用する。また、サーバをもう1台用意して、警告の収集とメール送信の機能を担当させてもよいだろう。この場合は、このサーバに警告を転送する。

Syslog-ngは、Unixシステム上のさまざまなアプリケーションで使用されているロギング機能のsyslogに代わるものだ。アプリケーションやOSが発したエラー・メッセージとセキュリティ警告はsyslogに送られる。オリジナルのsyslogにはイベントの種類(ファシリティと呼ばれる)が20しかない。各ファシリティには優先度が割り当てられている。このファシリティは汎用なので、さまざまなアプリケーションが利用する。つまり、複数のアプリケーションが、同じファシリティを使ってイベントをsyslogに送っているのだ。違うアプリケーションのイベントが同じファシリティとして報告されるため、特定のアプリケーションが生成したイベントを識別するのが難しい。

syslogファイルに大量のデータが格納されている場合、フィルタリングが困難だ。syslog-ngは、フィルタリングの粒度を上げることでこの問題を解決してくれる。syslog-ngでは、ファシリティや優先度だけでなく、内容でイベントをフィルタすることができる。また、オリジナルのsyslogにはない特長として、イベントのフィルタリングに正規表現を使うことができる。

syslog-ngは他にも、Snort環境に最適な機能を備えている。警告を複数のホストに転送する場合や、Stunnelを使って転送する場合には、オリジナルのsyslogから受け取った警告の送信元がわかりにくくなる。同じホスト上の複数のマシンから警告を収集する場合、syslogは正しいロギング・ホストを報告するが、syslogからのこのような警告をさらにマスタ・ホストに転送すると、この警告は2つ目のホストから送られてきたように見えてしまう。複数のロギング・サーバを利用する大規模なSnort環境では、これにより、警告の送信元を判断するのが難しくなるのだ。syslog-ngでは、ローカル・ホストで警告が生成された時間と共に完全なホスト名が格納されるので、この問題が解決されている。

オリジナルのsyslogはUDP経由で警告を送信する。困ったことに、Stunnelは現在のところ、UDPトラフィックの暗号化をサポートしていない。syslogセッション専用に、 Zebedee などのUDPトンネリング・パッケージをインストールすればこの問題を解決できるが、それよりも、TCPを使うsyslog-ngに乗り換えた方が、すでにインストールしたStunnelパッケージを利用でき、好都合だ。

syslog-ngはさらに、警告の電子メール送信をネイティブでサポートしている。構成ファイルに何行か追加するだけで、特定の文字列にマッチする警告が自動的に電子メールで送信される。これで、swatchをインストールする必要がなくなる。

syslog-ngを配置するには、まずセンサにパッケージをインストールして構成する。syslog-ngパッケージは libol に依存するので、syslog-ngよりも前にlibolをインストールしておく必要がある。おなじみのconfigure、make、make installコマンドを実行してlibolパッケージをインストールする。その後、syslog-ngをダウンロードして、再びconfigure、make、make installの一連のコマンドを実行してパッケージをインストールする。

センサでsyslog-ngを構成する

syslog-ngは、syslog-ng.conf構成ファイルによって制御される。このファイルはscratchで書くことができる。本書の例では、一般的にrservicesで使われるポート(512、513、514)をsyslog-ng用に使用するが、他のポートを使用してももちろん構わない。なお、セキュリティの面から、Snortを配置した層ではrservicesを使用するべきではない。

センサ用にsyslog-ngを構成するには、まず構成ファイル/etc/syslog-ng/syslog-ng.confを作成しなければならない(パッケージに含まれているデフォルト、またはサンプルのsyslog-ng.confファイルを使うのではなく、必ず新しいものを作成すること)。syslog-ng.confファイルは、syslog情報をどこで監視するか、そして情報が見つかった場合にはどのように対応するかをsyslog-ngに知らせるファイルだ。これを適切に利用するには、sourceとdestinationを入力し、この2つを関連付ける。sourceはsyslog-ngが受け取る警告の送信元で、destinationは警告の出力先となるエリアである。

sourceとdestinationを関連付けることで、syslog-ngはどこから警告を収集し、どこに送信すればよいかを判断できるようになる。定義したsourceには、いくつでもdestinationを関連付けることができ、その逆も同様だ。

最初に作成するのはsourceの行だ。これは、syslog-ngアプリケーションに送られたsyslog-ng警告の送信元を識別するのに使用される。sourceを指定する際には識別名も指定する必要がある。命名のガイドラインとしては、センサ名、アンダースコアに続いて、 ACID (Analysis Console for Intrusion Databases)内でセンサが使用している整数を使用するとよいだろう(「sensor_7」など)。構文は次のとおりだ。

source identifier {source-driver(parameter);};

source-driverは、syslog-ngが警告を監視する場所だ。source-driverはローカル・マシンやTCPポート、あるいはファイルでも構わない。source-driverはいくつでも指定できる。syslog-ngをセンサにインストールする場合は、ローカル・システムからの警告を受け入れる必要がある。そのためには、次のような設定行を使用する。

source sensor_7 {unix-stream(“/dev/log “);internal();};

識別名の「sensor_7」から、センサの名前はsensorであり、ACIDでは7に対応していることがわかる。unix-stream(“/dev/log “)というソース・ドライバは、これがLinuxシステムであること、そして、SOCK_STREAMモードで警告をリスニングすることをsyslog-ngに伝えている。BSDファミリのいずれかを使っている場合は、これをunix-dgram(“/dev/log “)に変更する。internalコマンドは、syslog-ngで内部的に生成されたメッセージもリスニングするよう指示するものだ。

次に作成する行は、警告の送信先であるdestinationを指定する行だ。destination行を次の構文で指定し、すべての警告がセンサから直接Snortサーバに転送されるようにする。

destination identifier {destination-driver(parameter);};

identifierはSnortサーバの名前、destinationは、サーバ上にインストールされるsyslog-ngサービスに対応するIPアドレスとポートだ。次に例を示す。

destination snort_server { tcp(“Snort_Server_IP ” port (514)); };

この行は、Snort_Server_IPにあり、514/TCPポートでリスニングを行っているsyslog-ngデーモンに警告を転送する。

最後の設定行は、どのsourceがどのdestinationに対応しているかをsyslog-ngに知らせるものだ。この例ではsourceとdestinationが1つずつしかないため、この設定行は1つで済む。log設定行の構文は次のとおりだ。

log {source(source_name); filter(filter_name); destination(destination_name) };

現在、フィルタは使用していないので、filterオプションは省略して構わない。後ほど、リアルタイム警告をサポートするためにsyslog警告のフィルタリングが必要になるが、今のところ、log行を構成するには、すでに作成したsource行とdestination行だけを利用すればよい。

log {source(sensor_7); destination(snort_server); };

これで、センサでのsyslog-ngの構成は完了だ。このファイルは後ほど、Stunnelを有効にする際にもう一度扱う。syslog-ngを起動するには、/usr/local/sbin/syslog-ngコマンドを実行する。

サーバにsyslog-ngをインストールして構成する

サーバにsyslog-ngをインストールする手順は、センサの場合と同様だ。libolをダウンロードしてインストールした後、syslog-ngをインストールする。

先の説明でsyslog-ng.confファイルの構成方法を把握していれば、Snortサーバでsyslog-ngを構成するのはそれほど大変ではない。syslog-ng構成ファイル(/etc/syslog-ng/syslog-ng.conf)を作成して、これを編集する。まず、TCPポートとローカルのsyslog-ngアプリケーションをリスニングするsource行を作成する。センサから転送されてくる警告に加え、syslog-ngアプリケーション自身に関連する警告も受け取れるようにしたいので、行は次のようになる。

source sensors {unix-stream(“/dev/log “); internal(); tcp(ip(Snort_Server_IP ) port(514) max-connections(7) };

このコマンドは、syslog-ngがローカルに生成した警告をリスニングする。さらに、TCPのポート514経由で送られた警告を、IPアドレスSnort_Server_IPが割り当てられたインタフェースでリスニングする。このIPアドレス(Snort_Server_IP)は、センサの制御に使用している管理用NICのIPに置き換えること。max-connections()オプションには、syslog-ngサーバに接続できるセンサの最大数を指定する。

次に、destinationの設定行を作成する。サーバのローカル・ログファイルに警告を送るようにするには、次のように指定する。

destination localhost { file(“/var/log/snort.log “)); };

これで、センサからのログがすべて、指定された場所にあるログファイルに書き込まれる。警告のローカルファイルへの転送に必要な最後の設定行は、sourceとdestinationを関連付けるlogステートメントだ。

log {source(sensors); destination(localhost); };

では、Snortをテストするために、警告を生成するようなトラフィックを送信して、by checking the /var/log/snort.logファイルをチェックしてみよう。何も問題がなければ、syslog-ngを利用したリアルタイム警告の構成に移ろう。

リアルタイム警告用にsyslog-ngを構成する

電子メールやポケットベル経由で警告を送信するようsyslog-ngを構成するには、指定された文字列が見つかった場合にsyslog-ngによって実行される、簡単なシェル・スクリプトを作成する。このシェル・スクリプトが、電子メール、またはポケットベル用アプリケーションを呼び出す。また、設定行もいくつか追加する必要がある。

まず設定行を追加し、その後シェル・スクリプトを作成していく。syslog-ng.confファイルを開いて編集するが、source設定行はローカルのsnort.logファイルにロギングするためのものを利用できるので、新しく作成する必要はない。警告のdestinationは作成する必要がある。スクリプトを実行させるには次の行を使用する。

destination email_alert_script {program (“/usr/local/bin/alert_mail.sh “); };

programオプションには、実行するコマンド(警告を受け取る)を指定する。コマンドの完全パスを指定すること。

次に、Snortの警告のうち、優先度が高いものだけにマッチするフィルタを作成する。優先度1のSnortの警告をすべて選択するには、filter行を次のように作成する。

filter high_priority {match (“\\[Priority:1 \\]”); };

角かっこをバックスラッシュ2つ(\\)でエスケープする必要があることに注意してほしい。警告を受け取りたい優先順位の1つ1つに、フィルタを作成する。

さらに、logステートメントを追加して、source、destination、そしてfilter設定行を互いに関連付ける。

log {source(sensors); filter(high_priority); destination(email_alert_script); };

これで、syslog-ng.confファイルの構成は完了だ。syslog-ngを終了して再起動する。

最後に、前述した簡単なシェル・スクリプトを書く必要がある。このスクリプトはsyslog-ngが実行する。/usr/local/bin/alert_mail.shファイルを開いて、次のスクリプトを入力する。

#!/bin/sh
while read line; do
echo $line |mail -s “High Priority Snort Alert” IDS__admin@domain.com
done

このスクリプトは、IDS_admin@domain.comに、「High Priority Snort Alert」という表題の電子メールで警告を送信する。ポケットベル用のパッケージや、sendmail以外の電子メール・アプリケーションを使用している場合などには、このスクリプトを必要に応じて変更してほしい。別の優先度の警告を受け取るには、フィルタとlogステートメントを新しく作成するだけでよい。リアルタイム警告が正しく機能しているかどうかをテストしたら、syslog-ngのトラフィックをStunnelで暗号化する方法について見ていこう。

syslog-ngセッションをStunnelで暗号化する

Stunnel on the SnortセンサとSnortサーバにStunnelがインストールされていない場合は、この記事の基となっている 書籍 の6章と7章を参考にしてインストールしてほしい。Stunnelを利用するには、センサとサーバ両方のsyslog-ng.confファイルに変更を加える必要がある。

センサのsyslog-ng.confファイルを開いて、まず、ローカルのsyslog-ngマシンの正確な名前を保存するグローバルなオプションを追加する。このオプションを指定しないと、すべての警告のホスト名がローカル・ホストのものになってしまい、どのセンサが警告を生成したのかを判断するのが困難になる。

options { keep_hostname(yes); };

続いて、新しいdestination設定行を作成する。Stunnelがトラフィックを読み取って暗号化し、サーバに転送できるよう、syslog-ngからトラフィックをルーティングさせるため、新しいdestination行は次のようになる。

destination stunnel {tcp(“127.0.0.1” port (513)) ;};

このdestinationは、ローカル・ホスト(127.0 0.1)のポート513に警告を送る。では、この新しいdestinationを使用するよう、既存のlog行を書き換えよう。

log { source(sensor_7); destination(stunnel); };

syslog-ng.confファイルを保存して閉じる。syslog-ngプロセスを再起動して、syslog-ngに新しい構成ファイルを認識させる。

それでは、Stunnelデーモンを起動して、暗号化されたsyslog-ngトラフィックを処理してみよう。

/usr/local/stunnel/sbin/stunnel -c -d 127.0.0.1:513 -r \
Snort_Server_IP :512 -s stunnel_user -g stunnel_group &

このコマンドでは-cスイッチが指定されており、Stunnelがクライアント・モードにセットされる。syslog-ngのトラフィックが、Snortサーバのローカル・ホスト(Snort_Server_IPにある)のポート513に転送される。このコマンドはまた、stunnel_user(stunnel_groupのメンバ)としてデーモンを実行する。センサ用のStunnelの構成はこれで完了だ。

今度はSnortサーバ側を構成しよう。syslog-ng構成ファイルに、センサの場合と同様の変更を加えなくてはならない。syslog-ng.confファイルを開いて、こちらではStunnelがトラフィックを受け取って、それをローカルのsyslog-ngのTCPポートに転送するように設定する。まず、新しいsource行を作成してこの変更を適用する。次のようなsource行を追加する。

source stunnel { unix-stream(“/dev/log “); internal();
tcp(ip(127.0.0.1) port(514) max-connections(7) };

次に、log行を変更して、新しいsourceを反映させる。既存のlog行を次のように変更する。

log {source(stunnel); destination(localhost); };

ファイルを保存して閉じ、syslog-ngデーモンを再起動する。これで、Stunnelからローカルのsyslog-ngサービスにログを保存する準備が整った。最後のステップは、 サーバ上のStunnelデーモンを起動することだ。

/usr/local/stunnel/sbin/stunnel -d 512 -r 127.0.0.1:514 -p /usr/local/ssl/certs/stunnel.pem &

このコマンドによって、Stunnelがポート512で、syslog-ngからの着信トラフィックのリスニングを開始する。その後このトラフィックを、ポート514で動作しているローカルのsyslog-ngサーバに転送する。これで、Stunnelの構成も終了だ。警告は、暗号化されてネットワーク上を転送されるようになった。

万全を期す

ここで紹介した分散型のSnortの設定は、セッション・ベースの攻撃には比較的強い。MySQL接続、syslog-ngセッション、ACIDブラウザ・セッションのすべてが暗号化されるからだ。もちろんこの設定は無敵ではないが、多くの攻撃者にとって、警告を傍受したり変更したりするのが難しくなるのは確かだ。このシステムに無視できないセキュリティ・ホールがあるとすれば、それはリアルタイム警告を送信する電子メールだ。

接続をここまで暗号化してきたのだから、この際、リアルタイム警告の電子メールも暗号化して、セキュリティを万全にするのがよいだろう。電子メール・システムの暗号化をインストールする方法は、電子メールのアプリケーションのマニュアルを参照してほしい。

Jack Koziolは、シカゴ西部に本拠地を置く国民健康保険関連企業の情報セキュリティ部門のマネージャである。1998年以来、ネットワークセキュリティの分野で活躍している。Eコマース、ヘルスケア、金融などの業界で、上級管理職として、実働環境で大規模なSnortベースの侵入検知システムを構築してきた。Information Security Magazine誌では「Hack and Defend」やCISSPのレビュー・セッション・コースの講師を務め、情報セキュリティに関するさまざまな記事を執筆している。

2へ
1へ