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屏蔽。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家能有一定的帮助,如果有疑问大家可以留言交流,谢谢大家对毛票票的支持。