---
# System prepended metadata

title: '[網路安全系列] CCkiller 安裝'
tags: [cc]

---

# [網路安全系列] CCkiller 安裝
###### tags: `cc`

## :beginner: Product Info

- 功能申明
  分享之前我必須先申明一下，眾所周知，DDoS攻擊指的是分佈式拒絕服務。而CC攻擊只是DDoS攻擊的一種，本文所闡述的CC攻擊，指的是單個IP達到我們設定好的閾值並發請求，而非海量IP的低並發攻擊！對於個人低配服務器，除了使用CDN來防護，至少我是沒有想到如何抵擋海量IP攻擊的！因為每個IP都模擬正常的用戶瀏覽器請求，並不會觸發防禦閾值，同時來1000個，甚至上萬個，個人低配服務器的帶寬在第一時間就會被佔滿，就無法繼續提供服務了。


  當然，用腳本也是無法防禦DDoS大流量攻擊的，因為所有機房的防禦帶寬是有限的，當攻擊的流量超過了機房的防禦帶寬，要么機房把你的服務器IP拉黑洞，要么就一起死。因此，如果你的服務器正遭受大流量攻擊，比如幾十G上百G，一般機房或CDN節點都是扛不住的，腳本也無能為力了，趕緊換高防服務器吧！

- 功能介紹 
  通過以上申明，也就大致給CCKiller一個定位：CCKiller是用於個人低配服務器的輕量級CC攻擊防禦，可以抵擋單個IP產生的高並發攻擊。
  目前設計的功能特性如下：
    - [ ] 秒級檢查
    - [ ] 拉黑時長
    - [ ] 並發閾值
    - [ ] 郵件發送這邊有設定tg告警
    - [ ] 並發顯示
    - [ ] 手動拉黑

### :small_blue_diamond: 詳細說明
:::warning
①、秒級檢查


很多人寫的防禦腳本都是使用了Linux系統的計劃任務crontab來定時檢查的。而crontab的最細顆粒是1分鐘，也就是說腳本最快也只能1分鐘檢查一次。對於一些強迫症來說就會很不爽。

所以，我還是按照以前分享的思路，利用while循環實現秒級檢查，實現更細的顆粒。當然，CCKiller更是被我寫成了系統服務，更加靈活穩定。

②、拉黑時長


CCKiller可以設置拉黑時長，默認為10分鐘。當發現有惡意請求時，會自動拉黑目標IP，並在拉黑時長結束後自動釋放，這個功能算是對我之前寫的腳本的一個大的改進。

③、並發閾值


CCKiller 可以設定單個IP的最高請求數，如果某個IP同時請求數超過了設定的閾值，就會被暫時拉黑一段時間。


④、郵件發送


這個功能沒啥好說的，意義並不大。而且發送成功率和服務器的環境也有很大關係。


⑤、並發顯示


安裝後，直接運行cckiller會列出當前系統的請求排行，可以清晰的看到當前請求IP和並發數。使用-s參數還可以繼續定制需求，比如cckiller -s 10 就能顯示當前並發數排行前10名的IP。

⑥、手動拉黑

支持手動拉黑，執行後會立即檢查，將並發請求超過n的IP拉黑一段時間，比如cckiller -k 100 就會將目前超過100個請求的IP拉黑一段時間，如果沒有則不會執行任何拉黑操作。

:::

## :triangular_flag_on_post: 工具安裝

## :feet: 在線安裝
由於我可能經常會更新一些功能，或修復一些BUG，所以僅提供在線安裝，以保證腳本是最新的。
安裝非常簡單，執行如下命令就能進入配置步驟了：

```shell=
curl -ko install.sh https://zhang.ge/wp-content/uploads/files/cckiller/install.sh?ver=1.0.8 && sh install.sh -i
```
默認配置如下：
:::success
The Time interval : 20 s #每20s檢查一次系統請求情況
The Forbidden Time: 600 s #拉黑時長設為10分鐘
Adminstrator Email: root@localhost #郵件對象設置為root@localhost（即關閉郵件發送）
Connections Allow: 100 #單個IP並發限制為100
:::

如果不符合你的需求，你可以使用ctrl + c 組合鍵終止腳本，或者先繼續安裝，因為工具設計了配置修改的功能，所以無需著急。

## :feet: 安裝腳本  install.sh
```shell=
#!/bin/sh
###################################################################
#  CCKiller version 1.0.8 Author: Jager <ge@zhang.ge>          #
#  For more information please visit https://zhang.ge/5066.html#
#-----------------------------------------------------------------#
#  Copyright ©2015-2019 zhang.ge. All rights reserved.              #
###################################################################
conf_env()
{
    export PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
    export DKName=CCKiller
    export Base_Dir=/usr/local/cckiller
    export DKVer=1.0.8
    clear
}

check_env()
{
    which sendmail || yum install -y sendmail
    mailx -V || yum install -y mailx
    test -x $0 || chmod +x $0
    #Centos 7 install iptables
    if [ -n "`grep 'Aliyun Linux release' /etc/issue`" -o -e /etc/redhat-release ];then
        which iptables >/dev/null
        if [ -n "`grep ' 7\.' /etc/redhat-release`" -a $? -ne 0 ] ; then
            yum -y install iptables-services
            systemctl mask firewalld.service
            systemctl enable iptables.service
        fi
    fi
    /etc/init.d/iptables start > /dev/null 2>&1
}

header()
{
printf "
###################################################################
#  $DKName version $DKVer Author: Jager <ge@zhang.ge>               #
#  For more information please visit https://zhang.ge/5066.html#
#-----------------------------------------------------------------#
#  Copyright @2015-2019 zhang.ge. All rights reserved.              #
###################################################################

"
}

showhelp()
{
    conf_env
	header
	echo 'Usage: cckiller [OPTIONS]'
	echo
	echo 'OPTIONS:'
	echo "-h | --help : Show help of $DKName"
	echo "-u | --update : update Check for $DKName"
	echo "-c | --config : Edit The configure of $DKName again"
	echo "-i | --install : install $DKName version $DKVer to This System"
	echo "-U | --uninstall : Uninstall cckiller from This System"
	echo
}

get_char()
{
    SAVEDSTTY=`stty -g`
    stty -echo
    stty cbreak
    dd if=/dev/tty bs=1 count=1 2> /dev/null
    stty -raw
    stty echo
    stty $SAVEDSTTY
}

Check_U()
{
    userid=$(id | awk '{print $1}' | sed -e 's/=/ /' -e 's/(/ /' -e 's/)/ /'|awk '{print $2}')
    if [[ $userid -ne 0 ]]
    then
        echo "No root permissions,Please run with root user..."
        exit
    fi
}

Update()
{
    conf_env
    curl -ko $Base_Dir/log/version.txt --connect-timeout 300 --retry 5 --retry-delay 3 https://zhangge.net/wp-content/uploads/files/cckiller/version.txt
    CONF_FILE=$(awk -F":" '/configure/ {print $2}' $Base_Dir/log/version.txt)
    
    FINAL_VER=$(awk -F":" '/version/ {print $2}' $Base_Dir/log/version.txt)
    
    if [[ -f $Base_Dir/ck.conf ]]
    then
        source $Base_Dir/ck.conf
    else
        echo "Error: Not Found $Base_Dir/ck.conf, Please install CCkiller Again."
        exit 1
    fi
    
    if [[ $DKVer != $FINAL_VER ]]
    then
        echo =============================================================================
        echo "Local Version: $DKVer"
        echo
        echo "Remote information:"
        echo
        cat $Base_Dir/log/version.txt
        echo
        echo =============================================================================
        read -p "New Version Found, Do You Want Update Now? (y/n, default y): " CHOICE
        if [[ $CHOICE == 'y' ]] || [[ $CHOICE == 'Y' ]] || [[ $CHOICE == "" ]]
        then
            clear
            Version=$FINAL_VER
            install update
        else
            echo "It‘s Skiped."
        fi
    else
        echo "Good, It's the latest versions."
    fi
}

Configure()
{
    if [[ "$1" == "config" ]] && [[ ! -d "$Base_Dir" ]]
    then
	    echo; echo; echo "Warn: CCkiller not found, Please used -i install first"
	    echo
	    exit 0
    fi
    if [[ "$1" == "default" ]]
    then
        SLEEP_TIME=20
        BAN_PERIOD=600
        EMAIL_TO=root@localhost
        NO_OF_CONNECTIONS=100
        IGNORE_PORT=
        LOG_LEVEL=INFO
        echo
        echo "You choice the default configuration:"
        echo 'Configure info,Please Review:'
        echo "======================================="
	    echo "  The Time interval : $SLEEP_TIME s"
	    echo
	    echo "  The Forbidden Time: $BAN_PERIOD s"
	    echo
	    echo "  Adminstrator Email: $EMAIL_TO"
	    echo
        echo "  Connections  Allow: $NO_OF_CONNECTIONS"
        echo 
        echo "  Ignore Port: Null                     "
        echo
        echo "  Log   Level:        $LOG_LEVEL        "
        echo "========================================"
        echo "Press any key to continue..."
    else
        echo
        read -p "Please Input The Rate(seconds) of CCkiller Check(default: 20): " SLEEP_TIME
        if [[ -z $SLEEP_TIME ]] || [[ 0 -eq $SLEEP_TIME ]] ;then
            echo "The Time interval of CCkiller Check will set default 20s"
            SLEEP_TIME=20
        fi
        echo
        read -p "Please Input the Forbidden Time(seconds) of banned IP(default: 600, if set 0 ip will banned until Restart System or iptables ): " BAN_PERIOD
        if [[ -z $BAN_PERIOD ]];then
    	    echo "The Forbidden Time will set default 600s"
    	    BAN_PERIOD=600
        fi
        echo
        read -p "Please Input the E-mail of Adminstrator(default: root@localhost): " EMAIL_TO
        if [[ -z $EMAIL_TO ]];then
    	    echo "The Adminstrator E-mail will set default root@localhost"
    	    EMAIL_TO=root@localhost
        fi
        echo
        read -p "Please Input the Maximum number of connections allowed(default 100): " NO_OF_CONNECTIONS
        if [[ -z $NO_OF_CONNECTIONS ]];then
        	echo "The Max number for connections Allowed will set default 100"
        	NO_OF_CONNECTIONS=100
        fi
        echo
        read -p "Please Input the ignore Ports of check like 21,8080,1080(default null): " IGNORE_PORT
        if [[ -z $IGNORE_PORT ]];then
        	echo "The ignore Ports of check will set default null"
        	IGNORE_PORT=
        fi
        echo
        read -p "Please Input the level of log like INFO,DEBUG,WARNING,OFF (default INFO): " LOG_LEVEL
        if [[ -z LOG_LEVEL ]];then
        	echo "The ignore Ports of check will set default INFO"
        	LOG_LEVEL=INFO
        fi
        clear
        echo
        echo 'Configure info,Please Review:'
        echo "======================================="
    	echo "  The Time interval : $SLEEP_TIME s"
    	echo
    	echo "  The Forbidden Time: $BAN_PERIOD s"
    	echo
    	echo "  Adminstrator Email: $EMAIL_TO"
    	echo
        echo "  Connections  Allow: $NO_OF_CONNECTIONS"
        echo 
        echo "  Ignore Port: $IGNORE_PORT"
        echo
        echo "  Log Level  : $LOG_LEVEL"
        echo "========================================"
        echo "Press any key to continue..."
    fi
    char=`get_char`
    mkdir -p $Base_Dir/log

cat << EOF >$Base_Dir/ck.conf
##### Paths of the script and other files
PROGDIR="$Base_Dir"
LOGDIR="$Base_Dir/log"
PROG="$Base_Dir/cckiller"
IGNORE_IP_LIST="$Base_Dir/ignore.ip.list"
IPT=$(which iptables | awk '{print $1}')
IPT_SVR="/etc/init.d/iptables"
DKName=$DKName
DKVer=$DKVer

##### Rate of running the script in proccess mode(default 20s)
SLEEP_TIME=$SLEEP_TIME

##### How many connections define a bad IP? Indicate that below.
NO_OF_CONNECTIONS=$NO_OF_CONNECTIONS

##### An email is sent to the following address when an IP is banned.
EMAIL_TO="$EMAIL_TO"

#####  The Forbidden seconds of banned IP(default:600 if set 0 ip will banned forever).
BAN_PERIOD=$BAN_PERIOD

##### The ignore Ports like 21,2121,8000 (default null)
IGNORE_PORT=$IGNORE_PORT

##### The level of log like INFO,DEBUG,WARNING,OFF (default INFO)
LOG_LEVEL=$LOG_LEVEL
EOF
    echo
    test -f /etc/init.d/cckiller && /etc/init.d/cckiller restart
    echo
    echo "Configure Completed."
}

install()
{
    if [[ -d "$Base_Dir" ]] && [[ -z $1 ]]; then
	    echo; echo; echo "Warn: cckiller is already installed, Please used -U uninstall first"
	    echo
	    exit 0
    fi
    if [[ $CONF_FILE == 'updated' ]] || [[ -z $CONF_FILE ]];then
        read -p 'Do you want to use the default configuration? (y/n): ' CHOICE
        if [[ $CHOICE == "n" ]]
        then
            Configure
        else
            Configure default
        fi
    fi
    source $Base_Dir/ck.conf
    clear
    echo; echo "Installing $DKName version ${FINAL_VER:-$DKVer} by zhang.ge"; echo
    echo; echo "Checking the operating environment..."
    check_env >/dev/null 2>&1
    echo; echo "Downloading source files..."
    curl -ko $Base_Dir/cckiller --connect-timeout 300 --retry 5 --retry-delay 3 https://zhangge.net/wp-content/uploads/files/cckiller/cckiller?ver=${FINAL_VER:-$DKVer}
    
    test -d /etc/init.d || mkdir -p /etc/init.d
    curl -ko /etc/init.d/cckiller --connect-timeout 300 --retry 5 --retry-delay 3 https://zhangge.net/wp-content/uploads/files/cckiller/cckiller_servicefile?ver${FINAL_VER:-$DKVer}
    chmod 0755 $Base_Dir/cckiller
    
    chmod 0755 /etc/init.d/cckiller
        
    chkconfig cckiller on 2>/dev/null || \
    
    test -f /etc/rc.d/rc.local && \
    echo "/etc/init.d/cckiller start" >>/etc/rc.d/rc.local
        
    ln -sf $Base_Dir/cckiller /bin/cckiller
    
    cp -f $0 $Base_Dir/ >/dev/null 2>&1
    
    if [[ -z $1 ]]
    then
        ip addr | awk -F '[ /]+' '/inet / {print $3}' | grep -v '127.0.' > $Base_Dir/ignore.ip.list
    fi
    echo "...done"
    echo
    echo
    if [[ -z $1 ]]
    then
        /etc/init.d/cckiller start
        echo
        echo "Installation has completed."
        echo
        echo "Config file is at $Base_Dir/ck.conf"
    else
        /etc/init.d/cckiller restart
        echo
        echo "Update success."
    fi
    
    echo
    echo 'Your can post comments or suggestions on https://zhang.ge/5066.html'
    echo
}

function uninstall()
{
    echo "Uninstalling cckiller..."
    echo;
    test -f /etc/init.d/cckiller && /etc/init.d/cckiller stop
    echo; echo; echo -n "Deleting script files....."
    if [ -e "$Base_Dir/cckiller" ]; then
        rm -f $Base_Dir/cckiller
	rm -f /bin/cckiller
        echo -n ".."
    fi
    if [ -d "$Base_Dir" ]; then
        rm -rf $Base_Dir
        echo -n ".."
    fi
    echo "done"
    echo; echo -n "Deleting system service....."
    if [ -e '/etc/init.d/cckiller' ]; then
        rm -f /etc/init.d/cckiller
        echo -n ".."
    fi
    echo "done"
    echo; echo "Uninstall Complete"; echo
}

conf_env

if [[ -z $1 ]];then
    showhelp
    exit
fi

header
Check_U
while [ $1 ]; do
	case $1 in
		'-h' | '--help' | '?' )
			showhelp
			exit
			;;
		'--install' | '-i' )
			install
			exit
			;;
		'--uninstall' | '-U' )
			uninstall
			exit
			;;
		'--update' | '-u' )
			Update
			exit
			;;	
		'--config' | '-c' )
			Configure config
			exit
			;;	
		* )
			showhelp
			exit
			;;
	esac
	shift
done

```


## :feet: 服務控制
:::success
安裝後，會將cckiller註冊成系統服務，這時你就可以使用service來控制cckiller了。使用標準的service定義，支持start | stop | restart | status 四個參數。所以，你可以使用service cckiller stop來停止cckiller，也可以使用service cckiller status來查看狀態。
:::

## :feet: 集成命令
:::success
成功安裝後，系統還會多出一個cckiller的命令，這個命令現有功能如下：
cckiller -h可以調出幫助信息：
:::

## :feet: 操作圖示
:::success
iptables -nvL | grep DROP 
查看被禁IP
![](https://i.imgur.com/NDenlF5.png)
設定檔預設位置 
![](https://i.imgur.com/30EsBkL.png)
狀態查詢
![](https://i.imgur.com/48EYqYE.png)
配置講解
![](https://i.imgur.com/O59UVyN.png)
安裝確認
![](https://i.imgur.com/Hj9W5jF.png)
日誌
![](https://i.imgur.com/Gqf7VHx.png)
TG告警
![](https://i.imgur.com/KNeInLE.png)
:::

## :feet: CCkiller (配置添加TG告警)
```shell=
#!/bin/sh
###################################################################
#  CCKiller version 1.0.8 Author: Jager <im@zhang.ge>             #
#  For more information please visit https://zhang.ge/5066.html#
#-----------------------------------------------------------------#
#  Copyright ©2015-2019 zhang.ge. All rights reserved.      #
###################################################################

#tg發送指令
send_tg(){
   curl "https://api.telegram.org/bot1033770595:AAH6-wqoOw37Z2A5LQruDQTt-c9cmcoLdtA/sendMessage?chat_id=-651507342&text=$1"
}
#机器hostname
ip=`hostname`

header()
{
        echo "CCKiller version 1.0.8 Author: Jager <ge@zhang.ge>"
        echo "Copyright ©2015-2019 zhang.ge. All rights reserved. "
}
load_conf()
{
    CONF="/usr/local/cckiller/ck.conf"
    if [[ -f "$CONF" ]]; then
        source $CONF
        if [[ ! -z $IGNORE_PORT ]]
        then
            IGNORE_PORT=\:\($(echo $IGNORE_PORT|tr ',' '|')\)\|
        fi
    else
        header
        echo "$CONF not found."
        exit 1
    fi
}

#write_log INFO "Messages" 
write_log()
{
    LOG_FILE=$LOGDIR/cckiller_$(date +%Y-%m-%d).log
    
    logout=""
    for((i=2;i<=$#;i++)); do 
        j=${!i}
        logout="${logout} $j "
    done
        elif [[ $LOG_LEVEL == "DEBUG" ]];then
        echo "[`date "+%Y-%m-%d %H:%M:%S"`][$1]: ${logout}" | tee -ai $LOG_FILE 
    
    else
        echo "[`date "+%Y-%m-%d %H:%M:%S"`][$1]: ${logout}"
    
    fi
    
}

showhelp()
{
        header
        echo
        echo 'Usage: cckiller [OPTIONS] [N]'
        echo 'N : number of tcp/udp     connections (default 100)'
        echo
        echo 'OPTIONS:'
        echo "-h | --help: Show this help screen"
        echo "-k | --kill: Block the offending ip making more than N connections"
        echo '-s | --show: Show The TOP "N" Connections of System Current'
        echo "-b | --banip: Ban The IP or IP subnet like cckiller -b 192.168.1.1"
        echo "-u | --unban: Unban The IP or IP subnet which is in the BlackList of iptables"
        echo
}

banip()
{
    LOG_FILE=$LOGDIR/cckiller_$(date +%Y-%m-%d).log
    if [[ ! -z $1 ]]
    then
        $IPT -nvL | grep DROP | grep $1 >/dev/null
        if [[ 0 -ne $? ]]
        then
            $IPT -I INPUT -s $1 -j DROP && \
                #echo "[`date "+%Y-%m-%d %H:%M:%S"`]: $1 Was Baned successfully." | tee -ai $LOG_FILE 
                write_log INFO "$1 Was Baned successfully." 
                send_tg "$ip 侦测异常IP %0A$1 Was Baned successfully"
                return 0
        else
            
            write_log DEBUG "$1 is already in iptables list, please check..."
            return 1
        fi
    else
         write_log DEBUG "Error: Not Found IP Address... Usage: cckiller -b IPaddress"
    fi
}

unbanip()
{
LOG_FILE=$LOGDIR/cckiller_$(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
        $IPT -D INPUT -s \$line -j DROP
        if [[ "$LOG_LEVEL" != "OFF" ]];then
            echo "[\`date "+%Y-%m-%d %H:%M:%S"\`][INFO]: \$line is Unbaned successfully." | tee -ai $LOG_FILE
             send_tg "$ip 的 \$line is Unbaned successfully."
        else
            echo "[\`date "+%Y-%m-%d %H:%M:%S"\`][INFO]: \$line is Unbaned successfully."
        fi
done < $BANNED_IP_LIST
rm -f $BANNED_IP_LIST $BANNED_IP_MAIL $BAD_IP_LIST $UNBAN_SCRIPT
EOF
. $UNBAN_SCRIPT &
else
    $IPT -nvL | grep DROP | grep $1 >/dev/null
    if [[ 0 -eq $? ]]
    then
        $IPT -D INPUT -s $1 -j DROP
        write_log INFO "$1 is Unbaned successfully."
        send_tg "$ip 的 $1  手动 Unbaned successfully."
    else
        write_log DEBUG "$1 is not found in iptables list, please check..."
    fi
fi
}

# Copyright by DDoS-Defender version 2.1.0 
core_netstat() {
 cat /proc/net/tcp6 /proc/net/tcp 2>/dev/null > /dev/shm/core_netstat
   awk '{print $2,$3,$4}' /dev/shm/core_netstat | awk '   
       BEGIN {
         #分割符    
           FS = "[ ]*|:" ;}
           
         #开始统计IP数     
         ( $0 !~ /local_address/ ){
         
         #统计ipv4     
         if (length($1) == 8)      
          { 
            local_ip_col4 = strtonum("0x"substr($1,1,2)) ;     
            local_ip_col3 = strtonum("0x"substr($1,3,2)) ;     
            local_ip_col2 = strtonum("0x"substr($1,5,2)) ;     
            local_ip_col1 = strtonum("0x"substr($1,7,2)) ;        
            rem_ip_col4 =  strtonum("0x"substr($3,1,2)) ;     
            rem_ip_col3 =  strtonum("0x"substr($3,3,2)) ;     
            rem_ip_col2 =  strtonum("0x"substr($3,5,2)) ;     
            rem_ip_col1 =  strtonum("0x"substr($3,7,2)) ;     
          }     
        else        
        #统计ipv6
         { 
           local_ip_col4 = strtonum("0x"substr($1,1,2)) ;     
           local_ip_col3 = strtonum("0x"substr($1,3,2)) ;     
           local_ip_col2 = strtonum("0x"substr($1,5,2)) ;     
           local_ip_col1 = strtonum("0x"substr($1,7,2)) ;        
           rem_ip_col4 =  strtonum("0x"substr($3,25,2)) ;     
           rem_ip_col3 =  strtonum("0x"substr($3,27,2)) ;     
           rem_ip_col2 =  strtonum("0x"substr($3,29,2)) ;     
           rem_ip_col1 =  strtonum("0x"substr($3,31,2)) ;     
         }      
           local_port = strtonum("0x"$2) ;   
           #rem_port = strtonum("0x"$4) ;
           
        #分析连接状态
        if ( $5 ~ /06/ ) tcp_stat = "TIME_WAIT"    
        else if ( $5 ~ /02/ ) tcp_stat = "SYN_SENT"    
        else if ( $5 ~ /03/ ) tcp_stat = "SYN_RECV"    
        else if ( $5 ~ /04/ ) tcp_stat = "FIN_WAIT1"    
        else if ( $5 ~ /05/ ) tcp_stat = "FIN_WAIT2"    
        else if ( $5 ~ /01/ ) tcp_stat = "ESTABLISHED" ;     
        else if ( $5 ~ /07/ ) tcp_stat = "CLOSE"    
        else if ( $5 ~ /08/ ) tcp_stat = "CLOSE_WAIT"    
        else if ( $5 ~ /09/ ) tcp_stat = "LAST_ACK"    
        else if ( $5 ~ /0A/ ) tcp_stat = "LISTEN"    
        else if ( $5 ~ /0B/ ) tcp_stat = "CLOSING"    
        else if ( $5 ~ /0C/ ) tcp_stat = "MAX_STATES"      
        printf("%d.%d.%d.%d [%d] %d.%d.%d.%d %s\n",local_ip_col1,local_ip_col2,local_ip_col3,local_ip_col4,local_port,rem_ip_col1,rem_ip_col2,
rem_ip_col3,rem_ip_col4,tcp_stat);}'
}

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()
{
    if [[ ! -z $1 ]] && [[ ! -z $2 ]]
    then
        core_netstat | awk '{print $1,$2,$3}' | \
        egrep -v "\[${IGNORE_PORT}\]|127.0.0.1|0.0.0.0"|sort|uniq -c
    else
        core_netstat | \
        egrep -v "\[${IGNORE_PORT}\]|127.0.0.1|0.0.0.0"|sort|uniq -c|sort -rn|\
        awk '{printf("%d %s\n",$1,$4)}'
    fi
}

cc_check()
{
    TMP_PREFIX='/tmp/cckiller'
    TMP_FILE="mktemp $TMP_PREFIX.XXXXXXXX"
    BANNED_IP_MAIL=$($TMP_FILE)
    BANNED_IP_LIST=$($TMP_FILE)
    LOG_FILE=$LOGDIR/cckiller_$(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
                write_log INFO "Banned $CURR_LINE_IP with $CURR_LINE_CONN connections" >> $BANNED_IP_MAIL
                echo $CURR_LINE_IP >> $BANNED_IP_LIST

        done < $BAD_IP_LIST
        if [[ $IP_BAN_NOW -ge 1 ]]; then
                dt=$(date)
                if [[ $EMAIL_TO != "" ]] && [[ $EMAIL_TO != "root@localhost" ]]; then
                        cat $BANNED_IP_MAIL | mailx -s "IP addresses banned on $dt" $EMAIL_TO
                fi
                if [[ $BAN_PERIOD -gt 0 ]];then
                    unbanip
                fi
        else
                rm -f $BANNED_IP_LIST $BANNED_IP_MAIL $BAD_IP_LIST 
        fi
}

process_mode()
{
    while true
    do
        cc_check
        sleep $1
    done
}

process_mode()
{
    while true
    do
        cc_check
        sleep $1
    done
}

#kill now
check_now()
{
    if [[ ! -z $1 ]]
    then
        NO_OF_CONNECTIONS=$1
    fi
    cc_check
}

load_conf
while [ $1 ]; do
        case $1 in
                '-h' | '--help' | '?' )
                        showhelp
                        exit
                        ;;
                '--kill' | '-k' )
                        check_now $2
                        ;;
                '--show' | '-s')
                    show_stats show $2
                    break;
                    ;;
                 '--banip' | '-b' )
                    banip $2
                    break
                        ;;   
                 '--unban' | '-u' )
                    unbanip $2
                    break
                        ;;      
                 '--process' | '-p' )
                    process_mode $SLEEP_TIME
                    break
                        ;;
                *[0-9]* )
                        check_now $1
                        ;;
                * )
                    showhelp
                    exit
                        ;;
        esac
        shift
done
[[ -z $1 ]] && show_stats

```