openresty+redis配合 lua指令碼封停 IP

杨梅冲發表於2024-09-04

1.安裝openresty-1.21.4.4

tar -xzvf openresty-1.21.4.4.tar.gz
cd openresty-1.21.4.4
mkdir modules

# 到 github中下載ngx_cache_purge-2.3,解壓後放到 modules裡面
wget http://labs.frickle.com/files/ngx_cache_purge-2.3.tar.gz


# 編譯安裝 openresty
./configure --prefix=/usr/local/openresty-1.21.4.4 --with-http_ssl_module --with-debug --with-http_realip_module --with-http_gzip_static_module --with-http_stub_status_module --with-luajit --with-http_iconv_module --with-stream --with-stream_ssl_module --with-threads --with-http_gunzip_module --with-http_mp4_module --with-http_dav_module --with-http_sub_module --with-http_random_index_module --with-http_flv_module --with-http_auth_request_module --with-http_addition_module --with-http_v2_module --with-pcre  --with-pcre-jit --without-http_redis2_module --with-http_geoip_module --with-http_secure_link_module --with-mail --with-mail_ssl_module --with-http_postgres_module --add-module=/usr/local/download/openresty-1.21.4.4/modules/ngx_cache_purge-2.3

gmake
gmake install

2.安裝 redis

自己安裝並設定密碼

3.lua指令碼設定

指令碼網上一堆,自己測試下

cd /usr/local/openresty-1.21.4.4
mkdir lua

cat ipblock.lua

ip_bind_time = 30  --封禁IP多長時間
ip_time_out = 10    --指定統計ip訪問頻率時間範圍
connect_count = 10 --指定ip訪問頻率計數最大值
--上面的意思就是10秒內訪問超過10次,自動封 IP 30秒,實際測試下來 6 次就封了。
 
--連線redis
local redis = require "resty.redis"
local cache = redis.new()
local ok , err = cache.connect(cache,"10.1.1.240","6380")
-- redis密碼
local res, err = cache:auth("wg1q2w3e")
cache:set_timeout(60000)
 
--如果連線失敗,跳轉到指令碼結尾
if not ok then
  goto Lastend
end
 
--查詢ip是否在封禁段內,若在則返回403錯誤程式碼
--因封禁時間會大於ip記錄時間,故此處不對ip時間key和計數key做處理
is_bind , err = cache:get("bind_"..ngx.var.remote_addr)
 
if is_bind == '1' then
  ngx.exit(ngx.HTTP_FORBIDDEN)
  -- 或者 ngx.exit(403)
  -- 當然,你也可以返回500錯誤啥的,搞一個500頁面,提示,親您訪問太頻繁啥的。
  goto Lastend
end
 
start_time , err = cache:get("time_"..ngx.var.remote_addr)
ip_count , err = cache:get("count_"..ngx.var.remote_addr)
 
--如果ip記錄時間大於指定時間間隔或者記錄時間或者不存在ip時間key則重置時間key和計數key
--如果ip時間key小於時間間隔,則ip計數+1,且如果ip計數大於ip頻率計數,則設定ip的封禁key為1
--同時設定封禁key的過期時間為封禁ip的時間
 
if start_time == ngx.null or os.time() - 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)
  if ip_count >= connect_count then
    res , err = cache:set("bind_"..ngx.var.remote_addr,1)
    res , err = cache:expire("bind_"..ngx.var.remote_addr,ip_bind_time) --fix keys
  end
end
--結尾標記
::Lastend::
local ok, err = cache:close()

4.openreststy啟動

cat localhost.conf 
server {
    listen 80;
    server_name localhost;

    location / {
        root html;
        index index.html index.htm;
        access_by_lua_file "/usr/local/openresty-1.21.4.4/lua/ipblock.lua";
    }

    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
        root html;          
    }
    access_log /data/logs/nginx/localhost_acc.log;
    error_log /data/logs/nginx/localhost_err.log;
}

5.訪問並檢視 redis資料

http://IP 統計重新整理次數,檢視日誌

檢視 redis

相關文章