0x01 调整时间格式
首先:查看nginx的默认日志的时间格式
[root@VM-0-13-centos ~]# more /var/log/nginx/access.log
时间格式是:28/Jul/2021:03:36:02 +0800
这个格式在写shell脚本的时候,date命令无法识别,所以我们需要更改nginx默认的日期格式。
开始调整nginx的日志时间格式,找到nginx的配置文件:
[root@VM-0-13-centos ~]# find / -name "nginx.conf"
默认的日期格式如下:
需要修改日期格式,修改如下
log_format json '{"@timestamp":"$time_iso8601",' '"clientip":"$remote_addr",' '"request":"$request",' '"http_user_agent":"$http_user_agent",' '"size":"$body_bytes_sent",' '"responsetime":"$request_time",' '"upstreamtime":"$upstream_response_time",' '"upstreamhost":"$upstream_addr",' '"http_host":"$host",' '"url":"$uri",' '"domain":"$host",' '"referer":"$http_referer",' '"status":"$status"}'; access_log /var/log/nginx/access.log json;
重新加载nginx的配置文件,使配置生效:
先查找可执行文件nginx的位置:
[root@VM-0-13-centos nginx]# whereis nginx nginx: /usr/sbin/nginx /usr/lib64/nginx /etc/nginx /usr/share/nginx /usr/share/man/man3/nginx.3pm.gz /usr/share/man/man8/nginx.8.gz
测试配置文件是否正确:
[root@VM-0-13-centos nginx]# /usr/sbin/nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
is ok 就表示配置文件没有问题。
重载使配置文件生效:
[root@VM-0-13-centos nginx]# /usr/sbin/nginx -s reload
再次查看nginx日志:
0x02 编写封堵脚本
#!/bin/bash #脚本详解:查询出nginx日志中访问量异常的ip进行封禁 #方法有很多可以利用nginx的deny方法,也可以采用iptables #我这里采用centos7自带的firewalld #nginx日志位置 nginx_access_log=/var/log/nginx/access.log ip=/var/log/nginx/ip.txt #一分钟内ip访问量统计排序 cat /var/log/nginx/access.log | grep `date -d "1 minutes ago" +"%Y-%m-%d"T"%H:%M"`|awk -F '"' '{ print $8 }' |sort |uniq -c |sort -rn > ip.txt for i in `awk '{print $1}' ip.txt` do if [ $i -gt 300 ]; then #设置的阈值为一分钟300次,即平均每秒访问5次判定为黑客攻击,当然也可以按秒统计次数 denyip=`grep $i ip.txt | awk '{print $2}'` # 找出IP #iptables -I INPUT -s $denyip -j DROP #利用iptables开始封堵 firewall-cmd --permanent --add-rich-rule="rule family=ipv4 destination address=$denyip reject" #利用firewalld开始封堵 firewall-cmd --reload #重新加载防火墙的热配置文件,使策略生效 echo $denyip > denyip.txt #记录封堵结果 fi done
核心语句分析:
[root@VM-0-13-centos ~]# cat /var/log/nginx/access.log | grep `date -d "1 minutes ago" +"%Y-%m-%d"T"%H:%M"`|awk -F '"' '{ print $8 }' |sort |uniq -c |sort -rn 1 150.223.27.195 1 114.118.7.124
上面的执行结果分析:表示在执行脚本的前一分钟内,nginx日志的每个ip的访问次数,前面的数字就是访问次数,后面一列是访问的ip。
0x03 脚本放入计划任务
[root@VM-0-13-centos ~]# vim /etc/crontab
每分钟执行一次脚本:
注意:这里的执行频率要与上面的日志统计时间间隔相对应。
*/1 * * * * root /root/fengduip.sh
0x04 测试脚本
通过循环的方式使127.0.0.1作为了异常访问的ip
[root@VM-0-13-centos nginx]# curl http://127.0.0.1
开始循环访问:
while true; do curl http://127.0.0.1; done
查看生成的日志:
[root@VM-0-13-centos nginx]# tail -20f /var/log/nginx/access.log