snort 2.0.1 のインストール
2003-08-21 作成 福島
2003-08-28 更新 福島
2003-08-30 更新 福島
2003-11-05 更新 福島
2003-11-27 更新 福島

ここでは、意識的に ACID は使っていません。
そのうち使うかもしれませんが、検知とか、復旧に関わるものはなるべく単純な形のままにしたいのです。

$ tar xzf snort-2.0.1.tar.gz
$ cd snort-2.0.1
snort-2.0.1$ ./configure
snort-2.0.1$ make
snort-2.0.1$ su
snort-2.0.1# make install

snort-2.0.1# mkdir /etc/snort
snort-2.0.1# cp -p ./etc/snort.conf /etc/snort/.
snort-2.0.1# cp -p ./etc/*.config /etc/snort/.
snort-2.0.1# cp -p ./etc/*.map /etc/snort/.
snort-2.0.1# cp -pr ./rules /etc/snort/.
snort-2.0.1# vi /etc/snort/snort.conf
#var RULE_PATH ../rules         /etc/snort/rules にルール定義を置いたので修正
var RULE_PATH ./rules
snort-2.0.1# groupadd snort snort-2.0.1# useradd -g snort snort snort-2.0.1# mkdir /var/log/snort snort-2.0.1# chown snort:snort /var/log/snort snort-2.0.1# snort -u snort -g snort -c /etc/snort/snort.conf -l /var/log/snort -i eth1 -k none -deDy snort-2.0.1# cat >> /etc/rc.d/rc.local
snort -u snort -g snort -c /etc/snort/snort.conf -l /var/log/snort -i eth1 -k none -deDy

rules ファイルの更新 (ルールセットをアップデートしないと、最新の攻撃を検知できません) http://www.snort.org/dl/rules/ に最新の snortrules ファイルがあるので、これを設置します。 $ tar xzf snortrules-stable.tar.gz $ cd rules 変更点は何かな? rules$ for i in *.config ; do diff /etc/snort/$i $i ; done rules$ for i in *.map ; do diff /etc/snort/$i $i ; done rules$ for i in *.rules ; do diff /etc/snort/rules/$i $i ; done
2003-07-29 バージョンでは、MSブラスター用のルールが追加されている模様。
*.config の比較 (変化無し)

*.map の比較 (シグネチャ ID に 2192,2193 が追加されている) 1c1 < # $Id: sid-msg.map,v 1.131 2003/07/21 22:16:01 cazz Exp $ --- > # $Id: sid-msg.map,v 1.132 2003/07/29 16:03:05 cazz Exp $ 2040a2041,2042 > 2192 || NETBIOS DCERPC ISystemActivator bind attempt || cve,CAN-2003-0352 > 2193 || NETBIOS SMB DCERPC ISystemActivator bind attempt || cve,CAN-2003-0352
*.rules の比較 (ポート 135,445 へのアクセスパターンが追加されている) 3c3 < # $Id: netbios.rules,v 1.25 2003/07/21 22:16:01 cazz Exp $ --- > # $Id: netbios.rules,v 1.26 2003/07/29 16:03:05 cazz Exp $ 29a30,32 > alert tcp $EXTERNAL_NET any -> $HOME_NET 135 (msg:"NETBIOS DCERPC ISystemAc 長いので省略 > alert tcp $EXTERNAL_NET any -> $HOME_NET 445 (msg:"NETBIOS SMB DCERPC ISyst 長いので省略 >
rules$ su rules# cp -p *.config /etc/snort/. それぞれのファイルをコピー rules# cp -p *.map /etc/snort/. rules# cp -p *.rules /etc/snort/rules/. rules# snort の再起動 (PID は /var/run/snort_eth1.pid : eth1 は環境によって違います) ルールファイルを更新するスクリプト (reprules.sh) を作ってみました。 root で実行する必要があります。 ルールの自動更新プログラムもありますが、 ワークエリアを指定するために専用の config を書きたくないので、スクリプトで何とかします。
スクリプト reprules.sh (755)
#!/bin/sh

# snort のルールファイルを取得・更新するスクリプト

# snort のルールファイル
# wget でダウンロードし、ローカルにも保持するファイル
#
RULES_FILE=snortrules-stable.tar.gz

# 更新前のタイムスタンプを取得
TIMESTAMP_OLD=0
if [ -f $RULES_FILE ] ; then
	TIMESTAMP_OLD=`/usr/bin/stat -t $RULES_FILE | /usr/bin/cut -d ' ' -f 13 -`
fi

# ルールファイルをダウンロード
# (ローカルファイルより新しければダウンロード)
# 残念ながら、終了コードでダウンロード状況を見分けることが出来ない。
#
wget -q -N http://www.snort.org/dl/rules/$RULES_FILE

# 更新後のタイムスタンプを取得
TIMESTAMP_NEW=0
if [ -f $RULES_FILE ] ; then
	TIMESTAMP_NEW=`/usr/bin/stat -t $RULES_FILE | /usr/bin/cut -d ' ' -f 13 -`
fi

MSG=''
if [ $TIMESTAMP_NEW -le $TIMESTAMP_OLD ] ; then
	# ダウンロードしなかった
	MSG="snort rules is not download."
else
	# ダウンロードしたルールファイルのほうが新しい
	/bin/gtar xzf $RULES_FILE

	cd ./rules

	WHATS_NEW=''

	for i in *.config ; do WHATS_NEW=$WHATS_NEW`/usr/bin/diff /etc/snort/$i $i` ; done
	for i in *.map    ; do WHATS_NEW=$WHATS_NEW`/usr/bin/diff /etc/snort/$i $i` ; done
	for i in *.rules  ; do WHATS_NEW=$WHATS_NEW`/usr/bin/diff /etc/snort/rules/$i $i` ; done

	if [ -n $WHATS_NEW ] ; then
		# 新しいルールをダウンロードしたが、変化が無かった
		MSG="snort rules is downloaded bat not find differences."
	else
		# 新しいルールに変化 (追加) があった
		mv *.config /etc/snort/.
		mv *.map    /etc/snort/.
		mv *.rules  /etc/snort/rules/.
		MSG="$WHATS_NEW"
	fi

	cd ..
fi

echo $MSG

ログの切り替え (snort の再起動) プレーンテキストのままログを保存するのに便利ですが、一瞬キャプチャが途絶える (下記青文字の部分) ので、気になる方は他の方法 (データベース利用) をお勧めします。 以下のファイルを作成し、定時に実行します。
/home/snort/restart.sh 754
#!/bin/sh

# snort のログを切り替えるスクリプト

cd /home/snort

DATE=`date +%Y%m%d-%H%M%S`

# snort が起動済みかチェック
ALIVED=0
PID=`cat /var/run/snort_eth1.pid`
if [ ! $PID == '' ]; then
	ALIVED=`ps -p $PID | grep snort | wc -l`
fi

if [ $ALIVED == 1 ]; then
	# 起動済みなので停止させる
	kill $PID
	# ログを保存 (リネーム) する
	mv /var/log/snort/alert /var/log/snort/alert-$DATE
fi

# ログファイルを snort グループで読めるようにする
touch /var/log/snort/alert
chmod 640 /var/log/snort/alert
chown snort:snort /var/log/snort/alert

# PROMISC を強制する
/sbin/ifconfig eth1 promisc

# snort を起動 (再起動) する
/usr/local/bin/snort -u snort -g snort -c /etc/snort/snort.conf -l /var/log/snort -i eth1 -k none -deDy

if [ $ALIVED == 1 ]; then
	# ついでにアーカイブする
	# 監視していない時間を短くするために、再起動した後にアーカイブします。
	/usr/bin/gzip /var/log/snort/alert-$DATE
fi

# crontab -e -u root 上記スクリプトを定時に起動
15 4 * * * [ -x /home/snort/restart.sh ] && /home/snort/restart.sh

ログ (/var/log/snort/alert) の読み方 [**] [分類:シグネチャID:リビジョン] 名称 [**] [Classification: Misc activity] [Priority: 3] //-::.少数秒 送信MACアドレス -> 受信MACアドレス type:0x800 len:0x6A 送信IPアドレス -> 受信IPアドレス ICMP TTL:120 TOS:0x0 ID:32548 IpLen:20 DgmLen:92 Type:8 Code:0 ID:512 Seq:34206 ECHO [Xref => 説明へのリンク]
ログの集計 ログのサマリを計算するスクリプト (logsum.pl) を作ってみました。 $ cat /var/log/snort/alert | logsum.pl 等として実行します。
実行結果
  1 99.14%  14442 Pr3 ICMP PING CyberKit 2.2 Windows
  2  0.21%     30 Pr2 WEB-MISC robots.txt access
  3  0.21%     30 Pr2 WEB-CGI count.cgi access
  4  0.13%     19 Pr1 WEB-IIS cmd.exe access
  5  0.13%     19 Pr1 WEB-IIS ISAPI .ida attempt
  6  0.06%      9 Pr3 ICMP Destination Unreachable (Communication Administratively Prohibited)
  7  0.03%      5 Pr2 MISC source port 53 to <1024
  8  0.03%      5 Pr2 WEB-CGI campus access
  9  0.02%      3 Pr2 SCAN SOCKS Proxy attempt
 10  0.01%      2 Pr3 BAD-TRAFFIC tcp port 0 traffic
 11  0.01%      2 Pr2 ATTACK-RESPONSES 403 Forbidden
 12  0.01%      2 Pr2 MS-SQL Worm propagation attempt
total: 14568 signals
スクリプト logsum.pl (755)
#!/usr/local/bin/perl

use strict ;

# 不審なパケットをカウントする
my @sign = () ;
my %sign = () ;
my $total = 0 ;
while (<>)
        {
        my $line = $_ ;
        chomp $line ;

        if ($line eq '')
                {
                if (@sign > 0)
                        {
                        my $first = $sign[0] ;

                        $first =~ s/\s*\[\*\*\]\s*//g ; # 両脇の [**] を取り除く
                        $first =~ s/\s*\[\d+:\d+:\d+\]\s*// ;   # [1:123:4] を取り除く

                        my($priority) = $sign[1] =~ /\[Priority:\s*(\d+)\]/ ;

                        $first = "Pr$priority ".$first ;

                        $sign{$first} ++ ;
                        $total ++ ;
                        }
                @sign = () ;
                }
        else
                {
                push @sign, $line ;
                }
        }

# カウンタ順にソート (降順) して表示する
my $lcnt = 0 ;
foreach my $key (sort { $sign{$b} <=> $sign{$a} } keys %sign)
        {
        $lcnt ++ ;

        my $n = $sign{$key} ;
        printf "%3d ", $lcnt ;
        printf "%5.2f%% ", $n / $total * 100 ;
        printf "%6d ", $n ;
        print "$key\n" ;
        }
print "total: $total signal" ;
print "s" if $total > 1 ;
print "\n" ;
そして、このスクリプトをメール送信するために呼び出してみます。
logsum_send.sh (755)
#!/bin/sh

MAILOFADMIN='net-admin@example.com'	# 管理者のメールアドレスです。適宜変更してください。

cd /root      # とりあえず /root です。環境に応じてカスタマイズしてください。

NOW=`date '+%m/%d %H:%M'`
ARCDAY=`date +%Y%m%d`
# 昨日なら `date +%Y%m%d -d yesterday`

# 今日 (直前に) アーカイブしたアラートファイル
ARCPATH='/var/log/snort/alert-'$ARCDAY'-*.gz'

# アーカイブされたアラートファイルの存在チェック
ARCEXIST=0
for f in $ARCPATH ; do
	if [ -f $f ]; then ARCEXIST=1 ; fi
done

# アーカイブされたアラートの復元準備
if [ $ARCEXIST -eq 1 ]; then
	ZCAT="/bin/zcat $ARCPATH"
else
	ZCAT=""
fi

# 集計メールを送信する
SUBJECT="snort logsum $NOW"
if [ -f /var/log/snort/alert ]; then
	# alert がある場合
	(cat /var/log/snort/alert ; $ZCAT) | ./logsum.pl | mail -s "$SUBJECT" $MAILOFADMIN
elif [ ! -z $ZCAT ]; then
	# alert は無いが、アーカイブファイルがある場合
	($ZCAT) | ./logsum.pl | mail -s "$SUBJECT" $MAILOFADMIN
fi
$ crontab -e
17:00 にメールを飛ばします。(眠っていない時間をお勧めします)
0 17 * * * [ -x /root/logsum/logsum_send.sh ] && /root/logsum/logsum_send.sh

snort に最適なスイッチ (HUB と呼ぶのか、スイッチなのか難しい) FS808TP-V1 (アライドテレシス) 売価 16,000 円のくせに 100base でポートミラーリング (シャドウポートとも言う) が可能です。激安です。 kermit でも設定が出来るので、リモート操作も完璧です。 写真はアライドテレシスからのパクりです。 クリックするとカタログページへ飛びます。 kermit で操作するときは、以下のファイルを作成し、 # kermit FS808TP-V1 kermit を起動 C-Kermit>c kermit のプロンプトで 'c' を入力 として起動します。(当然、手動でも可)
FS808TP-V1.ttyS1
set line /dev/ttyS1
set speed 9600
eight
set parity none
set stop-bits 1
set flow none
set carrier-watch off