nginx|openresty配置lua脚本自动封ip

打印 上一主题 下一主题

主题 995|帖子 995|积分 2985

本文不举行介绍怎么安装lua环境、openresty预安装有lua脚本运行环境、nginx必要自行编译;
本文会把黑名单ip界说在文件中,步伐运行时定时覆盖内容到内存中,提拔运行速度
1、nginx.conf配置加载lua
  1. #WAF
  2. lua_shared_dict blist 50m;
  3. init_worker_by_lua_file "/usr/local/openresty/nginx/conf/lua/init.lua";
  4. access_by_lua_file "/usr/local/openresty/nginx/conf/lua/blacklist.lua";
复制代码
lua_shared_dict blist 作用:创建一个共享内存字典,定名为 blist(存储黑名单ip信息)
init_worker_by_lua_file 作用:初始化全局变量或其他 Lua 模块
access_by_lua_file 作用:在 access 阶段(哀求访问控制阶段)运行指定的 Lua 脚本
获取访问进来的ip地点(兼容ipv4和ipv6)
  1. map $http_x_forwarded_for  $realip
  2. {
  3.   ""    $remote_addr;
  4.   ##兼容ipv4及ipv6,兼容特殊格式ipv6
  5.    "~*(?P<firstAddr>([0-9a-f]{0,4}:){1,7}[0-9a-f]{1,4}|([0-9]{1,3}\.){3}[0-9]{1,3})" $firstAddr;
  6. }
复制代码
把获取到的ip界说变量为$realip,后续脚本会调用
2、配置init.lua和blacklist.lua脚本

init.lua
  1.     local function load_blacklist_to_shared_memory()
  2.         local file, err = io.open("/usr/local/openresty/nginx/conf/waf/rule-config/iplist.txt", "r")
  3.         if not file then
  4.             ngx.log(ngx.ERR, "failed to open blacklist file: ", err)
  5.             return
  6.         end
  7.         -- 检查文件是否为空
  8.         local is_empty = true
  9.         for _ in file:lines() do
  10.             is_empty = false
  11.             break
  12.         end
  13.         if is_empty then
  14.             ngx.log(ngx.ERR, "blacklist file is empty")
  15.             file:close()
  16.             return
  17.         end
  18.         -- 文件非空时重新打开文件并加载数据
  19.         file:seek("set", 0)
  20.         local dict = ngx.shared.blist
  21.         dict:flush_all()  -- 清空共享内存,重新加载
  22.         for line in file:lines() do
  23.             dict:set(line, true)
  24.         end
  25.         file:close()
  26.     end
  27.     local function refresh_blacklist(premature)
  28.         if premature then
  29.             return
  30.         end
  31.         load_blacklist_to_shared_memory()
  32.         ngx.log(ngx.INFO, "Blacklist reloaded successfully.")
  33.         -- 重新设置定时器
  34.         local ok, err = ngx.timer.at(5, refresh_blacklist)
  35.         if not ok then
  36.             ngx.log(ngx.ERR, "Failed to create timer: ", err)
  37.         end
  38.     end
  39.     -- 初始化时加载黑名单
  40.     load_blacklist_to_shared_memory()
  41.     -- 设置定时器
  42.     local ok, err = ngx.timer.at(5, refresh_blacklist)
  43.     if not ok then
  44.         ngx.log(ngx.ERR, "Failed to create timer: ", err)
  45.     end
复制代码
定时器是5秒钟重新到黑名单文件读取ip写到内存中
blacklist.lua
  1.     -- 加载黑名单数据到共享内存
  2.     local function load_blacklist_to_shared_memory()
  3.         local file, err = io.open("/usr/local/openresty/nginx/conf/waf/rule-config/iplist.txt", "r")
  4.         if not file then
  5.             ngx.log(ngx.ERR, "failed to open blacklist file: ", err)
  6.             return false
  7.         end
  8.         -- 检查文件是否为空
  9.         local is_empty = true
  10.         for _ in file:lines() do
  11.             is_empty = false
  12.             break
  13.         end
  14.         if is_empty then
  15.             ngx.log(ngx.ERR, "blacklist file is empty")
  16.             file:close()
  17.             return false
  18.         end
  19.         -- 文件非空时重新打开文件并加载数据
  20.         file:seek("set", 0)
  21.         local dict = ngx.shared.blist
  22.         dict:flush_all()  -- 清空共享内存,重新加载
  23.         for line in file:lines() do
  24.             dict:set(line, true)
  25.         end
  26.         file:close()
  27.         return true
  28.     end
  29.     -- 检查 IP 是否在黑名单中
  30.     local function check_blacklist(ip)
  31.         local dict = ngx.shared.blist
  32.         return dict:get(ip)
  33.     end
  34.     -- 获取客户端 IP
  35.     local function get_client_ip()
  36.         return ngx.var.realip or "unknown"
  37.     end
  38.     -- 主逻辑
  39.     -- local blacklist_loaded = load_blacklist_to_shared_memory()
  40.     local client_ip = get_client_ip()
  41.     if  check_blacklist(client_ip) then
  42.         ngx.log(ngx.ERR, "IP " .. client_ip .. " is blacklisted")
  43.         ngx.exit(ngx.HTTP_FORBIDDEN)
  44.     end
  45.     -- 根据请求路径分发处理逻辑
  46.     local uri = ngx.var.uri
  47.     if uri == "/reload-blacklist" then
  48.         -- 添加 IP 条件判断
  49.         local allowed_ip_prefix = "172.31"
  50.         local client_ip_prefix = string.sub(client_ip, 1, #allowed_ip_prefix)
  51.         if client_ip_prefix ~= allowed_ip_prefix then
  52.             ngx.log(ngx.ERR, "Access forbidden for IP: " .. client_ip)
  53.             ngx.exit(ngx.HTTP_FORBIDDEN)
  54.         end
  55.         -- 重新加载黑名单到共享内存
  56.         local reloaded = load_blacklist_to_shared_memory()
  57.         if reloaded then
  58.             ngx.say("Blacklist reloaded successfully.")
  59.         else
  60.             ngx.say("Blacklist file not found or is empty. No changes made.")
  61.         end
  62.     end
复制代码
可以自界说访问reload-blacklist路径的url就举行革新黑名单ip,allowed_ip_prefix对访问进来的ip举行白名单限制
最后界说iplist.txt就可以了,每个ip为一行,init.lua和blacklist.lua中用io.open界说iplist.txt的路径

iplist.txt
  1. 1.2.3.4
  2. 1a:d8:eb:42:91:f8
复制代码
举行reload步伐就可以利用了,在这个自动化的基础上,配合日志体系,根据自界说规则就可以自动化的屏蔽异常ip;
异常ip输出到error日志中

博主利用过loki日志体系和elk日志体系,都可以根据一定时间内ip次数到达多少就自动屏蔽ip;运维以后不再半夜起床排查异常ip;
后续更新这篇博客,到场跳转链接,敬请等待;

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

数据人与超自然意识

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表