#!/bin/sh
#
# ssh_chk.sh By H.Uekusa since Sep 2005
# Ver 2.22 2017.01.18
# Automated defending tool for ssh/smtp attack.
# This command must be set on the cron with every minutes
###############################################################################
#
# You should set 
# [$SHPATH] [$TMP]/total_min_ipfw_add_cmd.txt
# [$SHPATH] [$TMP]/total_hour_ipfw_add_cmd.txt
# in /etc/rc.local
#
# exit code is...
# 0: Detect attack(s) in the minutes
# 1: Another ssh_chk is runnning
# 2: There is no difference between previous minutes
# 3: IP address format error
#
###############################################################################

###############################################################################
# Set variable for location of commands, Path of files...
###############################################################################

CATPATH="/bin/cat"
AWKPATH="/usr/bin/awk"
GREPPATH="nice -n 10 /usr/bin/grep --mmap"
DIFFPATH="/usr/bin/diff"
SORTPATH="/usr/bin/sort"
MAILPATH="/usr/bin/mail"
DATEPATH="/bin/date"
SHPATH="/bin/sh"
TOUCHPATH="/usr/bin/touch"
LOOKUP="/usr/local/bin/dig"
SEDPATH="/usr/bin/sed"

###############################################################################
# The full path of the logfile to check
# ssh: /var/log/auth.log
# smtp: /var/log/mail.log
###############################################################################
AUTHLOG="/var/log/auth.log"

TMP="/var/tmp/ssh_chk"
LOCKFILE="ssh_chk.lock"

PREV_MIN_RECORD="prev_min"
IPFW_FILE="ipfw_added.txt"

###############################################################################
# Key word for search in the log
# ssh: "Invalid"
# smtp: "did not issue MAIL/EXPN/VRFY/ETRN during connection to MTA"
###############################################################################
LOG_KEY="Invalid"

###############################################################################
# Count key such as process name in the log
# ssh: ssh
# smtp: sm-mta
###############################################################################
COUNT_KEY="ssh"

MAIL_SUBJECT_MIN="SSH attack detected by minutes"
MAIL_SUBJECT_HOUR="SSH attack detected by hour"

###############################################################################
# IP_STYLE:
# Format of IP address in the line
# 1: 123.123.123.123
# 2: [123.123.123.123]
###############################################################################
IP_STYLE="1"

###############################################################################
# Should be BSD-Firewall
###############################################################################
IPFWPATH="/sbin/ipfw"

###############################################################################
# Only for ssh/authlog
# Select to check "attempt"
###############################################################################
CHK_IP_RESOLV="yes"
CHK_IP_MAP="yes"
CHK_IP_MAXAUTH="yes"
CHK_IP_MAXAUTH_INVALID="yes"

###############################################################################
# Only for smtp/maillog
# "possible SMTP attack"
###############################################################################
CHK_possible_SMTP_attack="no"

###############################################################################
# Set threshold
###############################################################################
OK_PER_MIN="3"
OK_PER_HOUR="6"

###############################################################################
# Set IPFW parameters
###############################################################################
IPFW_NUM="199"
PORT="22"
IF_NAME="xxxx"

###############################################################################
# Set valid e-mail(s)!
###############################################################################
MAILTO="hogehoge@hogehoge.hogehoge"

###############################################################################

###############################################################################
#check the tmp dir
###############################################################################
if [ ! -d "$TMP" ];then
	mkdir $TMP
fi

###############################################################################
#check the lock file
###############################################################################
if [ -f "$TMP/$LOCKFILE" ];then
	echo "$0 is executing already"
	echo "Please wait for a while or remove lock file $LOCKFILE!"
	exit 1
fi

### put a lock file ###
$TOUCHPATH $TMP/$LOCKFILE

###############################################################################
#Get date values
###############################################################################
NOW=`$DATEPATH +%Y%m%d%H%M`
PREV=`cat $TMP/$PREV_MIN_RECORD`
NOW_HOUR=`$DATEPATH +%Y%m%d%H`
PREV_HOUR=`$DATEPATH -v -1H +%Y%m%d%H`

###############################################################################
#Sort and avoid blank line from the added IP list
###############################################################################
$TOUCHPATH $TMP/$IPFW_FILE
$SORTPATH -u $TMP/$IPFW_FILE >$TMP/$IPFW_FILE.sort
$GREPPATH -v '^$' $TMP/$IPFW_FILE.sort |$GREPPATH -v '^ .*' >$TMP/$IPFW_FILE.filtered

cp -p $TMP/$IPFW_FILE.filtered $TMP/$IPFW_FILE
rm -f $TMP/$IPFW_FILE.sort
rm -f $TMP/$IPFW_FILE.filtered

###############################################################################
#Get failed lines from auth log
###############################################################################

# Find a string for invalid user for FreeBSD 6.x and later
$GREPPATH "$LOG_KEY" $AUTHLOG > $TMP/"$NOW"_fail.txt

# It's old version of above for FreeBSD 4.x/5.x
# $GREPPATH Illegal $AUTHLOG > $TMP/"$NOW"_fail.txt

### Touch the previous file for safe ###
$TOUCHPATH $TMP/"$PREV"_fail.txt
echo "$NOW" > $TMP/$PREV_MIN_RECORD

###############################################################################
#Compare with before one minutes
###############################################################################

$DIFFPATH $TMP/"$NOW"_fail.txt $TMP/"$PREV"_fail.txt \
 |$GREPPATH '^<' > $TMP/diff_raw.txt

NONE_STATUS=`$GREPPATH -c $COUNT_KEY $TMP/diff_raw.txt`

###############################################################################
#Detect a probing of ssh from attacker (Selective)
#As same as above procedure for normal check
###############################################################################

if [ "$CHK_IP_RESOLV" = "yes" ];then
	$GREPPATH "POSSIBLE BREAK-IN ATTEMPT" $AUTHLOG |$GREPPATH "getaddrinfo" \
	 > $TMP/"$NOW"_fail-resolv.txt

	$TOUCHPATH $TMP/"$PREV"_fail-resolv.txt

	$DIFFPATH $TMP/"$NOW"_fail-resolv.txt $TMP/"$PREV"_fail-resolv.txt \
	 | $GREPPATH '^<' > $TMP/diff_raw-resolv.txt

	NONE_STATUS_RESOLV=`$GREPPATH -c $COUNT_KEY $TMP/diff_raw-resolv.txt`
else
	NONE_STATUS_RESOLV="0"
fi

if [ "$CHK_IP_MAP" = "yes" ];then

	$GREPPATH "POSSIBLE BREAK-IN ATTEMPT" $AUTHLOG \
	 |$GREPPATH "not map back to the address" \
	 > $TMP/"$NOW"_fail-map.txt

	$TOUCHPATH $TMP/"$PREV"_fail-map.txt

	$DIFFPATH $TMP/"$NOW"_fail-map.txt $TMP/"$PREV"_fail-map.txt \
	 | $GREPPATH '^<' > $TMP/diff_raw-map.txt

	NONE_STATUS_MAP=`$GREPPATH -c $COUNT_KEY $TMP/diff_raw-map.txt`
else
	NONE_STATUS_MAP="0"
fi

if [ "$CHK_IP_MAXAUTH" = "yes" ];then

	$GREPPATH "error: maximum authentication attempts exceeded" $AUTHLOG \
	 |$GREPPATH -v "invalid user" \
	 > $TMP/"$NOW"_fail-maxauth.txt

	$TOUCHPATH $TMP/"$PREV"_fail-maxauth.txt

	$DIFFPATH $TMP/"$NOW"_fail-maxauth.txt $TMP/"$PREV"_fail-maxauth.txt \
	 | $GREPPATH '^<' > $TMP/diff_raw-maxauth.txt

	NONE_STATUS_MAXAUTH=`$GREPPATH -c $COUNT_KEY $TMP/diff_raw-maxauth.txt`
else
	NONE_STATUS_MAXAUTH="0"
fi

if [ "$CHK_IP_MAXAUTH_INVALID" = "yes" ];then

	$GREPPATH "error: maximum authentication attempts exceeded" $AUTHLOG \
	 |$GREPPATH "invalid user" \
	 > $TMP/"$NOW"_fail-maxauth-invalid.txt

	$TOUCHPATH $TMP/"$PREV"_fail-maxauth-invalid.txt

	$DIFFPATH $TMP/"$NOW"_fail-maxauth-invalid.txt $TMP/"$PREV"_fail-maxauth-invalid.txt \
	 | $GREPPATH '^<' > $TMP/diff_raw-maxauth-invalid.txt

	NONE_STATUS_MAXAUTH_INVALID=`$GREPPATH -c $COUNT_KEY $TMP/diff_raw-maxauth-invalid.txt`
else
	NONE_STATUS_MAXAUTH_INVALID="0"
fi

###############################################################################
#Detect a possible SMTP attack (Selective)
#As same as above procedure for normal check
###############################################################################

if [ "$CHK_possible_SMTP_attack" = "yes" ];then
	$GREPPATH "possible SMTP attack" $AUTHLOG > $TMP/"$NOW"_fail-smtp.txt

	$TOUCHPATH $TMP/"$PREV"_fail-smtp.txt

	$DIFFPATH $TMP/"$NOW"_fail-smtp.txt $TMP/"$PREV"_fail-smtp.txt \
	 | $GREPPATH '^<' > $TMP/diff_raw-smtp.txt

	NONE_STATUS_SMTP=`$GREPPATH -c $COUNT_KEY $TMP/diff_raw-smtp.txt`
else
	NONE_STATUS_SMTP="0"
fi

###############################################################################
# if diff is null, skip all process and exit
###############################################################################

if [ "$NONE_STATUS" = "0" ];then
	if [ "$NONE_STATUS_RESOLV" = "0" ];then
		if [ "$NONE_STATUS_MAP" = "0" ];then
			if [ "$NONE_STATUS_MAXAUTH" = "0" ];then
				if [ "$NONE_STATUS_MAXAUTH_INVALID" = "0" ];then
					if [ "$NONE_STATUS_SMTP" = "0" ];then
						$TOUCHPATH $TMP/"$NOW_HOUR"-summary-hour_count_list.txt
						$TOUCHPATH $TMP/count_list.txt
						$TOUCHPATH $TMP/count_cmd.sh
						$TOUCHPATH $TMP/min_ipfw_add_cmd.txt
						$TOUCHPATH $TMP/min_ipfw_add_cmd_prev.txt
						$TOUCHPATH $TMP/$IPFW_FILE
						$TOUCHPATH $TMP/hour_ipfw_add_cmd.txt
						$TOUCHPATH $TMP/hour_ipfw_add_cmd_prev.txt
						$TOUCHPATH $TMP/"$NOW_HOUR"-hour_count_list.txt
						rm -f $TMP/"$PREV_HOUR"*
						rm -f $TMP/$LOCKFILE
						exit 2
					fi
				fi
			fi
		fi
	fi
fi

###############################################################################
#Exec for attack suddenly
###############################################################################

###############################################################################
# For IP resolv
###############################################################################

if [ "$NONE_STATUS_RESOLV" != "0" ];then
	$TOUCHPATH $TMP/min_ipfw_add_cmd-resolv.txt
	cp -p $TMP/min_ipfw_add_cmd-resolv.txt $TMP/min_ipfw_add_cmd_prev-resolv.txt

	$CATPATH $TMP/"$NOW"_fail-resolv.txt|$AWKPATH '{print $12}' \
	 | $AWKPATH -F"\]" '{print $1}' \
 	 | $AWKPATH -F'\[' '{print $2}' > $TMP/count_list-resolv.txt

	$SORTPATH -u $TMP/count_list-resolv.txt >$TMP/count_list-resolv.sort.txt
        cp -p $TMP/count_list-resolv.sort.txt $TMP/count_list-resolv.txt
        rm -f $TMP/count_list-resolv.sort.txt

	$GREPPATH -F -v -f $TMP/$IPFW_FILE $TMP/count_list-resolv.txt \
	 | $AWKPATH -v IPFW_NUM=`echo $IPFW_NUM` -v IF_NAME=`echo $IF_NAME` \
	 -v PORT=`echo $PORT` -v IPFWPATH=`echo $IPFWPATH` \
	'{ print IPFWPATH" add "IPFW_NUM" deny tcp from "$1"/24 to any "PORT" via "IF_NAME}' \
	 > $TMP/min_ipfw_add_cmd-resolv.txt

	$DIFFPATH $TMP/min_ipfw_add_cmd_prev-resolv.txt $TMP/min_ipfw_add_cmd-resolv.txt \
	 | $GREPPATH '^>'

	if [ "$?" = "0" ]; then
        	$DATEPATH >> $TMP/defend-log
      		$DATEPATH >> $TMP/defend-log.time
       		$SHPATH $TMP/min_ipfw_add_cmd-resolv.txt >> $TMP/defend-log

		$AWKPATH '{print $7}' $TMP/min_ipfw_add_cmd-resolv.txt \
		 | $AWKPATH -v LOOKUP=`echo $LOOKUP` -F/ \
		'{print LOOKUP" -x "$1}' > $TMP/defend-name-log-resolv.cmd

	 	$CATPATH $TMP/min_ipfw_add_cmd-resolv.txt > $TMP/min_mailbody-resolv.txt

		$SHPATH $TMP/defend-name-log-resolv.cmd \
		 | $SEDPATH s/\*/_/g \
		 | $GREPPATH -v ";" \
		 | $AWKPATH '{if ($3 == "IN" && $4 == "PTR") {QNAME=$5; print "Name: "QNAME"\n"}}' \
		 >> $TMP/min_mailbody-resolv.txt

		echo "by POSSIBLE BREAK-IN ATTEMPT ip-resolv" >> $TMP/min_mailbody-resolv.txt
		$MAILPATH -s "SSH attack detected by minutes" $MAILTO < $TMP/min_mailbody-resolv.txt
### to keep when reboot ###
		$CATPATH $TMP/min_ipfw_add_cmd-resolv.txt >> $TMP/total_min_ipfw_add_cmd.txt
### check for double ###
		$GREPPATH -F -v -f $TMP/$IPFW_FILE $TMP/count_list-resolv.txt \
		 >> $TMP/$IPFW_FILE
	fi
fi

###############################################################################
# For IP reverse map
###############################################################################

if [ "$NONE_STATUS_MAP" != "0" ];then
	$TOUCHPATH $TMP/min_ipfw_add_cmd-map.txt
	cp -p $TMP/min_ipfw_add_cmd-map.txt $TMP/min_ipfw_add_cmd_prev-map.txt

	$CATPATH $TMP/"$NOW"_fail-map.txt|$AWKPATH '{print $7}' \
	 > $TMP/count_list-map.txt

	$SORTPATH -u $TMP/count_list-map.txt >$TMP/count_list-map.sort.txt
        cp -p $TMP/count_list-map.sort.txt $TMP/count_list-map.txt
        rm -f $TMP/count_list-map.sort.txt

	$GREPPATH -F -v -f $TMP/$IPFW_FILE $TMP/count_list-map.txt \
	 | $AWKPATH -v IPFW_NUM=`echo $IPFW_NUM` -v IF_NAME=`echo $IF_NAME` \
	 -v PORT=`echo $PORT` -v IPFWPATH=`echo $IPFWPATH` \
	'{ print IPFWPATH" add "IPFW_NUM" deny tcp from "$1"/24 to any "PORT" via "IF_NAME}' \
	 > $TMP/min_ipfw_add_cmd-map.txt

	$DIFFPATH $TMP/min_ipfw_add_cmd_prev-map.txt $TMP/min_ipfw_add_cmd-map.txt \
	 | $GREPPATH '^>'

	if [ "$?" = "0" ]; then
        	$DATEPATH >> $TMP/defend-log
      		$DATEPATH >> $TMP/defend-log.time
       		$SHPATH $TMP/min_ipfw_add_cmd-map.txt >> $TMP/defend-log

		$AWKPATH '{print $7}' $TMP/min_ipfw_add_cmd-map.txt \
		 | $AWKPATH -v LOOKUP=`echo $LOOKUP` -F/ '{print LOOKUP" -x "$1}' \
		 > $TMP/defend-name-log-map.cmd

	 	$CATPATH $TMP/min_ipfw_add_cmd-map.txt > $TMP/min_mailbody-map.txt

		$SHPATH $TMP/defend-name-log-map.cmd \
		 | $SEDPATH s/\*/_/g \
		 | $GREPPATH -v ";" \
		 | $AWKPATH '{if ($3 == "IN" && $4 == "PTR") {QNAME=$5; print "Name: "QNAME"\n"}}' \
		 >> $TMP/min_mailbody-map.txt

		echo "by POSSIBLE BREAK-IN ATTEMPT ip-reverse-map" >> $TMP/min_mailbody-map.txt
		$MAILPATH -s "SSH attack detected by minutes" $MAILTO < $TMP/min_mailbody-map.txt
### to keep when reboot ###
		$CATPATH $TMP/min_ipfw_add_cmd-map.txt >> $TMP/total_min_ipfw_add_cmd.txt
### check for double ###
		$GREPPATH -F -v -f $TMP/$IPFW_FILE $TMP/count_list-map.txt \
		 >> $TMP/$IPFW_FILE
	fi
fi

###############################################################################
# For maxauth
###############################################################################

if [ "$NONE_STATUS_MAXAUTH" != "0" ];then
	$TOUCHPATH $TMP/min_ipfw_add_cmd-maxauth.txt
	cp -p $TMP/min_ipfw_add_cmd-maxauth.txt $TMP/min_ipfw_add_cmd_prev-maxauth.txt

	$CATPATH $TMP/"$NOW"_fail-maxauth.txt|$AWKPATH '{print $14}' \
	 > $TMP/count_list-maxauth.txt

	$SORTPATH -u $TMP/count_list-maxauth.txt >$TMP/count_list-maxauth.sort.txt
        cp -p $TMP/count_list-maxauth.sort.txt $TMP/count_list-maxauth.txt
        rm -f $TMP/count_list-maxauth.sort.txt

	$GREPPATH -F -v -f $TMP/$IPFW_FILE $TMP/count_list-maxauth.txt \
	 | $AWKPATH -v IPFW_NUM=`echo $IPFW_NUM` -v IF_NAME=`echo $IF_NAME` \
	 -v PORT=`echo $PORT` -v IPFWPATH=`echo $IPFWPATH` \
	'{ print IPFWPATH" add "IPFW_NUM" deny tcp from "$1"/24 to any "PORT" via "IF_NAME}' \
	 > $TMP/min_ipfw_add_cmd-maxauth.txt

	$DIFFPATH $TMP/min_ipfw_add_cmd_prev-maxauth.txt $TMP/min_ipfw_add_cmd-maxauth.txt \
	 | $GREPPATH '^>'

	if [ "$?" = "0" ]; then
        	$DATEPATH >> $TMP/defend-log
      		$DATEPATH >> $TMP/defend-log.time
       		$SHPATH $TMP/min_ipfw_add_cmd-maxauth.txt >> $TMP/defend-log

		$AWKPATH '{print $7}' $TMP/min_ipfw_add_cmd-maxauth.txt \
		 | $AWKPATH -v LOOKUP=`echo $LOOKUP` -F/ '{print LOOKUP" -x "$1}' \
		 > $TMP/defend-name-log-maxauth.cmd

	 	$CATPATH $TMP/min_ipfw_add_cmd-maxauth.txt > $TMP/min_mailbody-maxauth.txt

		$SHPATH $TMP/defend-name-log-maxauth.cmd \
		 | $SEDPATH s/\*/_/g \
		 | $GREPPATH -v ";" \
		 | $AWKPATH '{if ($3 == "IN" && $4 == "PTR") {QNAME=$5; print "Name: "QNAME"\n"}}' \
		 >> $TMP/min_mailbody-maxauth.txt

		echo "by MAX AUTH exceeded" >> $TMP/min_mailbody-maxauth.txt
		$MAILPATH -s "SSH attack detected by minutes" $MAILTO < $TMP/min_mailbody-maxauth.txt
### to keep when reboot ###
		$CATPATH $TMP/min_ipfw_add_cmd-maxauth.txt >> $TMP/total_min_ipfw_add_cmd.txt
### check for double ###
		$GREPPATH -F -v -f $TMP/$IPFW_FILE $TMP/count_list-maxauth.txt \
		 >> $TMP/$IPFW_FILE
	fi
fi

###############################################################################
# For maxauth-invalid
###############################################################################

if [ "$NONE_STATUS_MAXAUTH_INVALID" != "0" ];then
	$TOUCHPATH $TMP/min_ipfw_add_cmd-maxauth-invalid.txt
	cp -p $TMP/min_ipfw_add_cmd-maxauth-invalid.txt $TMP/min_ipfw_add_cmd_prev-maxauth-invalid.txt

	$CATPATH $TMP/"$NOW"_fail-maxauth-invalid.txt|$AWKPATH '{print $16}' \
	 > $TMP/count_list-maxauth-invalid.txt

	$SORTPATH -u $TMP/count_list-maxauth-invalid.txt >$TMP/count_list-maxauth-invalid.sort.txt
        cp -p $TMP/count_list-maxauth-invalid.sort.txt $TMP/count_list-maxauth-invalid.txt
        rm -f $TMP/count_list-maxauth-invalid.sort.txt

	$GREPPATH -F -v -f $TMP/$IPFW_FILE $TMP/count_list-maxauth-invalid.txt \
	 | $AWKPATH -v IPFW_NUM=`echo $IPFW_NUM` -v IF_NAME=`echo $IF_NAME` \
	 -v PORT=`echo $PORT` -v IPFWPATH=`echo $IPFWPATH` \
	'{ print IPFWPATH" add "IPFW_NUM" deny tcp from "$1"/24 to any "PORT" via "IF_NAME}' \
	 > $TMP/min_ipfw_add_cmd-maxauth-invalid.txt

	$DIFFPATH $TMP/min_ipfw_add_cmd_prev-maxauth-invalid.txt $TMP/min_ipfw_add_cmd-maxauth-invalid.txt \
	 | $GREPPATH '^>'

	if [ "$?" = "0" ]; then
        	$DATEPATH >> $TMP/defend-log
      		$DATEPATH >> $TMP/defend-log.time
       		$SHPATH $TMP/min_ipfw_add_cmd-maxauth-invalid.txt >> $TMP/defend-log

		$AWKPATH '{print $7}' $TMP/min_ipfw_add_cmd-maxauth-invalid.txt \
		 | $AWKPATH -v LOOKUP=`echo $LOOKUP` -F/ '{print LOOKUP" -x "$1}' \
		 > $TMP/defend-name-log-maxauth-invalid.cmd

	 	$CATPATH $TMP/min_ipfw_add_cmd-maxauth-invalid.txt > $TMP/min_mailbody-maxauth-invalid.txt

		$SHPATH $TMP/defend-name-log-maxauth-invalid.cmd \
		 | $SEDPATH s/\*/_/g \
		 | $GREPPATH -v ";" \
		 | $AWKPATH '{if ($3 == "IN" && $4 == "PTR") {QNAME=$5; print "Name: "QNAME"\n"}}' \
		 >> $TMP/min_mailbody-maxauth-invalid.txt

		echo "by MAX AUTH-invalid-user exceeded" >> $TMP/min_mailbody-maxauth-invalid.txt
		$MAILPATH -s "SSH attack detected by minutes" $MAILTO < $TMP/min_mailbody-maxauth-invalid.txt
### to keep when reboot ###
		$CATPATH $TMP/min_ipfw_add_cmd-maxauth-invalid.txt >> $TMP/total_min_ipfw_add_cmd.txt
### check for double ###
		$GREPPATH -F -v -f $TMP/$IPFW_FILE $TMP/count_list-maxauth-invalid.txt \
		 >> $TMP/$IPFW_FILE
	fi
fi

###############################################################################
# For possible SMTP attack
###############################################################################

if [ "$NONE_STATUS_SMTP" != "0" ];then
	$TOUCHPATH $TMP/min_ipfw_add_cmd-smtp.txt
	cp -p $TMP/min_ipfw_add_cmd-smtp.txt $TMP/min_ipfw_add_cmd_prev-smtp.txt

	$CATPATH $TMP/"$NOW"_fail-smtp.txt|$AWKPATH -F"\\\[\\|\\\]" '{print $4}' \
	 > $TMP/count_list-smtp.txt

	$SORTPATH -u $TMP/count_list-smtp.txt >$TMP/count_list-attack.smtp.txt
	cp -p $TMP/count_list-attack.smtp.txt $TMP/count_list-smtp.txt
	rm -f $TMP/count_list-attack.smtp.txt

	$GREPPATH -F -v -f $TMP/$IPFW_FILE $TMP/count_list-smtp.txt \
	 | $AWKPATH -v IPFW_NUM=`echo $IPFW_NUM` -v IF_NAME=`echo $IF_NAME` \
	 -v PORT=`echo $PORT` -v IPFWPATH=`echo $IPFWPATH` \
	'{ print IPFWPATH" add "IPFW_NUM" deny tcp from "$1"/24 to any "PORT" via "IF_NAME}' \
	 > $TMP/min_ipfw_add_cmd-smtp.txt

	$DIFFPATH $TMP/min_ipfw_add_cmd_prev-smtp.txt $TMP/min_ipfw_add_cmd-smtp.txt \
	 | $GREPPATH '^>'

	if [ "$?" = "0" ]; then
		$DATEPATH >> $TMP/defend-log
		$DATEPATH >> $TMP/defend-log.time
		$SHPATH $TMP/min_ipfw_add_cmd-smtp.txt >> $TMP/defend-log

		$AWKPATH '{print $7}' $TMP/min_ipfw_add_cmd-smtp.txt \
		 | $AWKPATH -v LOOKUP=`echo $LOOKUP` -F/ '{print LOOKUP" -x "$1}' \
		 > $TMP/defend-name-log-smtp.cmd

		$CATPATH $TMP/min_ipfw_add_cmd-smtp.txt > $TMP/min_mailbody-smtp.txt

		$SHPATH $TMP/defend-name-log-smtp.cmd \
		 | $SEDPATH s/\*/_/g \
		 | $GREPPATH -v ";" \
		 | $AWKPATH '{if ($3 == "IN" && $4 == "PTR") {QNAME=$5; print "Name: "QNAME"\n"}}' \
		 >> $TMP/min_mailbody-smtp.txt

		echo "by possible SMTP attack" >> $TMP/min_mailbody-smtp.txt
		$MAILPATH -s "possible SMTP attack detected by minutes" $MAILTO < $TMP/min_mailbody-smtp.txt
### to keep when reboot ###
		$CATPATH $TMP/min_ipfw_add_cmd-smtp.txt >> $TMP/total_min_ipfw_add_cmd.txt
### check for double ###
		$GREPPATH -F -v -f $TMP/$IPFW_FILE $TMP/count_list-smtp.txt \
		 >> $TMP/$IPFW_FILE
	fi
fi

###############################################################################
#Count per min
###############################################################################

if [ "$IP_STYLE" == "1" ];then
	$SORTPATH -u +10 $TMP/diff_raw.txt \
	|$AWKPATH -v TMP=`echo $TMP` '{print "echo -n \""$11" \"; grep -c "$11" "TMP"/diff_raw.txt"}' \
	> $TMP/count_cmd.sh
elif [ "$IP_STYLE" == "2" ];then
	$SORTPATH -u +8 $TMP/diff_raw.txt \
	|$AWKPATH -F"\\\[\\|\\\]" '{print $4}' \
	|$AWKPATH -v TMP=`echo $TMP` '{print "echo -n \""$1" \"; grep -c "$1" "TMP"/diff_raw.txt"}' \
	> $TMP/count_cmd.sh
else
	echo "Format definition error. Check IP_STYLE value!"
	exit 3
fi

$SHPATH $TMP/count_cmd.sh > $TMP/count_list.txt

###############################################################################
#Count per hour
###############################################################################

$CATPATH $TMP/count_list.txt >>$TMP/"$NOW_HOUR"-hour_count_list.txt

$SORTPATH +1 $TMP/"$NOW_HOUR"-hour_count_list.txt \
 | $AWKPATH '{if ( $1 == PREV ) { ADDR = $1; COUNT = COUNT + $2; PREV = ADDR;} \
 else { ADDR = $1; print PREV" "COUNT; COUNT = $2 ; PREV = ADDR;} next} END {print $1" "COUNT}' \
 | $AWKPATH '{if ($1 != NULL) {print $0}}' >$TMP/"$NOW_HOUR"-summary-hour_count_list.txt

###############################################################################
#Process with threthold
###############################################################################

$TOUCHPATH $TMP/$IPFW_FILE

### minutes ###
$TOUCHPATH $TMP/min_ipfw_add_cmd.txt
cp -p $TMP/min_ipfw_add_cmd.txt $TMP/min_ipfw_add_cmd_prev.txt

$CATPATH $TMP/count_list.txt | $AWKPATH '{print $1}' \
 > $TMP/count_list-addr.txt

$GREPPATH -F -v -f $TMP/$IPFW_FILE $TMP/count_list-addr.txt \
 > $TMP/count_list-new.txt

$GREPPATH -f $TMP/count_list-new.txt $TMP/count_list.txt \
 | $AWKPATH -v OK_PER_MIN=`echo $OK_PER_MIN` -v IPFW_NUM=`echo $IPFW_NUM` \
 -v IF_NAME=`echo $IF_NAME` -v PORT=`echo $PORT` -v IPFWPATH=`echo $IPFWPATH` \
 '{ if ( $2 > OK_PER_MIN ) \
 {print IPFWPATH" add "IPFW_NUM" deny tcp from "$1"/24 to any "PORT" via "IF_NAME}}' \
 > $TMP/min_ipfw_add_cmd.txt

### to keep when reboot ###
$CATPATH $TMP/min_ipfw_add_cmd.txt >> $TMP/total_min_ipfw_add_cmd.txt

### check for double ###
$GREPPATH -f $TMP/count_list-new.txt $TMP/count_list.txt \
 | $AWKPATH -v OK_PER_MIN=`echo $OK_PER_MIN` '{ if ( $2 > OK_PER_MIN ) {print $1}}' \
 >> $TMP/$IPFW_FILE

### hour ###
$TOUCHPATH $TMP/hour_ipfw_add_cmd.txt
cp -p $TMP/hour_ipfw_add_cmd.txt $TMP/hour_ipfw_add_cmd_prev.txt

$CATPATH $TMP/"$NOW_HOUR"-summary-hour_count_list.txt | $AWKPATH '{print $1}' \
 > $TMP/"$NOW_HOUR"-summary-hour_count_list-addr.txt

$GREPPATH -F -v -f $TMP/$IPFW_FILE $TMP/"$NOW_HOUR"-summary-hour_count_list-addr.txt \
 > $TMP/"$NOW_HOUR"-summary-hour_count_list-new.txt

$GREPPATH -f $TMP/"$NOW_HOUR"-summary-hour_count_list-new.txt \
 $TMP/"$NOW_HOUR"-summary-hour_count_list.txt \
 | $AWKPATH -v OK_PER_HOUR=`echo $OK_PER_HOUR` -v IPFW_NUM=`echo $IPFW_NUM` \
 -v IF_NAME=`echo $IF_NAME` -v PORT=`echo $PORT` -v IPFWPATH=`echo $IPFWPATH` \
 '{ if ( $2 > OK_PER_HOUR ) \
 {print IPFWPATH" add "IPFW_NUM" deny tcp from "$1"/24 to any "PORT" via "IF_NAME}}' \
 > $TMP/hour_ipfw_add_cmd.txt

### to keep when reboot ###
$CATPATH $TMP/hour_ipfw_add_cmd.txt >> $TMP/total_hour_ipfw_add_cmd.txt

### check for double ###
$GREPPATH -f $TMP/"$NOW_HOUR"-summary-hour_count_list-new.txt \
 $TMP/"$NOW_HOUR"-summary-hour_count_list.txt \
 | $AWKPATH -v OK_PER_HOUR=`echo $OK_PER_HOUR` '{ if ( $2 > OK_PER_HOUR ) {print $1}}' \
 >> $TMP/$IPFW_FILE

###############################################################################
# Execute IPFW
###############################################################################

$DIFFPATH $TMP/min_ipfw_add_cmd_prev.txt $TMP/min_ipfw_add_cmd.txt \
 | $GREPPATH '^>'

if [ "$?" = "0" ]; then
	$DATEPATH >> $TMP/defend-log
	$DATEPATH >> $TMP/defend-log.time
	$SHPATH $TMP/min_ipfw_add_cmd.txt >> $TMP/defend-log

	$AWKPATH '{print $7}' $TMP/min_ipfw_add_cmd.txt\
	 | $AWKPATH -v LOOKUP=`echo $LOOKUP` -F/ '{print LOOKUP" -x "$1}' \
	 > $TMP/defend-name-log.cmd

	$CATPATH $TMP/min_ipfw_add_cmd.txt > $TMP/min_mailbody.txt

	$SHPATH $TMP/defend-name-log.cmd \
	 | $SEDPATH s/\*/_/g \
	 | $GREPPATH -v ";" \
	 | $AWKPATH '{if ($3 == "IN" && $4 == "PTR") {QNAME=$5; print "Name: "QNAME"\n"}}' \
	 >> $TMP/min_mailbody.txt

	$MAILPATH -s "$MAIL_SUBJECT_MIN" $MAILTO < $TMP/min_mailbody.txt
fi

$DIFFPATH $TMP/hour_ipfw_add_cmd_prev.txt $TMP/hour_ipfw_add_cmd.txt \
 | $GREPPATH '^>'

if [ "$?" = "0" ]; then
	$DATEPATH >> $TMP/defend-log
	$DATEPATH >> $TMP/defend-log.time
	$SHPATH $TMP/hour_ipfw_add_cmd.txt >> $TMP/defend-log
	$MAILPATH -s "$MAIL_SUBJECT_HOUR" $MAILTO < $TMP/hour_ipfw_add_cmd.txt
fi

###############################################################################
#Delete previous files
###############################################################################

rm -f $TMP/"$PREV_HOUR"*
rm -f $TMP/$LOCKFILE

exit 0
