Nginx日志实现访问异常报警详解
前言
在工作中为了防止一些恶意访问的行为,例如不断的请求刷流量,通过实时过滤Nginx访问日志,将单位时间内访问次数达到指定阀值的来源ip及时的通知系统管理员,这里通过邮件的方式通知。
监控脚本
vim/opt/nginx/sbin/nginx_log_monitor.sh
#!/bin/bash #日志文件 logfile=/opt/nginx/logs/www #开始时间 start_time=`date-d"$last_minutesminutesago"+"%H:%M:%S"` #结束时间 stop_time=`date+"%H:%M:%S"` #过滤出单位之间内的日志并统计最高ip数 tac$logfile/access.log|awk-vst="$start_time"-vet="$stop_time"'{t=substr($4,RSTART+14,21);if(t>=st&&t<=et){print$0}}'\ |awk'{print$1}'|sort|uniq-c|sort-nr>$logfile/log_ip_top10 ip_top=`cat$logfile/log_ip_top10|head-1|awk'{print$1}'` #单位时间[1分钟]内单ip访问次数超过200次,则触发邮件报警 if[[$ip_top-gt200]];then /usr/bin/python/opt/tools/send_mail.py& fi
chmod+x/opt/nginx/sbin/nginx_log_monitor.sh
定时任务
如上脚本监控一分钟内的日志,因此每分钟执行一次:
#crontab-e */1****/bin/bash/opt/nginx/sbin/nginx_log_monitor.sh
邮件告警
这里通过python实现发送邮件
#vim/opt/tools/send_mail.py
#-*-coding:utf-8-*- fromemailimportencoders fromemail.headerimportHeader fromemail.mime.textimportMIMEText fromemail.utilsimportparseaddr,formataddr fromemail.mime.multipartimportMIMEMultipart fromemail.mime.baseimportMIMEBase fromdatetimeimportdatetime importos importsmtplib def_format_addr(s): name,addr=parseaddr(s) returnformataddr((Header(name,'utf-8').encode(),addr)) #邮箱定义 smtp_server='smtp.exmail.qq.com' smtp_port=465 from_addr='chenqingkang@qiniu.com' password=os.environ.get('MAIL_PASSWD') to_addr=['810959120@qq.com'] #邮件对象 msg=MIMEMultipart() msg['From']=_format_addr('发件人<%s>'%from_addr) msg['To']=_format_addr('收件人<%s>'%to_addr) msg['Subject']=Header('Warning:单ip请求次数异常','utf-8').encode() #获取系统中要发送的文本内容 withopen('/opt/nginx/logs/log_ip_top10','r')asf: line=f.readline().strip() line=line.split("") print(line) #邮件正文是MIMEText: html='一分钟内单ip请求次数超过阀值
'+\ 'ip:%s请求次数/min:%s
'%(line[1],line[0])+\ '' msg.attach(MIMEText(html,'html','utf-8')) server=smtplib.SMTP_SSL(smtp_server,smtp_port) server.login(from_addr,password) server.sendmail(from_addr,to_addr,msg.as_string()) server.quit()
示例
写个脚本不停curl请求资源触发报警:
#vimcurl.sh
#!/bin/bash #example:curl.shhttp://www.qingkang.me100 usage() { echo"usage:`basename$0`urlcount" } if[$#-ne2];then usage exit1 fi foriin`seq1$2`;do http_code=`curl-o/dev/null-s-w%{http_code}$1` echo$1$http_code done
#bashcurl.shhttp://qingkang.me/5 http://qingkang.me/200 http://qingkang.me/200 http://qingkang.me/200 http://qingkang.me/200 http://qingkang.me/200
调低阀值触发告警:
一分钟内单ip请求次数超过阀值 ip:115.231.182.82请求次数/min:27
完善
这里仅实现了邮件告警功能,实际上还可以实现自动屏蔽恶意访问的ip。可以通过Nginxdeny来实现,也可以iptables-IINPUT-sx.x.x.x-jDROP通过iptables屏蔽。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家能有一定的帮助,如果有疑问大家可以留言交流,谢谢大家对毛票票的支持。