Nginx+Lua脚本+Redis 实现自动封禁访问频率过高IP

1 、安装OpenResty
安装使用 OpenResty,这是一个集成了各种 Lua 模块的 Nginx 服务器,是一个以Nginx为核心同时包含很多第三方模块的Web应用服务器,使用Nginx的同时又能使用lua等模块实现复杂的控制。

(1)安装编译工具、依赖库

[root@test1 ~]# yum -y install readline-devel pcre-devel openssl-devel gcc
(2)下载openresty-1.13.6.1.tar.gz 源码包,并解压;下载ngx_cache_purge模块,该模块用于清理nginx缓存;下载nginx_upstream_check_module模块,该模块用于ustream健康检查。

cd /usr/local/
wget https://openresty.org/download/openresty-1.13.6.1.tar.gz
tar -zxvf openresty-1.13.6.1.tar.gz
cd openresty-1.13.6.1/bundle
wget http://labs.frickle.com/files/ngx_cache_purge-2.3.tar.gz
tar -zxvf ngx_cache_purge-2.3.tar.gz
wget https://github.com/yaoweibin/nginx_upstream_check_module/archive/v0.3.0.tar.gz
tar -zxvf v0.3.0.tar.gz

(3)配置需安装的模块

# ./configure --help可查询需要安装的模块并编译安装

./configure --prefix=/usr/local/openresty --with-luajit --with-http_ssl_module --user=root --group=root --with-http_realip_module --add-module=./bundle/ngx_cache_purge-2.3/ --add-module=./bundle/nginx_upstream_check_module-0.3.0/ --with-http_stub_status_module 
make && make install

(5)启动nginx

 /usr/local/openresty/nginx/sbin/nginx  -c /usr/local/openresty/nginx/conf/nginx.conf 
随后,打开浏览器访问页面。

(6)在Nginx上测试一下能否使用Lua脚本

vim /usr/local/openresty/nginx/conf/nginx.conf
在server里面加一个location /lua {default_type text/plain;content_by_lua 'ngx.say("hello,lua!")';
}

加完后重新reload配置。
在浏览器里输入 ip地址/lua,出现下面的字就表示Nginx能够成功使用lua了

2 、安装Redis
yum install -y redis

systemctl start redis

3 、Lua访问Redis
(1)连接redis,然后添加一些测试参数

redis-cli
set "123" "456"

(2)编写连接Redis的Lua脚本

vim /usr/local/openresty/nginx/conf/lua/redis.lua
local redis = require "resty.redis"
local conn = redis.new()
#根据自己情况写ip和端口号
conn.connect(conn, '192.168.20.205', '6379')      
local res = conn:get("123")
if res==ngx.null thenngx.say("redis集群中不存在KEY——'123'")return
end
ngx.say(res)

(3)在nginx.conf配置文件中的server下添加以下location

vim /usr/local/openresty/nginx/conf/nginx.conf
location /lua_redis {default_type text/plain;content_by_lua_file /usr/local/openresty/nginx/conf/lua/redis.lua;
}

随后重新reload配置。

(4)验证Lua访问Redis的正确性

在浏览器输入ip/lua_redis, 如果能看到下图的内容表示Lua可以访问Redis。

准备工作已经完成,现在要实现OpenResty+Lua+Redis自动封禁并解封IP了。

4 、OpenResty+Lua实现
(1)添加访问控制的Lua脚本(只需要修改Lua脚本中连接Redis的IP和端口即可)
注意:如果在Nginx或者OpenResty的上层有用到阿里云的SLB负载均衡的话,需要修改一下脚本里的所有…ngx.var.remote_addr,把remote_addr替换成从SLB获取真实IP的字段即可,不然获取到的IP全都是阿里云SLB发过来的并且是处理过的IP,同时,这些IP全都是一个网段的,根本没有办法起到封禁的效果)

完整的Lua脚本如下所示。

vim /usr/local/openresty/nginx/conf/lua/access.lua
local ip_block_time=300 --封禁IP时间(秒)
local ip_time_out=30    --指定ip访问频率时间段(秒)
local ip_max_count=20 --指定ip访问频率计数最大值(秒)
local BUSINESS = ngx.var.business --nginx的location中定义的业务标识符,也可以不加,不过加了后方便区分--连接redis
local redis = require "resty.redis"  
local conn = redis:new()  
ok, err = conn:connect("192.168.20.205", 6379)  
conn:set_timeout(2000) --超时时间2秒--如果连接失败,跳转到脚本结尾
if not ok thengoto FLAG
end--查询ip是否被禁止访问,如果存在则返回403错误代码
is_block, err = conn:get(BUSINESS.."-BLOCK-"..ngx.var.remote_addr)  
if is_block == '1' thenngx.exit(403)goto FLAG
end--查询redis中保存的ip的计数器
ip_count, err = conn:get(BUSINESS.."-COUNT-"..ngx.var.remote_addr)if ip_count == ngx.null then --如果不存在,则将该IP存入redis,并将计数器设置为1、该KEY的超时时间为ip_time_outres, err = conn:set(BUSINESS.."-COUNT-"..ngx.var.remote_addr, 1)res, err = conn:expire(BUSINESS.."-COUNT-"..ngx.var.remote_addr, ip_time_out)
elseip_count = ip_count + 1 --存在则将单位时间内的访问次数加1if ip_count >= ip_max_count then --如果超过单位时间限制的访问次数,则添加限制访问标识,限制时间为ip_block_timeres, err = conn:set(BUSINESS.."-BLOCK-"..ngx.var.remote_addr, 1)res, err = conn:expire(BUSINESS.."-BLOCK-"..ngx.var.remote_addr, ip_block_time)elseres, err = conn:set(BUSINESS.."-COUNT-"..ngx.var.remote_addr,ip_count)res, err = conn:expire(BUSINESS.."-COUNT-"..ngx.var.remote_addr, ip_time_out)end
end-- 结束标记
::FLAG::
local ok, err = conn:close()

(2)在需要做访问限制的location里加两段代码即可,这里用刚才的/lua做演示

vim /usr/local/openresty/nginx/conf/nginx.conf


主要是添加如下配置:

access_by_lua_file /usr/local/openresty/nginx/conf/lua/access.lua;
其中,set $business “lua” 是为了把IP放进Redis的时候标明是哪个location的,可以不加这个配置。随后,重新reload配置。

(3)打开浏览器访问192.168.20.205/lua 并一直按F5刷新。

随后,连接Redis,查看IP的访问计数。
发现redis已经在统计访问lua这个网页ip的访问次数了

这个key的过期时间是30秒,如果30秒没有重复访问20次这个key就会消失,所以说正常用户一般不会触发这个封禁的脚本。

当30秒内访问超过了20次,发现触发脚本了,变成了403

再次查看Redis的key,发现多了一个lua-block-192.168.20.28,过期时间是300秒,就是说在300秒内这个ip无法继续访问192.168.20.205/lua这个页面了。

过五分钟后再去访问这个页面,又可以访问了。

这个脚本的目的很简单:一个IP如果在30秒内其访问次数达到20次则表明该IP访问频率太快了,因此将该IP封禁5分钟。同时由于计数的KEY在Redis中的超时时间设置成了30秒,所以如果两次访问间隔时间大于30秒将会重新开始计数。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/58308.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[Linux] linux 软硬链接与动静态库

标题:[Linux] linux 软硬链接与动静态库 个人主页水墨不写bug (图片来源于网络) /** _oo0oo_* o8888888o* 88" . "88* (| -_- |)* …

通过cv库智能切片 把不同的分镜切出来 自媒体抖音快手混剪

用 手机自动化脚本,从自媒体上获取视频,一个商品对应几百个视频,我们把这几百个视频下载下来,进行分镜 视频切片,从自媒体上下载视频,通过cv库用直方图识别每个镜头进行切片。 下载多个图片进行视频的伪原…

学习threejs,使用粒子实现下雪特效

👨‍⚕️ 主页: gis分享者 👨‍⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍⚕️ 收录于专栏:threejs gis工程师 文章目录 一、🍀前言1.1 ☘️THREE.Points简介1.11 ☘️…

C++之多态的深度剖析

目录 前言 1.多态的概念 2.多态的定义及实现 2.1多态的构成条件 2.1.1重要条件 2.1.2 虚函数 2.1.3 虚函数的重写/覆盖 2.1.4 选择题 2.1.5 虚函数其他知识 协变(了解) 析构函数的重写 override 和 final关键字 3. 重载,重写&…

Codeforces Round 919 (Div. 2)

B. Summation Game 题意 输入 输出 思路 遇到两人博弈问题&#xff0c;可以分别贪心&#xff0c;先贪心一个固定下来&#xff0c;然后遍历贪心另一个人 void solve() {int n, k, x;cin >> n >> k >> x;vector<int> arr(n 1);int *s new int[n …

GIT分布式版本控制系统基础操作

问题大纲 1、什么分布式版本控制系统 2、简述Git的使用分为哪几个步骤 3、克隆和拉取的区别是什么&#xff1f; 4、git相关的所有指令 一、分布式版本控制系统 分布式版本控制系统是一种版本控制系统&#xff0c;它允许每个用户都拥有完整的项目历史记录和版本控制信息。与…

【linux网络编程】| socket套接字 | 实现UDP协议聊天室

前言&#xff1a;本节内容将带友友们实现一个UDP协议的聊天室。 主要原理是客户端发送数据给服务端。 服务端将数据再转发给所有链接服务端的客户端。 所以&#xff0c; 我们主要就是要实现客户端以及服务端的逻辑代码。 那么&#xff0c; 接下来开始我们的学习吧。 ps:本节内容…

vivo 轩辕文件系统:AI 计算平台存储性能优化实践

在早期阶段&#xff0c;vivo AI 计算平台使用 GlusterFS 作为底层存储基座。随着数据规模的扩大和多种业务场景的接入&#xff0c;开始出现性能、维护等问题。为此&#xff0c;vivo 转而采用了自研的轩辕文件系统&#xff0c;该系统是基于 JuiceFS 开源版本开发的一款分布式文件…

Java | Leetcode Java题解之第520题检测大写字母

题目&#xff1a; 题解&#xff1a; class Solution {public boolean detectCapitalUse(String word) {// 若第 1 个字母为小写&#xff0c;则需额外判断第 2 个字母是否为小写if (word.length() > 2 && Character.isLowerCase(word.charAt(0)) && Charact…

如何封装一个可取消的 HTTP 请求?

前言 你可能会好奇什么样的场景会需要取消 HTTP 请求呢&#xff1f; 确实在实际的项目开发中&#xff0c;可能会很少有这样的需求&#xff0c;但是不代表没有&#xff0c;比如&#xff1a; 假如要实现上述这个公告栏&#xff0c;每点击一个 tab 按钮就会切换展示容器容器中…

图的最短路径算法-迪杰斯特拉(Dijkstra)算法与弗洛伊德(Frolyd)算法(更新中)

一、最短路径算法&#xff08;Shortest Path&#xff09; 最短路径问题是图论研究中的一个经典算法问题&#xff0c;旨在寻找图&#xff08;由结点和路径组成的&#xff09;中两结点之间的最短路径。 最短路径不一定是经过边最少的路径&#xff0c;但在这些最短路径中&#x…

ubuntu编译ffmpeg

配置 运行环境&#xff1a;vmware ubuntu 20.04 时间&#xff1a;2024年10月24日 权限问题&#xff1a;由于ubuntu权限问题 建议使用root权限编译&#xff0c;且~是根据用户组来进行定位的。 环境配置更新 cd ~ && \ mkdir ffmpeg_sources ffmpeg_build bin &…

EasyExcel自定义下拉注解的三种实现方式

文章目录 一、简介二、关键组件1、ExcelSelected注解2、ExcelDynamicSelect接口&#xff08;仅用于方式二&#xff09;3、ExcelSelectedResolve类4、SelectedSheetWriteHandler类 三、实际应用总结 一、简介 在使用EasyExcel设置下拉数据时&#xff0c;每次都要创建一个SheetWr…

【vs2022】windows可用的依赖预编译库

ffmpeg 、x264 、x265 等。obs是基于qt6+vs2022+64bit obs的官网传统构建已经不用了obs的s2022构建OBS Deps Build 2024-09-12FFmpeg4.4 库,x64 可用。

每天五分钟深度学习pytoroch:基于pytorch搭建逻辑回归算法模型

本文重点 前面我们学习了线性回归模型的搭建,无论是基于pytorch还是不基于pytorch,以上的模型都是回归模型,本文我们将使用pytorch搭建逻辑回归模型,逻辑回归模型是一个经典的分类问题。 模型搭建 class LogisticRegression(nn.Module) : def __init__(self) :super (Lo…

玩转Docker | 使用Docker部署推箱子网页小游戏

玩转Docker | 使用Docker部署推箱子网页小游戏 一、项目介绍项目简介项目预览 二、系统要求环境要求环境检查Docker版本检查检查操作系统版本 三、部署推箱子网页小游戏下载镜像创建容器检查容器状态检查服务端口安全设置 四、访问推箱子网页小游戏五、总结 一、项目介绍 项目…

Iperius Backup(数据备份软件) v8.3.0 中文免费版

下载&#xff1a; 【1】https://pan.quark.cn/s/19ef716c02d5 【2】https://drive.uc.cn/s/197acba8d8d94?public1 Iperius Backup是一款专业的备份还原软件&#xff0c;功能强大&#xff0c;支持DAT备份、LTO备份、NAS备份、磁带备份、RDX驱动器、USB备份&#xff0c;满足用…

K8S测试pod内存和CPU资源不足

只设置requests参数 mysql主从pod启动后监控 读压测之后 同时设置limits和requests&#xff0c;只调低内存值 监控 压力测试 同时设置limits和requests&#xff0c;只调低CPU值 初始状态 开始压测 结论 对于CPU&#xff0c;如果pod中服务使用CPU超过设置的limits&…

谷歌云GCP基础概念讲解

概览 云的基础是虚拟化&#xff1a;服务器&#xff0c;存储&#xff0c;网络。服务器是远程计算机的逻辑分区。存储是物理硬盘的逻辑划分。网络则是虚拟私有云。 谷歌是唯一一个拥有全球私有基础设施的公司&#xff1b;他们的谷歌云基础设施没有任何一部分通过公共互联网。换句…

Python 爬虫的寻宝大冒险:如何捕获 API 数据的宝藏

在这个信息爆炸的数字时代&#xff0c;数据就像是隐藏在网络深处的宝藏&#xff0c;等待着勇敢的探险家去发现。今天&#xff0c;我们要讲述的是如何成为一名 Python 爬虫探险家&#xff0c;装备你的代码工具&#xff0c;深入 API 的迷宫&#xff0c;捕获那些珍贵的数据宝藏。 …