美文网首页
centos iptables 分析自动封锁

centos iptables 分析自动封锁

作者: 9682f4e55d71 | 来源:发表于2018-07-07 17:57 被阅读22次
    #!/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
    
    

    相关文章

      网友评论

          本文标题:centos iptables 分析自动封锁

          本文链接:https://www.haomeiwen.com/subject/dvjguftx.html