Skip to content

Instantly share code, notes, and snippets.

@nickfox-taterli
Created March 10, 2018 08:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save nickfox-taterli/ac7c443c06f9afa2e1e7de71275342fe to your computer and use it in GitHub Desktop.
Save nickfox-taterli/ac7c443c06f9afa2e1e7de71275342fe to your computer and use it in GitHub Desktop.
auto ip deny script
#!/bin/bash
#检测时间
SLEEP_TIME=10
#禁用阈值
NO_OF_CONNECTIONS=50
#禁用时长
BAN_PERIOD=300
#白名单
IGNORE_IP_LIST=/root/autodeny/allow_ip.txt
#排除的端口
IGNORE_PORT=
write_log()
{
logout=""
for((i=2;i<=$#;i++)); do
j=${!i}
logout="${logout} $j "
done
echo "[`date "+%Y-%m-%d %H:%M:%S"`][$1]: ${logout}" | tee -ai /root/autodeny/debug.log
}
banip()
{
LOG_FILE=/root/autodeny/autodeny_$(date +%Y-%m-%d).log
if [[ ! -z $1 ]]
then
iptables -nvL | grep DROP | grep $1 >/dev/null
if [[ 0 -ne $? ]]
then
iptables -I INPUT -s $1 -j DROP && \
write_log INFO "$1 Was Baned successfully."
return 0
fi
fi
}
unbanip()
{
LOG_FILE=/root/autodeny/autodeny_$(date +%Y-%m-%d).log
if [[ -z $1 ]]
then
UNBAN_SCRIPT=$(mktemp /tmp/unban.XXXXXXXX)
cat << EOF >$UNBAN_SCRIPT
#!/bin/sh
sleep $BAN_PERIOD
while read line
do
iptables -D INPUT -s \$line -j DROP
echo "[\`date "+%Y-%m-%d %H:%M:%S"\`][INFO]: \$line is Unbaned successfully." | tee -ai $LOG_FILE
done < $BANNED_IP_LIST
rm -f $BANNED_IP_LIST $BANNED_IP_MAIL $BAD_IP_LIST $UNBAN_SCRIPT
EOF
. $UNBAN_SCRIPT &
else
iptables -nvL | grep DROP | grep $1 >/dev/null
if [[ 0 -eq $? ]]
then
iptables -D INPUT -s $1 -j DROP
write_log INFO "$1 is Unbaned successfully."
else
write_log DEBUG "$1 is not found in iptables list, please check..."
fi
fi
}
check_ip()
{
#check_ip if in the $IGNORE_IP_LIST
grep -q $CURR_LINE_IP $IGNORE_IP_LIST && return 0
#check ip belongs to IP subnet
result=$(grep '/' $IGNORE_IP_LIST | awk -F'[./]' -v ip=$1 '
{for (i=1;i<=int($NF/8);i++){a=a$i"."}
if (index(ip, a)==1){split( ip, A, ".");if (A[4]<2^(8-$NF%8)) print "hit"}
a=""}' )
if [[ "$result" = "hit" ]]
then
return 0
else
return 1
fi
}
show_stats()
{
netstat -ntu | \
egrep -v "${IGNORE_PORT}LISTEN|127.0.0.1" | \
awk -F"[ ]+|[:]" '{print $6}' | \
sed -n '/[0-9]/p' | sort | uniq -c | sort -rn
}
cc_check()
{
TMP_PREFIX='/tmp/autodeny'
TMP_FILE="mktemp $TMP_PREFIX.XXXXXXXX"
BANNED_IP_MAIL=$($TMP_FILE)
BANNED_IP_LIST=$($TMP_FILE)
LOG_FILE=/root/autodeny/autodeny_$(date +%Y-%m-%d).log
echo "Banned the following ip addresses on `date`" > $BANNED_IP_MAIL
echo >> $BANNED_IP_MAIL
BAD_IP_LIST=$($TMP_FILE)
show_stats | awk -v str=$NO_OF_CONNECTIONS '{if ($1>=str){print $0}}' > $BAD_IP_LIST
IP_BAN_NOW=0
while read line; do
CURR_LINE_CONN=$(echo $line | cut -d" " -f1)
CURR_LINE_IP=$(echo $line | cut -d" " -f2)
check_ip $CURR_LINE_IP
if [ $? -eq 0 ]; then
continue
fi
banip $CURR_LINE_IP
if [ $? -eq 1 ]; then
continue
else
let IP_BAN_NOW+=1
fi
CURR_LINE_IP_LOCATION=$(curl -s ip.cn/$CURR_LINE_IP)
write_log INFO "Banned $CURR_LINE_IP ($CURR_LINE_IP_LOCATION) with $CURR_LINE_CONN connections" >> $BANNED_IP_MAIL
echo $CURR_LINE_IP >> $BANNED_IP_LIST
#echo $CURR_LINE_IP >> $IGNORE_IP_LIST
done < $BAD_IP_LIST
if [[ $IP_BAN_NOW -ge 1 ]]; then
dt=$(date)
if [[ $BAN_PERIOD -gt 0 ]];then
unbanip
fi
else
rm -f $BANNED_IP_LIST $BANNED_IP_MAIL $BAD_IP_LIST
fi
}
while true
do
cc_check
sleep $SLEEP_TIME
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment