Need to ban people who hammer your ftp, but dont want to or cant install fail2ban ? This may help get you on the right track:
#!/usr/bin/env python import popen2, re, datetime, time, os, sys, logging, syslogtimeLimit = 300 # in seconds (== 5 minutes) failureLimit = 5 # X number of fails in timeLimit secureFile = '/var/log/secure' banFile = '/proc/net/ipt_recent/blacklist_ftp' pidFile = '/var/run/ftp-autobanner.pid' debug = 0 ####################### #### NO EDIT POINT #### ####################### def daemonize (stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'): # Perform first fork. try: pid = os.fork( ) if pid > 0: sys.exit(0) # Exit first parent. except OSError, e: sys.stderr.write("fork #1 failed: (%d) %sn" % (e.errno, e.strerror)) sys.exit(1) # Decouple from parent environment. os.chdir("/") os.umask(0) os.setsid( ) # Perform second fork. try: pid = os.fork( ) if pid > 0: fh = open(pidFile,'w') fh.write(str(pid)) fh.close() sys.exit(0) # Exit second parent. except OSError, e: sys.stderr.write("fork #2 failed: (%d) %sn" % (e.errno, e.strerror)) sys.exit(1) # The process is now daemonized, redirect standard file descriptors. for f in sys.stdout, sys.stderr: f.flush( ) si = file(stdin, 'r') so = file(stdout, 'a+') se = file(stderr, 'a+', 0) os.dup2(si.fileno( ), sys.stdin.fileno( )) os.dup2(so.fileno( ), sys.stdout.fileno( )) os.dup2(se.fileno( ), sys.stderr.fileno( )) daemonize() syslog.syslog('Starting') failureList = [] (outStm,inStm) = popen2.popen2("/usr/bin/tail -qFn0 -s 0.5 "+secureFile+" 2>/dev/null") while 1: fileLine = outStm.readline() if ((fileLine.rfind('authentication failure') != -1) and (fileLine.rfind('vsftpd') != -1)): if debug: syslog.syslog('Suitable line found: ' + fileLine) # Grab parts of line we want, and add into array t = datetime.datetime.now() # no need to read timestamp from log as its at most half a second behind epochStamp = time.mktime(t.timetuple()) matchObj = re.search( r'rhost=(\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b)', fileLine, re.M|re.I) ip = matchObj.group(1) failureList.append( (epochStamp, ip) ) if debug: syslog.syslog('Added ' + ip + " Stamped at: " + str(epochStamp)) # Get list in shape (remove over-old entries) for failureEntry in failureList[:]: # take a copy of the lsit (will be removing elements later on) t = datetime.datetime.now() epochNow = time.mktime(t.timetuple()) if ((epochNow - failureEntry[0]) >= timeLimit): failureList.remove(failureEntry) if debug: syslog.syslog('Removing stale entry ' + failureEntry) # Calculate number of each IP in the list failureTotals = {} for failureEntry in failureList: if failureEntry[1] in failureTotals: failureTotals[failureEntry[1]] += 1 else: failureTotals[failureEntry[1]] = 1 # Ban any IPs with more than the the limit of entries for key in failureTotals: if (failureTotals[key] > failureLimit): # put IP into ban file FH = open(banFile, 'w') FH.write(key+'\n') FH.close() if debug: syslog.syslog('IP: ' + key + " Banned") # Remove all occurances of this IP, as its now banned for failureEntry in failureList[:]: if failureEntry[1] == key: failureList.remove(failureEntry)