\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.
In openresty, you can find:
set_by_lua,access_by_lua,content_by_lua,rewrite_by_lua等方法。
Then the access control should be , access stage.
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.
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来处理访问控制 } }
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
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 }
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
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
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!