简介

在日常业务场景中可能存在恶意用户频繁访问系统,占用系统资源,影响正常用户访问,我们有许多方案杜绝此类问题发生,例如增加验证码,应用内限制访问次数,网关ip封禁等等。本次介绍如何利用Nginx和shell脚本自动化封禁访问ip。

Nginx封禁ip或ip段

封禁ip/ip段语法

1
2
deny 1.2.3.4;
deny 91.212.45.0/24;

允许ip/ip段语法

1
2
allow 1.2.3.4;
allow 91.212.45.0/24;

新建/usr/local/nginx/conf/vhosts/blockip.conf,将封禁ip/ip段的语句放入到blockip.conf

根据放入的语句块实现封禁ip的范围:

  • include vhosts/blockip.conf放在server语句块,则单独封禁某个网站
  • include vhosts/blockip.conf放在http语句块,则封禁所有网站

记得在nginx.conf导入blockip.conf

禁用ip配置

shell脚本自动化封禁ip

awk

AWK 是一种处理文本文件的语言,是一个强大的文本分析工具。后面会详细介绍。

自动化封禁ip的思路:

1、统计访问日志的ip并去重排序

2、计算超过特定访问速率(每分钟60次)的ip

3、将ip记录在vhosts/blockip.conf并灰度发布

4、crontab定时运行脚本

1
awk '{print $1}' /usr/local/nginx/logs/access.log

统计access.log

1
awk '{print $1}' /usr/local/nginx/logs/access.log | sort | uniq -cd

去重和排序

1
awk '{print $1}' /usr/local/nginx/logs/access.log | sort | uniq -cd | awk '{if($1>)print $0}'

计算超过特定访问速率(每分钟60次)的ip

编写shell脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#不能把别人IP一直封着吧,这里就清除掉了
echo "" > /usr/local/nginx/conf/vhosts/blockip.conf

#前面最开始编写的统计数据功能
ip_list=$(awk '{print $1}' /usr/local/nginx/logs/access.log | sort | uniq -cd | awk '{if($1>60)print $0}')

#获取当前时间
starttime=$(date +%Y-%m-%d\ %H:%M:%S)

#判断这个变量是否为空
if test -z "$ip_list"
then
#为空写入 blockip.log中,并重新启动ngnix
echo "$starttime 暂无封禁ip" >> /usr/local/nginx/logs/blockip.log

/usr/bin/nginx -s reload
else
#如果不为空 前面加上 deny格式和ip写入blockip.conf中
echo "deny" $ip_list > /usr/local/nginx/conf/vhosts/blockip.conf

#因为前面携带了行数,所有我们需要去除掉前面的行数,写入后在读取一次
ip_list2=$(awk '{print $3}' /usr/local/nginx/conf/vhosts/blockip.conf)

#最后再把读取出来的值,在次写入到blockip.conf中
echo "deny" $ip_list2";"> /usr/local/nginx/conf/vhosts/blockip.conf

#重启ngnix
/usr/bin/nginx -s reload
#清空之前的日志,从最新的开始截取
echo "" > /usr/local/nginx/logs/access.log

# 记录封禁ip
echo "$starttime 封禁ip $ip_list2" >> /usr/local/nginx/logs/blockip.log
fi

crontab定时运行脚本

编辑/etc/crontab

1
* * * * * root /usr/bin/sh /usr/local/nginx/shell/blockip.sh

* * * * *表示每分钟运行一次

root表示运行用户

/usr/bin/sh表示运行程序

/usr/local/nginx/shell/blockip.sh表示运行脚本

crontab定时运行脚本

效果

为了更快达到效果,博主将访问次数改为20次

封禁ip效果

如果想调整每分钟的访问次数,请修改shell脚本

如果想调整定时任务的间隔时间,请参考cron表达式,修改/etc/crontab