1. 程式人生 > >nginx + lua 限制訪問

nginx + lua 限制訪問

lua nginx

local redis = require ‘resty.redis‘ local cache = redis.new() local ok ,err = cache.connect(cache,‘127.0.0.1‘,‘6379‘) cache:set_timeout(60000) -- 如果連接失敗,跳轉到label處 if not ok then goto label end -- 白名單 is_white ,err = cache:sismember(‘whitelist‘,ngx.var.remote_addr) if is_white == 1 then goto label end -- 黑名單 is_black ,err = cache:sismember(‘blacklist‘,ngx.var.remote_addr) if is_black == 1 then ngx.exit(ngx.HTTP_FORBIDDEN) goto label end ip_forum_edittopic, err = cache:get(‘ip_forum_edittopic:‘ .. ngx.var.remote_addr) if ip_forum_edittopic == ngx.null then res , err = cache:set(‘ip_forum_edittopic:‘ .. ngx.var.remote_addr, 1) res , err = cache:expire(‘ip_forum_edittopic:‘ .. ngx.var.remote_addr, 43200) -- 12h重置 end is_forum_ban , err = cache:get(‘ip_forum_edittopic:‘ .. ngx.var.remote_addr) if tonumber(is_forum_ban) > 80 then local source = ngx.encode_base64(ngx.var.scheme .. ‘://‘ .. ngx.var.host .. ‘:‘ .. ngx.var.server_port .. ngx.var.request_uri) local dest = ‘http://127.0.0.1:5000/‘ .. ‘?continue=‘ .. source ngx.redirect(dest,302) goto label else res , err = cache:incr(‘ip_forum_edittopic:‘ .. ngx.var.remote_addr) end -- ip訪問頻率時間段 ip_time_out = 60 -- ip訪問頻率計數最大值 connect_count = 45 -- 60s內達到45次就ban -- 封禁ip時間(加入突曲線增長算法) ip_ban_time, err = cache:get(‘ip_ban_time:‘ .. ngx.var.remote_addr) if ip_ban_time == ngx.null then ip_ban_time = 300 res , err = cache:set(‘ip_ban_time:‘ .. ngx.var.remote_addr, ip_ban_time) res , err = cache:expire(‘ip_ban_time:‘ .. ngx.var.remote_addr, 43200) -- 12h重置 end -- 查詢ip是否在封禁時間段內,若在則跳轉到驗證碼頁面 is_ban , err = cache:get(‘ban:‘ .. ngx.var.remote_addr) if tonumber(is_ban) == 1 then -- source攜帶了之前用戶請求的地址信息,方便驗證成功後返回原用戶請求地址 local source = ngx.encode_base64(ngx.var.scheme .. ‘://‘ .. ngx.var.host .. ‘:‘ .. ngx.var.server_port .. ngx.var.request_uri) local dest = ‘http://127.0.0.1:5000/‘ .. ‘?continue=‘ .. source ngx.redirect(dest,302) goto label end -- ip記錄時間key start_time , err = cache:get(‘time:‘ .. ngx.var.remote_addr) -- ip計數key ip_count , err = cache:get(‘count:‘ .. ngx.var.remote_addr) -- 如果ip記錄時間的key不存在或者當前時間減去ip記錄時間大於指定時間間隔,則重置時間key和計數key -- 如果當前時間減去ip記錄時間小於指定時間間隔,則ip計數+1, -- 並且ip計數大於指定ip訪問頻率,則設置ip的封禁key為1,同時設置封禁key的過期時間為封禁ip時間 if start_time == ngx.null or os.time() - tonumber(start_time) > ip_time_out then res , err = cache:set(‘time:‘ .. ngx.var.remote_addr , os.time()) res , err = cache:set(‘count:‘ .. ngx.var.remote_addr , 1) else ip_count = ip_count + 1 res , err = cache:incr(‘count:‘ .. ngx.var.remote_addr) -- 統計當日訪問ip集合 res , err = cache:sadd(‘statistic_total_ip:‘ .. os.date(‘%x‘), ngx.var.remote_addr) if ip_count >= connect_count then res , err = cache:set(‘ban:‘ .. ngx.var.remote_addr , 1) res , err = cache:expire(‘ban:‘ .. ngx.var.remote_addr , ip_ban_time) res , err = cache:incrby(‘ip_ban_time:‘ .. ngx.var.remote_addr, ip_ban_time) -- 統計當日屏蔽ip總數 res , err = cache:sadd(‘statistic_ban_ip:‘ .. os.date(‘%x‘), ngx.var.remote_addr) end end ::label:: local ok , err = cache:close()

nginx + lua 限制訪問