#!/usr/local/bin/bash
##
## FreeBSD ipfw log analyzer
##
PATH="/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/sbin:$PATH"
TS=`date +"%s"`
TMPFILE="/tmp/ana_ipfw-$TS"
TMPFILEsort="/tmp/ana_ipfw_sort-$TS"
LC_ALL=C
LANG=C
### Default options
datelimit=no
portlimit=no
iplimit=no
verbose=no
sorted=no
onlydata=no
datestr=""
logfile="/var/log/ipfw.log"
### Help
usage () {
echo "Usage: $0 [-p] [-i] [-v] [-s] [-o] [-d date_limit] [filename]"
echo " -p port analysis"
echo " -i IP address analysis"
echo " -d date format"
echo " +DDAY from DDAY to today"
echo " +-DDAY DDAY days ago"
echo " YYYYMMDD-YYYYMMDD from first YYYYMMDD to last YYYYMMDD"
echo " total all data records in the log file"
echo " -s sorted by count"
echo " -o only data and disable verbose"
echo " -v enable verbose messages"
echo " filename default : /var/log/ipfw.log"
}
if [ $# -eq 0 ]; then
usage
exit 1
fi
### Get arguments
args=`getopt dpivso $*`
if [ $? != 0 ]; then
echo "$0:ERROR"
exit 2
fi
set -- $args
for arg
do
case "$arg" in
-d ) datelimit=yes; shift ;;
-p ) portlimit=yes; shift ;;
-i ) iplimit=yes; shift ;;
-v ) verbose=yes; shift ;;
-s ) sorted=yes; shift ;;
-o ) onlydata=yes; shift ;;
-- ) datestr=$2; shift; shift ;;
esac
done
if [ $datelimit == "no" ]; then
if [ ! -z $datestr ]&&[ -f $datestr ]; then
logfile=$datestr
fi
else
if [ ! -z $datestr ]&&[ ! -z $1 ]; then
logfile=$1
fi
fi
if [ ! -f $logfile ]; then
echo "Error : Log file $logfile does not existed."
exit 1
fi
if [ $onlydata == "yes" ]; then
verbose=no
fi
### For debug
if [ $verbose == "yes" ]; then
echo "Parameters"
echo $args
echo "Date $datelimit($datestr) Port $portlimit IP $iplimit Verbose $verbose Sort $sorted Logfile $logfile"
echo ""
fi
### Generate date limitation
if [ $datelimit == "no" ]; then
dtmp="0"
datearray=($dtmp)
else
if [ ! -z `echo $datestr | awk 'BEGIN { FS = "+" } ; { print $2 }'` ]; then
if [ ! -z `echo $datestr | awk 'BEGIN { FS = "+" } ; { print $2 }' | awk 'BEGIN { FS = "-" } ; { print $2 }'` ]; then
datearray=(`echo $datestr | awk 'BEGIN { FS = "+" } ; { print $2 }' | awk 'BEGIN { FS = "-" } ; { print $2 }'`)
else
i=`echo $datestr | awk 'BEGIN { FS = "+" } ; { print $2 }'`
dtmp=""
for((; i >= 0; i--))
do
dtmp="$dtmp $i"
done
datearray=($dtmp)
fi
elif [ "$datestr" == "total" ]; then
datestr="total"
elif [ -z $datestr ]; then
dtmp="0"
datearray=($dtmp)
else
if [[ $datestr != *[!0-9\-]* ]]; then
bdate=`echo $datestr | awk 'BEGIN { FS = "-" } ; { print $1 }'`
edate=`echo $datestr | awk 'BEGIN { FS = "-" } ; { print $2 }'`
else
bdate=`date +"%Y%m%d"`
edate=`date +"%Y%m%d"`
fi
todayts=`date -j "+%s"`
bdatets=`date -j -f "%Y%m%d" "$bdate" "+%s"`
edatets=`date -j -f "%Y%m%d" "$edate" "+%s"`
if [ $bdatets -gt $todayts ]; then
echo "Error : $bdate is future. I can not analyze it."
exit 1
else
ib=`expr \( $todayts - $bdatets \) / 86400`
fi
if [ $edatets -gt $todayts ]; then
if [ $verbose == "yes" ]; then
echo "Warning : $edate is future. But I can replace it with today("`date +"%Y%m%d"`")."
echo ""
fi
ie=0
else
ie=`expr \( $todayts - $edatets \) / 86400`
fi
dtmp=""
for((i = $ib; i >= $ie; i--))
do
dtmp="$dtmp $i"
done
datearray=($dtmp)
fi
fi
### Create tmp file
if [ $verbose == "yes" ]; then
echo "Create $TMPFILE"
echo ""
fi
touch $TMPFILE
### Get log
if [ $verbose == "yes" ]; then
echo "Get log from $logfile"
fi
if [ $datelimit == "no" ]; then
if [ $verbose == "yes" ]; then
date +"%b %e"
fi
keyfilter=`date +"%b %e"`
grep "$keyfilter" $logfile >> $TMPFILE
elif [ "$datestr" == "total" ]; then
cat $logfile > $TMPFILE
else
for dnum in ${datearray[@]}
do
if [ $verbose == "yes" ]; then
date -v-${dnum}d +"%b %e"
fi
keyfilter=`date -v-${dnum}d +"%b %e"`
grep "$keyfilter" $logfile >> $TMPFILE
done
fi
if [ $verbose == "yes" ]; then
echo ""
fi
if [ $verbose == "yes" ]; then
echo "Count lines in $TMPFILE"
wc -l $TMPFILE
echo ""
fi
### Port Analysis
if [ $portlimit == "yes" ]; then
if [ $sorted == "yes" ]; then
rm -f $TMPFILEsort
touch $TMPFILEsort
fi
if [ $onlydata == "no" ]; then
echo "[[[ Port Analysis ]]]"
printf "%12s\t%12s\n" "Port Number" "Count"
printf "%12s\t%12s\n" "------------" "--------"
fi
for portnum in `cat $TMPFILE | awk 'BEGIN { FS = " " } ; { if( $11=="\-\>" ){ split($12, p, ","); print p[1] } else { print $11 } }' | grep ":" | awk 'BEGIN { FS = ":" } ; { print $2 }' | sort -u -n`
do
if [ $sorted == "yes" ]; then
printf "%12s\t%12s\n" "$portnum" `cat $TMPFILE | awk 'BEGIN { FS = " " } ; { if( $11=="\-\>" ){ split($12, p, ","); print p[1] } else { print $11 } }' | grep ":" | awk 'BEGIN { FS = ":" } ; { print $2 }' | grep $portnum | wc -l` >> $TMPFILEsort
else
printf "%12s\t%12s\n" "$portnum" `cat $TMPFILE | awk 'BEGIN { FS = " " } ; { if( $11=="\-\>" ){ split($12, p, ","); print p[1] } else { print $11 } }' | grep ":" | awk 'BEGIN { FS = ":" } ; { print $2 }' | grep $portnum | wc -l`
fi
done
if [ $sorted == "yes" ]; then
cat $TMPFILEsort | awk 'BEGIN { FS = " " } ; { printf ( "%12s\t%12s\n", $1, $2) }' | sort -rgk2 > /tmp/ttt-$TS
cat /tmp/ttt-$TS > $TMPFILEsort
rm -f /tmp/ttt-$TS
cat $TMPFILEsort
fi
fi
### Client IP Analysis
if [ $iplimit == "yes" ]; then
if [ $sorted == "yes" ]; then
rm -f $TMPFILEsort
touch $TMPFILEsort
fi
if [ $onlydata == "no" ]; then
echo "[[[ Client IP Analysis ]]]"
printf "%16s\t%12s\n" "IP Address" "Count"
printf "%16s\t%12s\n" "----------------" "--------"
fi
for ipaddr in `cat $TMPFILE | awk 'BEGIN { FS = " " } ; { print $10 }' | grep ":" | awk 'BEGIN { FS = ":" } ; { print $1 }' | sort -u -n`
do
if [ $sorted == "yes" ]; then
printf "%16s\t%12s\n" "$ipaddr" `cat $TMPFILE | awk 'BEGIN { FS = " " } ; { print $10 }' | grep ":" | awk 'BEGIN { FS = ":" } ; { print $1 }' | grep $ipaddr | wc -l` >> $TMPFILEsort
else
printf "%16s\t%12s\n" "$ipaddr" `cat $TMPFILE | awk 'BEGIN { FS = " " } ; { print $10 }' | grep ":" | awk 'BEGIN { FS = ":" } ; { print $1 }' | grep $ipaddr | wc -l`
fi
done
if [ $sorted == "yes" ]; then
cat $TMPFILEsort | awk 'BEGIN { FS = " " } ; { printf ( "%16s\t%12s\n", $1, $2) }' | sort -rgk2 > /tmp/ttt-$TS
cat /tmp/ttt-$TS > $TMPFILEsort
rm -f /tmp/ttt-$TS
cat $TMPFILEsort
fi
fi
### Remove tmp file
if [ $verbose == "yes" ]; then
echo ""
echo "Remove $TMPFILE"
fi
rm -f $TMPFILE
if [ $sorted == "yes" ]; then
if [ $verbose == "yes" ]; then
echo "Remove $TMPFILEsort"
fi
rm -f $TMPFILEsort
fi
使用方法如下 :
Usage: /Path/to/ana_ipfw.sh [-p] [-i] [-v] [-s] [-o] [-d date_limit] [filename]
-p port analysis
-i IP address analysis
-d date format
+DDAY from DDAY to today
+-DDAY DDAY days ago
YYYYMMDD-YYYYMMDD from first YYYYMMDD to last YYYYMMDD
total all data records in the log file
-s sorted by count
-o only data and disable verbose
-v enable verbose messages
filename default : /var/log/ipfw.log
分析範例如下 :
今天的 port 分析
# ./ana_ipfw.sh -p
[[[ Port Analysis ]]]
Port Number Count
------------ --------
21 4
22 14
25 13
80 30
111 2
199 2
389 2
443 8
873 2
2049 2
3000 36
3306 11
5800 2
5900 5
6000 2
6001 2
今天的 port 分析(按照數量排序)
# ./ana_ipfw.sh -ps
[[[ Port Analysis ]]]
Port Number Count
------------ --------
3000 36
80 30
22 14
25 13
3306 12
443 8
5900 5
21 4
6001 2
6000 2
5800 2
2049 2
873 2
389 2
199 2
111 2
最近三天的 port 分析
# ./ana_ipfw.sh -p -d +3
[[[ Port Analysis ]]]
Port Number Count
------------ --------
21 7
22 20
25 41
80 72
111 2
199 2
389 2
443 14
873 2
2049 2
3000 72
3306 57
5800 2
5900 12
5901 3
6000 7
6001 2
最近三天的 port 分析(按照數量排序)
# ./ana_ipfw.sh -p -d +3 -s
[[[ Port Analysis ]]]
Port Number Count
------------ --------
3000 72
80 72
3306 57
25 41
22 20
443 14
5900 12
6000 7
21 7
5901 3
6001 2
5800 2
2049 2
873 2
389 2
199 2
111 2
最後開進工程模式(用來修 script 用, 應該還有 bug.).
# ./ana_ipfw.sh -pv
Parameters
-p -v --
Date no() Port yes IP no Verbose yes Sort no Logfile /var/log/ipfw.log
Create /tmp/ana_ipfw-1347716436
Get log from /var/log/ipfw.log
Sep 15
Count lines in /tmp/ana_ipfw-1347716436
495 /tmp/ana_ipfw-1347716436
[[[ Port Analysis ]]]
Port Number Count
------------ --------
21 4
22 14
25 13
80 30
111 2
199 2
389 2
443 8
873 2
2049 2
3000 36
3306 12
5800 2
5900 5
6000 2
6001 2
Remove /tmp/ana_ipfw-1347716436
No comments:
Post a Comment