nginx lua redis 访问频率限制(转)

1. 需求分析

Nginx来处理访问控制的方法有多种,实现的效果也有多种,访问IP段,访问内容限制,访问频率限制等。

用Nginx+Lua+Redis来做访问限制主要是考虑到高并发环境下快速访问控制的需求。

Nginx处理请求的过程一共划分为11个阶段,分别是:

post-read、server-rewrite、find-config、rewrite、post-rewrite、 preaccess、access、post-access、try-files、content、log.

在openresty中,可以找到:

set_by_lua,access_by_lua,content_by_lua,rewrite_by_lua等方法。

那么访问控制应该是,access阶段。

解决方案

按照正常的逻辑思维,我们会想到的访问控制方案如下:

1.检测是否被forbidden?
=》是,forbidden是否到期:是,清除记录,返回200,正常访问;否,返回403;
=》否,返回200,正常访问

2.每次访问,访问用户的访问频率+1处理

3.检测访问频率是否超过限制,超过即添加forbidden记录,返回403

这是简单地方案,还可以添加点枝枝叶叶,访问禁止时间通过算法导入,每次凹曲线增加。

实现方法

首先为nginx添加vhost配置文件,vhost.conf部分内容如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

lua_package_path "/usr/local/openresty/lualib/?.lua;;";#告诉openresty库地址

lua_package_cpath "/usr/local/openresty/lualib/?.so;;";

error_log /usr/local/openresty/nginx/logs/openresty.debug.log debug;

server {

listen 8080 default;

server_name www.ttlsa.com;

root  /www/openresty;

location /login {

default_type ‘text/html‘;

access_by_lua_file "/usr/local/openresty/nginx/lua/access_by_redis.lua";#通过lua来处理访问控制

}

}

Access_by_redis.lua

参考了下v2ex.com的做法,redis存储方案只做简单地string存储就足够了。key分别是:

用户登录记录:user:127.0.0.1:time(unix时间戳)
访问限制:block:127.0.0.1

先连接Redis吧:

1

2

3

4

5

6

7

8

local red = redis:new()

function M:redis()

red:set_timeout(1000)

local ok, err = red:connect("127.0.0.1", 6379)

if not ok then

ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)

end

end

按照我们的逻辑方案,第二步是,检测是否forbidden,下面我们就检测block:127.0.0.1,如果搜索到数据,检测时间是否过期,未过期返回403,否则直接返回200:

1

2

3

4

5

6

7

8

9

10

11

12

13

function M:check1()

local time=os.time() --system time

local res, err = red:get("block:"..ngx.var.remote_addr)

if not res then -- redis error

ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) --redis get data error end

if type(res) == "string" then --if red not null then type(red)==string

if tonumber(res) >= tonumber(time) then  --check if forbidden expired

ngx.exit(ngx.HTTP_FORBIDDEN)

--ngx.say("forbidden")

end

end

}

接下来会做检测,是否访问频率过高,如果过高,要拉到黑名单的,

实现的方法是,检测user:127.0.0.1:time的值是否超标:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

function M:check2()

local time=os.time() --system time

local res, err = red:get("user:"..ngx.var.remote_addr..":"..time)

if not res then -- redis error

ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) --redis get data error

end

if type(res) == "string" then

if tonumber(res) >= 10 then -- attack, 10 times request/s

red:del("block:"..self.ip)

red:set("block:"..self.ip, tonumber(time)+5*60 ) --set block time

ngx.exit(ngx.HTTP_FORBIDDEN)

end

end

end

最后呢,还要记得,把每次访问时间做一个自增长,user:127.0.0.1:time

1

2

3

4

5

6

7

function M:add()

local time=os.time() --system time

ok, err = red:incr("user:"..ngx.var.remote_addr..":"..time)

if not ok then

ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR) --redis get data error

end

end

那么,测试,强刷几次浏览器,发现过一会,返回了403,ok,搞定。

https://www.ttlsa.com/nginx/nginx-lua-redis-access-frequency-limit/

时间: 2024-08-07 00:09:17

nginx lua redis 访问频率限制(转)的相关文章

nginx+lua+redis实现验证码防采集

之前介绍过在nginx里如何嵌入lua模块,利用nginx+lua可以很好的开发开发nginx的业务逻辑,并且达到高并发的效果. 下面我们就来介绍下利用nginx+lua+redis实现防采集的功能. 现象: 网站在为用户提供服务的同时也在被搜索引擎.采集器不断的抓取,可能会造成网站不堪重负,导致页面放回5XX错误.针对此种情况,我们就要对采集器及搜索引擎来进行访问控制,当然对搜索引擎的控制可能会影响网站的收录. 功能描述: nginx+lua在前端实现客户端的访问控制,将客户端的访问信息记入r

Nginx+Lua+Redis 对请求进行限制

Nginx+Lua+Redis 对请求进行限制 一.概述 需求:所有访问/myapi/**的请求必须是POST请求,而且根据请求参数过滤不符合规则的非法请求(黑名单), 这些请求一律不转发到后端服务器(Tomcat) 实现思路:通过在Nginx上进行访问限制,通过Lua来灵活实现业务需求,而Redis用于存储黑名单列表. 相关nginx上lua或redis的使用方式可以参考我之前写的一篇文章: openresty(nginx).lua.drizzle调研 http://www.cnblogs.c

nginx+php+redis vs nginx+lua+redis

最近在做通知系统,前端用的轮询方式(后端压力不小),因为时间比较紧,开始我准备把未读通知标识存在数据库中,但是每次拿数据的时候需要查询一遍数据库,总监说你这样效率较低,说你可以根据用户id作为key放在redis中存储.说说自己在做这个的一些体会和闲下来总结的一些笔记. phpredis connect pconnect 我最开始使用的是connect,每次请求完毕关闭连接 1 <?php 2 $redis = new Redis(); 3 $nError = $redis->connect(

Nginx+Lua+Redis配置

想在Nginx上开发具有这样功能的一个转发模块,外部转发策略控制服务器将一些指定的URL发送给数据库,Nginx读取数据库中的URL列表,将列表指定的这些URL转发到特定的缓存代理服务器上,其他非数据库URL列表中的URL请求直接通过Nginx转发到出口网关上.实际上以上的功能就是很多网站利用Nginx做负载均衡时的实现的七层转发功能,不太一样的是,我想加一个外部的转发策略控制服务器将一些实时的URL列表发送给Nginx,这样如果这些URL信息是根据大数据处理结果统计出的最高热点访问URL,就可

nginx+lua+redis实现灰度发布_test

nginx+lua+redis实现灰度发布: 灰度发布是指在黑白之间能够平滑过渡的一种方式 AB test就是一种灰度发布方式,让一部分用户继续用A,一部分用户开始用B,如果用户对B没有什么反对意见,那么逐步扩大范围,把所有用户都迁移到B上面 来.灰度发布可以保证整体系统的稳定,在初始灰度的时候就可以发现.调整问题,以保证其影响度. 灰度发布可以保证应用系统的稳定,降低产品升级影响的用户范围:也可以按照一定的策略让部分用户提前参与产品测试,从而提早获取到用户的反馈,完善应用功能 原理:使用ngi

nginx+lua+redis(openresty)配置

nginx+lua+redis(openresty)配置 2014-07-18 11:10 2494人阅读 评论(1) 收藏 举报 方案一: 1.安装lua解释器 wget http://luajit.org/download/LuaJIT-2.0.2.tar.gz (http://luajit.org/download.html) 配置lua Lib和include/luajit-$version目录为环境变量 2.下载ngx_devel_kit和lua-nginx-module https:

nginx+lua+redis构建高并发应用(转)

nginx+lua+redis构建高并发应用 ngx_lua将lua嵌入到nginx,让nginx执行lua脚本,高并发,非阻塞的处理各种请求. url请求nginx服务器,然后lua查询redis,返回json数据. 备注:centos或者redhat系统请跳转到nginx + ngx_lua安装测试 一.安装lua 1 2 3 # apt-get install lua5.1 # apt-get install liblua5.1-dev # apt-get install liblua5.

Nginx+Lua+Redis整合实现高性能API接口 - 网站服务器 - LinuxTone | 运维专家网论坛 - 最棒的Linux运维与开源架构技术交流社区! - Powered by Discuz!

Nginx+Lua+Redis整合实现高性能API接口 - 网站服务器 - LinuxTone | 运维专家网论坛 - 最棒的Linux运维与开源架构技术交流社区! - Powered by Discuz! log.latermoon.com/

nginx+lua+redis构建高并发应用

ngx_lua将lua嵌入到nginx,让nginx执行lua脚本,高并发,非阻塞的处理各种请求. url请求nginx服务器,然后lua查询redis,返回json数据. 一.安装lua-nginx-module 参见<LNMLGC>架构 二.安装redis2-nginx-module模块 get https://github.com/openresty/echo-nginx-module get https://github.com/openresty/redis2-nginx-modul