2013/03/07

サーバのログを加工してみた

 サーバへ飛んでくる不正アクセスと,そのログ.iptablesを使って指定した国からのアクセスを弾き,ログを残すよう設定してあるのだけれど,時間帯別/国別の頻度を見てみたいなーと思っていました.そこで今回はshellの練習も交えてログ解析の(簡単!お粗末!な)スクリプトを作成しました.

材料

syslogの吐く/var/log/messagesから.1アクセスにつき残るログはこんな感じ.

/var/log/messages-20130303:Mar  2 11:21:59 server kernel: [IPTABLES DENY_COUNTRY]:IN=eth0 OUT= MAC=x:x:x SRC=61.236.64.56 DST=xxx.xxx.xxx LEN=48 TOS=0x00 PREC=0x00 TTL=112 ID=61662 PROTO=TCP SPT=13548 DPT=22 WINDOW=65535 RES=0x00 SYN URGP=0

フォーマットはデフォルトのままです.とりあえずここからアクセス元IPアドレス("SRC=xxx.xxx.xxx.xxx")を抽出してみます.

調理その1 - 時間帯別の集計

道具は当然shell.まずはログから1時間毎のアクセス頻度を集計してみます.最近ようやく慣れてきたけど全然美しくないコマンドは以下のようになりました.

$ grep "IPTABLES DENY_COUNTRY" ${LOG}/messages | awk '{print $3}' | cut -f1 -d':' | sed 's/^0\([0-9]\)/\1/' | sort -n | uniq -c | awk '{print $2 " " $1 }'

0 4
1 4
2 6
3 7
~中略~
21 6
22 5
23 10


1)ログから時刻を抽出して,2)重複している時刻をカウントし,3)整形して出力 という感じ.最初はsortとuniqの順序が逆だったのですが,これだと重複が正しく処理されませんでした.なので,uniqの前に必ずsortをかけましょー.
数字を羅列しただけだとわかりづらいですが,時間帯による頻度の差はそれほど無いように思えます.

調理その2 - 国別の集計

続いて,アクセス元の国名から集計します.必要なのは

  1. ログからのアクセス元IPアドレスの抽出
  2. IPアドレスから国名を判定
の2点です.1はOKでしょう.2はとりあえず国名がわかれば良いのでwhoisを使ってみます.これはCentOS6にデフォルト入っていないので,jwhoisをインストールしました.

$sudo yum -y install jwhois

試しに自分のドメインを照会してみました.

$whois hogehoge.net
・・・中略・・・
Tech Country: JP
・・・中略・・・

どうやら"Tech Country"で絞ってやれば取得できそうです.ログに残っている適当なIPアドレスを使って

$whois xxx.xxx.xxx.xxx | grep "Tech Country" ${LOG}/messages

が,何も出力されない.まさかと思って単純にwhoisで照会すると,なんとフォーマットが異なっていました.さらにはフィールドに国名すら載っていない国もある.はてさて困った.けどちょちょっと調べたらgeoiplookupなるコマンドを発見.さっそくインストール.

$sudo yum -y install geoip

$geoiplookup hogehoge.net
GeoIP Country Edition: JP, Japan

$geoiplookup somewhere@china
GeoIP Country Edition: CN, China

どうやら大丈夫そうです.というわけで長くなりましたが,最終的に作ったスクリプトは以下のようになります.


#!/bin/bash

iaddr_list=(`grep "IPTABLES DENY_COUNTRY" $1 | sed 's/^.*SRC=\(.\+\) DST.\+$/\1/g' | uniq`)
cn_list=()
for iaddr in ${iaddr_list[@]}
do
     cn=`geoiplookup ${iaddr}`"\n"
     cn_list=("${cn_list[@]}" $cn)
done
echo -e "${cn_list[@]}" | sed '/^\s*$/d' | awk '{print $4}'  | sort | uniq -c | sed 's/\(.\+\),$/\1/g' | awk '{print $2 " " $1 }'

1)ログから抽出したIPアドレスのリストを配列に格納して,2)それぞれに対して国名を照会し,3)整形して出力という感じです.for文を使ったためちょっと見づらいですが,練習にはちょうどよしでした.いままでパイプに頼りすぎてfor文をまともに書いたことなかったので(...でもfor文がいらなくなる方法やらコマンドありそう,絶対).以下,結果です.


BR 2
CN 96
IP 2
KR 11
RU 7
TW 5

上手くいきました."IP"は国名が見つからなかったアドレスです.国別の結果はわかりやすく,中国からのアクセスが圧倒的です.

今回初めて実用的...かどうかは置いといて,ログをいじくって簡単な集計をしてみました.なるべく他人のブログなどなど見ないようにしてやり通しましたが,やっぱり自分はまだまだshellのレベルが低いことを痛感します.抽出したデータも見える情報少ないですしね.けれどもなかなか収穫も多かったように思います.もう少し発展させて,母数を増やしてきちんと分析・考察できたら楽しいだろうな.

とりあえずやってみました,以上です.

0 件のコメント:

コメントを投稿