centos iptables 分析自动封锁

2018-07-07  本文已影响22人  9682f4e55d71
#!/bin/sh
# desc: 检查登陆页面 单个IP的访问次数, 加参数 -k 可直接加入到防火墙
# author: dbquan
# -_- 写了很多,其实就是一行命令搞定: tail -n 10000 /path_to/nginx-access.log | awk -F '|' '{if($7 ~ "?main_page=login") {print $1}}' | sort | uniq -c | sort -n -k 1 -r | head -n 10 | awk '{if($1>100) {print $0}}' | awk '{print $2}' | xargs -I {} echo "iptables -I INPUT 17 -s {}/24 -j DROP"


CHECK_ACCESS_FILE='/path_to/nginx-access.log'  # 日志文件
CHECK_ACCESS_PAGE='?main_page=login' # 需要检查的页面
CHECK_ACCESS_TIMES=100   # 访问次数, 大于该次数则加入到防火墙
CHECK_LOG_TAIL_LINE_NUMBERS=10000  # 检查的日志行数
CHECK_KILL_LINES=25   # 排名前25的会被过滤出来

DATA_FROM='file'   # file or netstat
IPT_INSERT_POSITION=17
ISKILL='N'

#BASE_PATH=$(cd `dirname $0`; pwd)
BASE_PATH="/data/bin/ip_check"
TMP_DATA_FILE="$BASE_PATH/tmp_data"
LOG_DIR="$BASE_PATH/logs"


usage()
{
    echo "Usage: $0 [OPTION]"
    echo "        Show head count and ip information."
    echo "  -k    Add matched ip to iptables."
}

get_count_ip()
{
    echo "start to get ip and count from $DATA_FROM ..."

    if [ "$DATA_FROM" = "file" ]; then
        tail -n $CHECK_LOG_TAIL_LINE_NUMBERS $CHECK_ACCESS_FILE | \
            awk -F '|' -v CHECK_ACCESS_PAGE="$CHECK_ACCESS_PAGE" '{if($7 ~ CHECK_ACCESS_PAGE) {print $1}}' | \
            sort | uniq -c | sort -n -k 1 -r | \
            head -n "$CHECK_KILL_LINES" > "$TMP_DATA_FILE"
    else
        # 已经建立的链接
        netstat -an | grep ESTABLISHED | awk '{print $5}' | awk -F ':' '{print $1}' | grep -v -E '192.168|127.0' | sort | uniq -c | sort -rn  -k 1 | head > "$TMP_DATA_FILE"
    fi

    if [ $? -eq 0 ]; then
        echo "  count ip($CHECK_ACCESS_PAGE)"
        cat "$TMP_DATA_FILE"
    else
        echo "ERROR, exit $?"
        exit $?
    fi
}


add_to_iptables()
{
    if [ "$ISKILL" = "Y" ]; then
        echo -e '\nstart to add to iptables ...'
        while read line
        do
            local count=`echo $line | awk '{print $1}'`
            local ip=`echo $line | awk '{print $2}'`
            local datetime=`date "+%Y%m%d %H:%M:%S"`
            local cmd="iptables -I INPUT $IPT_INSERT_POSITION -s $ip/24 -j DROP -m comment --comment \"$datetime|$ip|$count\""

            # 避免加入重复的记录
            if [ `iptables -nL --line-numbers | grep "$ip" > /dev/null 2>&1 ; echo $?` -eq 1 ]; then
                if [ $count -gt $CHECK_ACCESS_TIMES ]; then
                    eval $cmd
                    if [ $? -eq 0 ]; then
                        echo "$cmd [OK]"
                        [ -d "$LOG_DIR" ] || mkdir "$LOG_DIR" || "WARN: mkdir $LOG_DIR fail"
                        echo "[`date "+%Y%m%d %H:%M:%S"]` $cmd" >> "$LOG_DIR/`date "+%Y%m%d"`.log"
                    else
                        echo "ERROR, exit $?"
                        exit $?
                    fi
                else
                    echo "  << access times less than $CHECK_ACCESS_TIMES: $ip|$count"
                fi
            else
                echo "  >> $ip already in iptables"
            fi
        done < $TMP_DATA_FILE
    fi
}


case "$1" in
    "-k")
        ISKILL='Y'
        ;;
    "")
        ;;
    *)
        usage
        exit
        ;;
esac


get_count_ip && \
    add_to_iptables
if [ $? -eq 0 ]; then
    echo "done"
else
    echo "fail!"
fi

上一篇下一篇

猜你喜欢

热点阅读