A small simple SSH log watcher && iptables blocker in Python

TRYTIME = 8#s
TRYNUMB = 10#x
DROPTIME = 60#s
import os
import re
import signal
import subprocess
import sys
import time
os.system("iptables -F INPUT")
p = subprocess.Popen(["tail", "-n", "0", "-f", sys.argv[1]], stdout=subprocess.PIPE)
h = {}
def chek(i, t):
	s = int(time.time())
	d = pow(2, i[2] - 1)
	if (i[3] > 1):
		return 2
	if ((i[1] > 0) and (i[2] > 0) and (i[3] > 0) and ((s - i[0]) >= (t * d))):
		return 1
	return 0
while (1):
	q = os.fork()
	if (q == 0):
		while (1):
			s = int(time.time())
			for a in h.keys():
				if (chek(h[a], DROPTIME) == 1):
					c = ("iptables -D INPUT -s '%s' -j DROP > /dev/null 2>&1 ; #for %ds" % (a, DROPTIME * pow(2, h[a][2] - 1)))
					print("del",s,c)
					os.system(c)
					del h[a]
			time.sleep(1)
		sys.exit(0)
	else:
		s = int(time.time())
		for a in h.keys():
			if (chek(h[a], DROPTIME) == 1):
				h[a][3] = 2
				h[a][0] = s
				print("~",s,a,h[a])
			if (h[a][3] != 1):
				if ((s - h[a][0]) > TRYTIME):
					h[a][1] = max(0, h[a][1] - int((s - h[a][0]) / TRYTIME))
					h[a][0] = s
				if (h[a][1] < 1):
					print("x",s,a,h[a])
					del h[a]
		l = p.stdout.readline().strip()
		r = re.match("^.*sshd.*fail.*[^0-9]([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+).*$", l, re.I)
		if (r):
			a = str(r.group(1))
			s = int(time.time())
			if (not a in h.keys()):
				h[a] = [s, 0, 0, 0];#address-string->[last-time,try-number,block-number,state-flag]
			if ((s - h[a][0]) <= TRYTIME):
				h[a][1] += 1
				print("+",s,a,h[a])
			if ((s - h[a][0]) > TRYTIME):
				h[a][1] = max(1, h[a][1] - int((s - h[a][0]) / TRYTIME))
				print("-",s,a,h[a])
			if (h[a][1] >= TRYNUMB):
				h[a][1] = (int(TRYNUMB / 2) + 1)
				h[a][2] += 1
				h[a][3] = 1
				c = ("iptables -A INPUT -s '%s' -j DROP ; #for %ds" % (a, DROPTIME * pow(2, h[a][2] - 1)))
				print("add",s,c)
				os.system(c)
			h[a][0] = s
		try:
			os.kill(q, signal.SIGKILL)
		except:
			pass
		try:
			os.waitpid(q, 0)
		except:
			pass

python sshipt.py /var/log/auth.log

('+', 1412665540, '1.93.29.79', [1412665540, 1, 0, 0])
('+', 1412665542, '1.93.29.79', [1412665540, 2, 0, 0])
('+', 1412665544, '1.93.29.79', [1412665542, 3, 0, 0])
('+', 1412665545, '1.93.29.79', [1412665544, 4, 0, 0])
('+', 1412665546, '1.93.29.79', [1412665545, 5, 0, 0])
('+', 1412665547, '1.93.29.79', [1412665546, 6, 0, 0])
('+', 1412665548, '1.93.29.79', [1412665547, 7, 0, 0])
('+', 1412665549, '1.93.29.79', [1412665548, 8, 0, 0])
('+', 1412665551, '1.93.29.79', [1412665549, 9, 0, 0])
('+', 1412665552, '1.93.29.79', [1412665551, 10, 0, 0])
('add', 1412665552, "iptables -A INPUT -s '1.93.29.79' -j DROP ; #for 60s")

Leave a comment