当前位置:首页 > 技术文章 > 正文内容

通过 lua 进行 nginx redis 访问控制

arlanguage3个月前 (01-26)技术文章26

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

1. 需求分析

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

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

3. 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部分内容如下:

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吧:

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:

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的值是否超标:

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

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.linuxprobe.com/lua-access-control-redis.html

扫描二维码推送至手机访问。

版权声明:本文由AR编程网发布,如需转载请注明出处。

本文链接:http://www.arlanguage.com/post/1142.html

分享给朋友:

“通过 lua 进行 nginx redis 访问控制” 的相关文章

服务器不能正常关机和重启是怎么回事?

服务器不能正常关机和重启是怎么回事?服务器无法正常关机或重启可能是由多种原因引起的,涉及操作系统、硬件、应用程序和配置设置等方面。以下是详细的原因分析及对应的解决方案。一、服务器无法关机/重启的常见原因1. 操作系统问题(1)系统进程未正常终止某些进程或服务在关机时未能按预期停止,导致系统卡在关机或...

高端Linux 脚本很有用,赶紧学起来!

Linux 脚本?准确的说叫 Linux Shell 脚本,Shell 脚本是一种被设计用来运行命令行解释器,他是 Linux 系统的一大特色之一。命令行是 Linux 系统中一种非常重要的交互方式,而它的实现基于 Linux 内核和 Shell 程序,为用户提供了强大和灵活的操作方式。使用 Lin...

php高并发的瓶颈到底在哪

php高并发的瓶颈到底在哪?是同步阻塞?还是nginx+fpm不断创建-销毁进程资源过度消耗?高并发到底是什么问题,是语言问题嘛,为什么说php不适合高并发?求大佬指点从2009年后一直用lnmp,从5.2.17一直到现在的PHP7.4,做的项目无数个,大到日IP10W+、PV50W+的平台,小到日...

解决Apache 2.4+PHP5.6不支持CURL

跑一个demo,突然发现,服务器上最普通的Apache 2.4+PHP5.6组合,不支持curl,报告没有curl_init函数;而php.ini里面已经打开了php_curl.dll,而且php -i的输出是正常的,说明curl是可以执行的。折腾了半天百思不得其解,最后索性把php5.6、apac...

php手把手教你做网站(二十四)jquery ajax上传大的附件

上传大的附件分为两种情况,可以改变服务器配置;不能改变配置;第2种使用分片上传优势:可以突破服务器上传大小的限制,可以web存储上传到哪一块了,在浏览器关闭或者刷新的情况下可以断点续传;劣势:上传速度慢,在我本地电脑测试,200M的文件,改变配置按照正常方式上传大约需要12到15秒,但是使用第2种分...

高性能Linux服务器构建实战:运维监控、性能调优与集群应用

百万级字迹详解实战案例,篇幅因素故只展现pdf目录,完整解析获取方式在篇尾了!目录读者对象Web应用篇(1至第3章)数据备份恢复篇(4至第6章)网络存储应用篇(7和第8章)运维监控与性能优化篇(9和第10章)集群高级应用篇(11至第14章)勘误和支持第1篇 Web应用篇1 、轻量级HTTP服务器Ng...