高性能 Web 应用服务器 Nginx 功能之自动化封禁 ip
| 字数总计:828|阅读时长:3 分钟 | 阅读量:154
简介
在日常业务场景中可能存在恶意用户频繁访问系统,占用系统资源,影响正常用户访问,我们有许多方案杜绝此类问题发生,例如增加验证码,应用内限制访问次数,网关 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
:

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
|

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}'
|

编写 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
表示运行脚本

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

如果想调整每分钟的访问次数,请修改 shell 脚本
如果想调整定时任务的间隔时间,请参考 cron 表达式,修改 /etc/crontab