天天看點

指定時間内網站通路次數的監控

需求說明:

在日常運維工作中,為了防止一些惡意通路的行為,例如不斷的請求刷流量,通過實時過濾Nginx通路日志,将機關時間内通路次數達到指定閥值的來源ip查找出來,并通過郵件報警方式及時通知運維人員!

比如針對url為http://192.168.10.202:8888的通路進行監控,當在1分鐘内通路次數超過300次數,就郵件報警給運維人員。

1)nginx日志監控腳本

[root@Fastdfs_storage_s1 ~]# cat /opt/nginx_log_monit.sh 
#!/bin/bash
#日志檔案
logfile=/usr/local/nginx/logs/access.log
  
#開始時間
start_time=`date -d"$last_minutes minutes ago" +"%H:%M:%S"`
  
#結束時間
stop_time=`date +"%H:%M:%S"`
  
#過濾出機關之間内的日志并統計最高ip數
tac $logfile | awk -v st="$start_time" -v et="$stop_time" '{t=substr($4,RSTART+14,21);if(t>=st && t<=et) {print $0}}' \
| awk '{print $1}' | sort | uniq -c | sort -nr > /root/log_ip_top10
ip_top=`cat /root/log_ip_top10 | head -1 | awk '{print $1}'`
# 機關時間[1分鐘]内單ip通路次數超過300次,則觸發郵件報警
if [[ $ip_top -gt 300 ]];then
 /usr/bin/python /opt/send_mail.py &
fi      

2)python報警腳本

[root@Fastdfs_storage_s1 ~]# cat /opt/send_mail.py 
# -*- coding: utf-8 -*-
from email import encoders
from email.header import Header
from email.mime.text import MIMEText
from email.utils import parseaddr, formataddr
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from datetime import datetime
import os
import smtplib
def _format_addr(s):
 name, addr = parseaddr(s)
 return formataddr((Header(name, 'utf-8').encode(), addr))
# 郵箱定義
smtp_server = 'smtp.kevin.com'
smtp_port = 465
from_addr = '[email protected]'
password = os.environ.get('monit@123')
to_addr = ['[email protected]']
# 郵件對象
msg = MIMEMultipart()
msg['From'] = _format_addr('發件人 <%s>' % from_addr)
msg['To'] = _format_addr('收件人 <%s>' % to_addr)
msg['Subject'] = Header('Warning:單ip請求次數異常', 'utf-8').encode()
# 擷取系統中要發送的文本内容
with open('/root/log_ip_top10', 'r') as f:
 line = f.readline().strip()
 line = line.split(" ")
print(line)
# 郵件正文是MIMEText:
html = '<html><body><h2>一分鐘内單ip請求次數超過閥值</h2>' + \
 '<p>ip:%s  請求次數/min:%s</p>' % (line[1],line[0]) + \
 '</body></html>' 
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()      

3)寫個測試腳本不停curl請求資源觸發報警

[root@Fastdfs_storage_s1 ~]# cat /opt/curl.sh 
#!/bin/bash
#example:curl.sh http://www.kevin.com 100
usage()
{
 echo "usage: `basename $0` url count"
}
if [ $# -ne 2 ]; then
 usage
 exit 1
fi
for i in `seq 1 $2`;do
 http_code=`curl -o /dev/null -s -w %{http_code} $1`
 echo $1 $http_code
done


手動執行測試腳本
[root@Fastdfs_storage_s1 ~]# /bin/bash /opt/curl.sh http://192.168.10.202:8888 300
http://192.168.10.202:8888 200
http://192.168.10.202:8888 200
http://192.168.10.202:8888 200
http://192.168.10.202:8888 200
http://192.168.10.202:8888 200
http://192.168.10.202:8888 200
http://192.168.10.202:8888 200
http://192.168.10.202:8888 200
http://192.168.10.202:8888 200
http://192.168.10.202:8888 200
http://192.168.10.202:8888 200
...........      

4)定時任務,由于上面腳本是監控一分鐘内的日志,是以每分鐘執行一次

[root@Fastdfs_storage_s1 ~]# crontab -e
* * * * * /bin/bash -x /opt/nginx_log_monit.sh >/dev/null 2>&1      

這裡僅僅是實作了郵件告警功能,實際上還可以實作自動屏蔽惡意通路的ip。

可以通過Nginx deny來實作,也可以通過iptables屏蔽("iptables -I INPUT -s x.x.x.x -j DROP"方式)。

*************** 當你發現自己的才華撐不起野心時,就請安靜下來學習吧!***************