指定時間內網站訪問次數的監控

 

需求說明:
在平常運維工做中,爲了防止一些惡意訪問的行爲,例如不斷的請求刷流量,經過實時過濾Nginx訪問日誌,將單位時間內訪問次數達到指定閥值的來源ip查找出來,並經過郵件報警方式及時通知運維人員!html

好比針對url爲http://192.168.10.202:8888的訪問進行監控,當在1分鐘內訪問次數超過300次數,就郵件報警給運維人員。
1)nginx日誌監控腳本python

[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報警腳本nginx

[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 = 'monit@kevin.com'
password = os.environ.get('monit@123')
to_addr = ['wangshibo@kevin.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()
# 獲取系統中要發送的文本內容
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請求資源觸發報警bash

[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"方式)。curl

相關文章
相關標籤/搜索