1 系统环境
test@iZbp1g7fmjea77vsqc5hmmZ:~$ cat /etc/os-release
PRETTY_NAME="Ubuntu 22.04.4 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.4 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy
#
test@iZbp1g7fmjea77vsqc5hmmZ:~$ /usr/local/openresty/nginx/sbin/nginx -v
nginx version: openresty/1.25.3.1
#
test@iZbp1g7fmjea77vsqc5hmmZ:~$ redis-cli -v
redis-cli 7.3.240
2 修改nginx配置
#更加实际情况修改相关配置文件server {listen 80;server_name localhost;#charset koi8-r;#access_log logs/host.access.log main;location / {root html;index index.html index.htm;access_by_lua_file "/usr/local/openresty/nginx/lua/access_limit.lua";#封禁lua文件}#error_page 404 /404.html;# redirect server error pages to the static page /50x.html#error_page 500 502 503 504 /50x.html;location = /50x.html {root html;}
3 lua配置文件
sudo vim /usr/local/openresty/nginx/lua/access_limit.lua
package.path = '/usr/local/openresty/lualib/resty/?.lua;'
function get_client()local redis = require "redis"client = redis:new()client:set_timeout(300000) -- 1 secondclient:set_keepalive(600000, 200)local ip = '172.16.195.13'local port = 6379local redis_db = 11local ok, err = client:connect(ip,port)if not ok thenreturn nil, "failed to connect."endlocal ok1,err = client:auth("password")if not ok1 thenreturn nil, "failed to authenticate."endclient:select(redis_db)return client, nil
endfunction auth(client, sid)key = ":1:"..sidlocal res, err = client:get(key)return res, nil
end
local function getIp()local clientIP = ngx.req.get_headers()["X-Real-IP"]if clientIP == nil thenclientIP = ngx.req.get_headers()["x_forwarded_for"]endif clientIP == nil thenclientIP = ngx.var.remote_addrendreturn clientIP
end
local clientip = getIp()
local incrKey = "ipcount:"..clientip
local blockKey = "iplimit:"..clientip
client, err = get_client()
if err thenngx.log(ngx.ERR, "connect redis error:", err)ngx.status = 500--ngx.say("{\"detail\":\"server error\"}")ngx.say("{\"detail\":\"redis sid no !\"}")return
end
local is_block,err = client:get(blockKey)
if tonumber(is_block) == 1 thenngx.exit(403)--ngx.exit(ngx.HTTP_FORBIDDEN)client:close()
end
local ip_count, err = client:incr(incrKey)
if tonumber(ip_count) == 1 thenclient:expire(incrKey,1)
end
if tonumber(ip_count) > 9 thenclient:set(blockKey,1)client:expire(blockKey,7200) -- 封锁IP 2小时
end
client:close()
4 测试,正常访问不超过9次/秒
#如果每秒访问超过9次,如下
#查看redis
5 Redis incr 命令
#存储在指定key中的数值进行自增操作。 当执行INCR命令时,如果key不存在,Redis会创建一个新的key,并将其初始值设置为0,再进行自增操作。如果key的值可以被解释为一个整数,Redis会将其自增1,并返回自增后的值.
127.0.0.1:6379[11]> incr hihi