We’ve noticed that most of our servers have been under heavy attack from random IP addresses to break via SSH.
With the help of the last post on how to ban an IP, and the following python script, you’ll be able to have a cronjob that runs once or twice a day and automagically bans all the offending ips from ever trying to brute force their way in ever again.
touch and make executable a file called “detect_ssh_hostiles”
touch detect_ssh_hostiles chmod +x detect_ssh_hostiles
Then copy the following code inside:
# Usage: # python detect_ssh_hostiles [auth.log file path] # # Requirement: There should be "ban_ip" and "unban_ip" command availability on the path # # Note: you gotta have read permissions on the auth.log file and sudo # permissions for the script to ban the ips. #If an IP meets this number of failed login attemmpts it will be banned BAN_THRESHOLD = 7 SUSPECTS = {} #Put here IP addresses you trust, could be making genuine login errors SAFE_IPS = ['81.73.111.49','101.73.111.160','72.31.171.235','72.36.23.234','82.36.180.210','202.132.82.16'] import os import sys import re BANNED = {} def loadBanned(): ''' This function will load all the banned IPS into the BANNED Dict. It will also count how many times (by mistake) the same IP has been banned, and it will unban it, so that it will appear only once. ''' global BANNED command = 'sudo iptables --list --numeric' try: p = os.popen(command,'rb') except Exception,e: print e sys.exit(1) line = '-' while line != '': line = p.readline().strip() if line.startswith("DROP"): parts = line.split() ip = parts[3] #add hit or register banned ip if BANNED.has_key(ip): BANNED[ip]+=1 else: BANNED[ip]=1 #Make sure banned IPs are banned only once for ip in BANNED: if BANNED[ip] > 1: print "IP %s has been banned %d times" % (ip, BANNED[ip]) n=BANNED[ip]-1 while n > 0: os.system("unban_ip %s" % ip) print ("unban_ip %s" % ip) n=n-1 p.close() # ---- here we go ---- loadBanned() #read auth log logfile = '/var/log/auth.log' if len(sys.argv)==2: logfile = sys.argv[1] command = 'grep "Failed password for " %s' % logfile #print command try: p = os.popen(command,'rb') except Exception,e: print e sys.exit(1) line = "123" while line != '': line = p.readline() #Sample line: # May 25 03:29:49 main sshd[6933]: Failed password for root from 202.118.236.132 port 54863 ssh2 pattern = "(.*)(froms)(d+.d+.d+.d+)(.*)" matchObject = re.match(pattern, line) suspect = None if matchObject is not None: suspect = matchObject.groups()[2] #skip safe IPs if suspect in SAFE_IPS: continue if SUSPECTS.has_key(suspect): #add a hit SUSPECTS[suspect] += 1 else: #add first hit SUSPECTS[suspect] = 1 p.close() #close the pipe print "=="*30 import time t = time.localtime() #(2008, 6, 6, 9, 35, 21, 4, 158, 1) timestr = "%d-%d-%d@%d:%d:%d" % (t[0],t[1],t[2],t[3],t[4],t[5]) print timestr print "--"*30 if len(SUSPECTS) > 0: for suspect in SUSPECTS: if SUSPECTS[suspect] >= BAN_THRESHOLD and not BANNED.has_key(suspect): print "Banning %s with %d attempts" % (suspect,SUSPECTS[suspect]) BANNED[suspect]=1 os.system("ban_ip %s" % suspect) elif BANNED.has_key(suspect): print "Ip %s has already been banned" % (suspect) else: print "Suspect candidate? %s with %d attempts" % (suspect,SUSPECTS[suspect]) else: print "Found no suspects to ban" print "=="*30
Then add this as a cronjob of your root user, and it will automatically ban all those IPs that have tried to break in. See the script for configuration. You can always make some IPs immune to banning by adding them on the SAFE_IPS list.
yo uso el paquete denyhosts para eso… tb existe fail2ban, no hay que reinventar la rueda 😀
tienes razon, no soy partidario de no reinventar la rueda, pero para el momento no encontre denyhosts ni fail2ban
I hope this works i have been looking for a script like this ever since, thanks man you the best gonna publicize this blog to the world for tech guys to view