Home > Database > Redis > How to use lua for nginx redis access control

How to use lua for nginx redis access control

王林
Release: 2023-06-02 16:31:15
forward
970 people have browsed it

怎么使用lua进行nginx redis访问控制

1. Requirements analysis

\1. There are many ways for Nginx to handle access control, and there are also many implementation effects. Access IP segments, Access content restrictions, access frequency restrictions, etc.

\2. Using Nginx Lua Redis for access restriction mainly takes into account the need for fast access control in high concurrency environments.

\3. The process of Nginx processing requests is divided into 11 stages, which are:

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

In openresty, you can find:

set_by_lua,access_by_lua,content_by_lua,rewrite_by_lua等方法。
Copy after login

Then the access control should be , access stage.

Solution

According to normal logical thinking, the access control solution we would think of is as follows:

1. Detect whether it is forbidden? =》Yes, whether forbidden has expired: Yes, clear the record, return 200, normal access; No, return 403; =》No, return 200, normal access

2. Each visit, visit the user's visit Frequency 1 processing

3. Check whether the access frequency exceeds the limit. If it exceeds the limit, add a forbidden record and return 403

This is a simple solution. You can also add branches and leaves, and the access prohibition time is passed The algorithm is imported, and each time the concave curve increases.

Implementation method

First add the vhost configuration file for nginx. The vhost.conf part is as follows:

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来处理访问控制   }
}
Copy after login

Access_by_redis.lua

After referring to the implementation of v2ex.com, we found that using a simple string storage solution is enough, so we chose redis as the storage method. The keys are:

User login record: user:127.0.0.1:time (unix timestamp)

Access restrictions: block:127.0.0.1

Connect to Redis first :

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
Copy after login

According to our logical plan, the second step is to detect whether it is forbidden. Next, we will detect block:127.0.0.1. If the data is searched, check whether the time has expired. If it has not expired, 403 will be returned. Otherwise, directly Return 200:

function M:check1()local time=os.time() --system timelocal 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  endif 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
}
Copy after login

The next step will be to check whether the access frequency is too high. If it is too high, it will be blacklisted.

The implementation method is to detect user:127.0.0.1 Whether the value of :time exceeds the standard:

function M:check2()local time=os.time() --system timelocal 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
endif 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
Copy after login

Finally, remember to make an auto-increment in the time of each access, 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
Copy after login

Then, test, I swiped the browser several times and found that after a while, 403 was returned. OK, done.

The above is the detailed content of How to use lua for nginx redis access control. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:yisu.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template