Skip to content

Commit be9c76a

Browse files
committed
监控被攻击的日志中,将IP加入黑名单
1 parent 9628d1c commit be9c76a

File tree

1 file changed

+239
-0
lines changed

1 file changed

+239
-0
lines changed

block_attack_log_ip.py

+239
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
#!/usr/bin/python
2+
#coding:utf-8
3+
# monitor /var/log/nginx/hack/*.log and analysis attack ip then block it
4+
# by avyou
5+
# at 20140930
6+
7+
import time,datetime
8+
import subprocess
9+
import select
10+
import re,os,sys
11+
import smtplib
12+
from email.mime.text import MIMEText
13+
14+
mail_to_list=['test@163.com']
15+
mail_host="smtp.163.com"
16+
mail_user="test@163.com"
17+
mail_pass="123456"
18+
mail_postfix="163.com"
19+
20+
##当前时间
21+
nowtime = datetime.datetime.now()
22+
##当前时间的上一分钟
23+
lastmin = nowtime - datetime.timedelta(minutes=2)
24+
## 转换成日志格式的时间,为了让awk 能使用,字符"/"会转成"\/"
25+
log_nowtime_format = nowtime.strftime('%H:%M:%S')
26+
log_lastmin_format = lastmin.strftime('%H:%M:%S')
27+
28+
log_day = nowtime.strftime('%Y-%m-%d')
29+
30+
#log_lastmin_format = "22/Sep/2014:06:24"
31+
#log_nowtime_format = "22/Sep/2014:06:26"
32+
33+
hostname = os.popen('echo $HOSTNAME').read()
34+
35+
##要分析日志文件
36+
nginx_log = "/var/log/nginx/hack/www.5usport.com_%s_sec.log" % log_day
37+
#nginx_log = "0922.log"
38+
nginx_p = "/usr/local/webserver/nginx/sbin/nginx"
39+
watch_log = "/var/log/nginx/hack/block_nginx_ip.log"
40+
f_suffix='.tmp'
41+
42+
##可疑用户访问错误达到的次数
43+
errors_block = 10
44+
##过期移除IP的间隔时间
45+
expire_time = 7200
46+
47+
##生成ip文件的临时目录
48+
ip_tmp_dir = "ip_tmp"
49+
##nginx 封断IP的文件
50+
block_ip_file = "/usr/local/webserver/tengine/conf/auto_block_ip.conf"
51+
#block_ip_file = "auto_block_ip.conf"
52+
##白名单规则
53+
writelist = "1.1.1.1|2.2.2.2|192.168.111.\d{0,3}|192.168.3.\d{0,3}"
54+
55+
## awk命令,获取时间范围的日志
56+
get_logs_cmd = r"""gawk -F '[ \[]' '$5>"%s" && $5<"%s"' %s""" %(log_lastmin_format ,log_nowtime_format, nginx_log)
57+
log_obj_output = os.popen(get_logs_cmd)
58+
##f = subprocess.Popen(['tail','-n10000',log],stdout=subprocess.PIPE,stderr=subprocess.PIPE)
59+
##log_contents = f.stdout.readlines()
60+
log_contents = log_obj_output.readlines()
61+
#print log_contents
62+
63+
##编译正则
64+
re_writelist_rules_match = re.compile(writelist)
65+
66+
##创建临时目录,如果不存在
67+
if not os.path.exists(ip_tmp_dir):
68+
os.makedirs(ip_tmp_dir)
69+
70+
if not os.path.isfile(block_ip_file):
71+
with open(block_ip_file,'w') as f:
72+
f.write('')
73+
74+
75+
def SendMail(sub,content):
76+
msg = MIMEText(content,_subtype='plain',_charset='gb2312')
77+
me="monitor"+"<"+mail_user+"@"+mail_postfix+">"
78+
msg['Subject'] = sub
79+
msg['From'] = me
80+
msg['To'] = ";".join(mail_to_list)
81+
try:
82+
print "send mail test ...."
83+
server = smtplib.SMTP()
84+
server.connect(mail_host)
85+
server.login(mail_user,mail_pass)
86+
server.sendmail(me, mail_to_list, msg.as_string())
87+
server.close()
88+
return True
89+
except Exception, e:
90+
print str(e)
91+
return False
92+
93+
94+
def WriteLog(msg):
95+
with open(watch_log,"a") as f:
96+
f.write(msg)
97+
98+
def ReloadNginx(nginx_p):
99+
test_nginx_cmd = subprocess.Popen('%s -t' % nginx_p, shell=True, stdout=subprocess.PIPE, \
100+
stderr=subprocess.STDOUT)
101+
nginx_status_list = test_nginx_cmd.stdout.readlines()
102+
re_ok = re.compile('ok')
103+
re_success = re.compile('successful')
104+
if (re_ok.search(nginx_status_list[0]) is not None) and (re_success.search(nginx_status_list)[1] is not None):
105+
subprocess.Popen('%s -s reload' % nginx_p, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
106+
107+
def suspiciousIPList():
108+
## 可疑IP列表
109+
suspicious_iplist = []
110+
[ suspicious_iplist.append(log_line.split()[0]) for log_line in log_contents]
111+
print suspicious_iplist
112+
return suspicious_iplist
113+
114+
#print "suspicious_iplist: ",suspicious_iplist
115+
116+
def doBlockIP(iplist,errors_num):
117+
add_ip_status = 0
118+
if len(iplist) != 0:
119+
iplist.sort()
120+
ipdict = {}
121+
##IP计数
122+
for ip in iplist :
123+
ipdict[ip] = ipdict.get(ip,0) + 1
124+
##如果IP出错次数大于指定值,则进行相应操作
125+
log_ip = []
126+
for ip in ipdict.keys():
127+
if ipdict[ip] >= errors_num:
128+
#print ip, ipdict[ip]
129+
##可疑IP生成文件名保存到指定目录
130+
genip = os.path.join(ip_tmp_dir,"".join([ip,'.tmp']))
131+
print genip
132+
with open(genip,'w') as f:
133+
f.write("")
134+
##可疑IP写入日志
135+
nowtime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
136+
msg = "At %s==> suspicious IP %s access web.\n" % (nowtime,ip)
137+
WriteLog(msg)
138+
139+
##打开nginx 的阻止IP配置文件,写入IP
140+
try:
141+
with open(block_ip_file,"a+") as f:
142+
if ip not in [ each_ip.lstrip("deny ").rstrip(";\n") for each_ip in f ]:
143+
f.write("".join(["deny ",ip,";\n"]))
144+
log_ip.append(ip)
145+
add_ip_status = 1
146+
147+
except:
148+
msg = "Write IP wrong,please check!\n"
149+
WriteLog(msg)
150+
break
151+
152+
if add_ip_status == 1:
153+
ReloadNginx(nginx_p)
154+
nowtime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
155+
sub = u"monitor for analysis log file and add ip"
156+
msg = "(%s)At %s==> Add Some IP in block file: %s\n" %(hostname,nowtime,log_ip)
157+
SendMail(sub,msg)
158+
print 'nginx reload'
159+
add_ip_status = 0
160+
161+
162+
def removeList():
163+
remove_iplist = []
164+
## IP文件列表
165+
files_list = os.listdir(ip_tmp_dir)
166+
print "files_list: %s" % files_list
167+
## 如果文件列表不为空就添加放到移除列表
168+
if len(files_list) != 0:
169+
for ip_file in files_list:
170+
if ip_file.endswith(f_suffix):
171+
## 获取文件的时间
172+
mfile = time.localtime(os.stat(os.path.join(ip_tmp_dir,ip_file)).st_mtime)
173+
#print mtime
174+
mfile = time.strftime("%Y-%m-%d %H:%M:%S",mfile)
175+
file_time = datetime.datetime.strptime(mfile,'%Y-%m-%d %H:%M:%S')
176+
nowtime = datetime.datetime.now()
177+
## IP文件到现在的时间,以秒为单位
178+
difftime_seconds = (nowtime - file_time).seconds
179+
print "ip file: %s" %ip_file
180+
##print "difftime_time: %s" %difftime_seconds
181+
##print "expire_time: %s" %expire_time
182+
183+
## 如果IP文件时间超过指定的时间
184+
if difftime_seconds >= expire_time:
185+
ip = ip_file.rstrip(f_suffix)
186+
## 放入到移除列表
187+
remove_iplist.append(ip)
188+
#print "delete file"
189+
dfile = os.path.join(ip_tmp_dir,ip_file)
190+
if os.path.isfile(dfile):
191+
os.remove(dfile)
192+
nowtime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
193+
msg = "At %s==> Remove expire time IP: %s\n" %(nowtime,ip)
194+
WriteLog(msg)
195+
196+
print "remove ip: ",remove_iplist
197+
return remove_iplist
198+
199+
############# 移除到期的IP ####################
200+
def doRemoveIP(iplist):
201+
print "iplist: %s" %iplist
202+
del_ip_status = 0
203+
##如果移除列表不为空,进行相应操作
204+
print "remove list: %s" % len(iplist)
205+
if len(iplist) != 0:
206+
with open(block_ip_file,'r') as in_f:
207+
##获取原block_ipfile文件中的IP列表的集合
208+
set_block_ip_list = set([ip.lstrip("deny ").rstrip(";\n") for ip in in_f.readlines()])
209+
#print set_block_ip_list
210+
#print set(iplist)
211+
## 获取保留的IP集合
212+
sip = set_block_ip_list - set(iplist)
213+
214+
with open(block_ip_file,'w+') as out_f:
215+
for ip in sip:
216+
out_f.write("".join(["deny ",ip,";\n"]))
217+
del_ip_status = 1
218+
219+
if del_ip_status == 1:
220+
ReloadNginx(nginx_p)
221+
nowtime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
222+
sub = u"monitor for analysis log file and remove ip"
223+
msg = "(%s)At %s==> Remove some expire time IP: %s\n" %(hostname,nowtime,iplist)
224+
SendMail(sub,msg)
225+
print 'nginx reload'
226+
del_ip_status = 0
227+
228+
229+
if __name__ == "__main__":
230+
##可疑IP
231+
suspicious_iplist = suspiciousIPList()
232+
##阻止IP
233+
print suspicious_iplist
234+
#print suspicious_iplist2
235+
doBlockIP(suspicious_iplist,errors_block)
236+
##要移除的IP
237+
remove_ip_list = removeList()
238+
##移除IP
239+
doRemoveIP(remove_ip_list)

0 commit comments

Comments
 (0)