Linux日志分析异常IP并手动确认K掉

  •   
  • 2470
  • Linux
  • 8
  • super_dodo
  • 2014/11/17

项目运作中,常常会受到一些机器的攻击,如果攻击都来自同一个IP则可以初步判定该IP可能有风险,应采取措施进行规避风险。通过分析nginx的访问日志access.log,判断出1分钟内访问网站页面(排除静态资源访问)最多的IP,如果IP异常,使用IPtables杀掉IP。


#!/usr/bin/python
# -*- coding: utf-8 -*-
import os
import sys
import time
#日志路径
LogPath = "/home/wwwlogs/"
#日志文件名
LogFile = "access.log"
#临时IP地址存放 
TmpIp   = "tmpip.txt"
#已K掉的IP列表 
DenyIp  = "denyip.txt"
#读取的分析日志条数 
ReadSize = "10000"
#有问题IP列表 的访问次数
AccessTimes = "30"
#存储当前异常IP列表的字典 
IPARR = {}

#主类
class ReadLogs:
    def __init__(self):
        if os.path.exists(LogPath):
            filepath = LogPath+LogFile
            if os.path.isfile(filepath):
                self.readNow()
            else:
                print "the log file "+filepath+" is not exist"
        else:
            print "the log path is not exist"
    #读取日志操作,使用shell脚本快速处理
    def readNow(self):
        min1time = time.strftime('%H%M%S',time.localtime((time.time()-60)))
        nowtime  = time.strftime('%H%M%S',time.localtime(time.time()))
        command  = "tail  -n "+ReadSize+" "+LogPath+LogFile+"| egrep -v "+'"\.(gif|jpg|jpeg|png|css|js)" |'
        command += "awk  -v a="+min1time+" -v b="+nowtime+" -F [' ':] '{t=$5$6$7;if (t>=a && t<=b) print $1}' |"
        command += " sort|uniq -c|sort -rn |"
        command += "awk '{if ($1>="+AccessTimes+") print $2\":\"$1}'"
        print "run shell script:"+command
        tmpcol=os.popen(command).readlines();
        nowindex = 0
        fp = open(TmpIp,"w")
        for x in tmpcol:
            tmpstr = str(x)
            tmparr = tmpstr.split(":");
            ipstr  = tmparr[0].strip("\n")+" "+tmparr[1].strip("\n")
            fp.write(ipstr+"\n")
            print "find ip:"+tmparr[0].strip("\n")+",access times:"+tmparr[1].strip("\n")
        fp.close()
        print "write IP to file "+TmpIp+"! "
        self.showKillMenu()
    #显示IP处理菜单
    def showKillMenu(self):
        print "-------------------------------------"
        print "This is kill Ip menu"
        if len(IPARR) == 0:
            fp = open(TmpIp,"r")
            IPARR[0] = "all"
            line = fp.readline()
            nowindex = 1
            while line:
                ipstr = line.split()
                IPARR[nowindex] = ipstr[0]
                nowindex += 1
                line = fp.readline()
            fp.close()
        dlen = len(IPARR)
        if dlen <= 1:
            print "No IP find,will exist"
            sys.exit(0)
        for k in IPARR:
            print str(k)+" : "+IPARR[k]
        inputi = raw_input("Please input index to kill,input 0 to killAll:")
        inputi = int(inputi)
        if inputi >= 0:
            if inputi < dlen:
                self.killIP(inputi)
                self.showKillMenu()
            else:
                print "input Error,please retry"
                self.showKillMenu()
        else:
            print "you must input a number"
            self.showKillMenu()
    #用来封杀IP的函数
    def killIP(self,index):
        if index == 0:
            IPARR2 = IPARR.copy()
            for x in IPARR2:
                if IPARR[x] != 'all':
                    self.killAction(IPARR[x])
                    del(IPARR[x])
        else:
            self.killAction(IPARR[index])
            del(IPARR[index])

    def killAction(self,ip):
        print ip+" access deny"
        command = "iptables -I INPUT -s "+ip+"  -j DROP"
        os.popen(command).readlines();
        #封杀的结果写入日志
        fp = open(DenyIp,"a")
        fp.write(ip+"\n")
        fp.close()

        

if __name__ == '__main__':
    print "welcome to use yangjuyu nocc script"
    rd = ReadLogs() 

该文仅作抛砖迎玉之意。有不完善的地方请多多指点。

提剑跨麒挥鬼语,白骨如山鸟惊飞。尘世如潮人如水,只叹江湖几人回。