openresty+lua+redis把非正常访问的域名加入黑名单

[复制链接]
发表于 2025-7-9 01:29:06 | 显示全部楼层 |阅读模式
一、验证lua geoIp2是否缺少依靠

1、执行下令
  1. /usr/local/openresty/bin/opm get anjia0532/lua-resty-maxminddb
复制代码

执行安装下令报错,缺少Digest/MD5依靠
2、Digest/MD5依靠
  1. yum -y install perl-Digest-MD5
复制代码

GeoIP2 lua库依靠动态库安装,lua库依靠libmaxminddb实现对mmdb的高效访问
二、安装libmaxminddb数据库
  1. cd /data/file/
  2. wget https://github.com/maxmind/libmaxminddb/releases/download/1.12.2/libmaxminddb-1.12.2.tar.gz
  3. tar -zxf libmaxminddb-1.12.2.tar.gz
  4. cd libmaxminddb-1.12.2
  5. ./configure
  6. make && make install
  7. sh -c "echo /usr/local/lib  >> /etc/ld.so.conf.d/local.conf"
  8. ldconfig
复制代码
三、编写操作geoIp的lua脚本
  1. --引入Redis
  2. local redis = require "resty.redis";
  3. --引入rsa
  4. local rsa = require "resty.rsa";
  5. --引入maxminddb库
  6. local geo=require 'resty.maxminddb';
  7. --Redis链接ip
  8. local ip = "192.168.0.145"
  9. --Redis链接端口
  10. local port = 6379
  11. --Redis连接密码
  12. local pass = "aa123456"
  13. --鉴权Redis
  14. local function connAuth()
  15.         local red = redis:new();
  16.         local connCount, err = red:connect(ip, port);
  17.         if not connCount then
  18.                 ngx.say("failed to connect: ", err)
  19.                 close_redis(red)
  20.                 return
  21.         end
  22.         red:set_timeouts(2000);
  23.         local ok, err = red:auth(pass)
  24.         if not ok then
  25.                 ngx.say("failed to auth: ", err)
  26.                 close_redis(red)
  27.                 return
  28.         end
  29.         return red
  30. end
  31. --关闭Redis
  32. local function close_redis(red)
  33.     if not red then
  34.         return
  35.     end
  36.     --释放连接(连接池实现)
  37.     local pool_max_idle_time = 10000
  38.     local pool_size = 100
  39.     local ok, err = red:set_keepalive(pool_max_idle_time, pool_size)
  40.     if not ok then
  41.         ngx.say("set keepalive error : ", err)
  42.     end
  43. end
  44. --获取请求者IP
  45. local function getIp()
  46.     local clientIP = ngx.req.get_headers()["X-Real-IP"]
  47.     if clientIP == nil then
  48.         clientIP = ngx.req.get_headers()["x_forwarded_for"]
  49.     end
  50.     if clientIP == nil then
  51.         clientIP = ngx.var.remote_addr
  52.     end
  53.     return clientIP
  54. end
  55. --获取用户访问IP
  56. local clientIP = getIp();
  57. --封禁token时间(秒)
  58. local token_block_time= 120
  59. --指定token访问频率计数最大值(次)
  60. local token_max_count = 3
  61. --如果数据为空的情况下
  62. local function is_empty(value)
  63.     if type(value) == "table" then
  64.         return next(value) == nil
  65.     elseif type(value) == "string" then
  66.         return #value == 0
  67.     elseif type(value) == "nil" then
  68.         return true
  69.     end
  70.         return false
  71. end
  72. --过滤特殊字符串(只保留字母与数字,字母不区分大小写)
  73. local function filter_special_chars(s)
  74.     local ss = {}
  75.     local k = 1
  76.     while true do
  77.         if k > #s then break end
  78.         local c = string.byte(s,k)
  79.         if not c then break end
  80.         if c<192 then
  81.             if (c>=48 and c<=57) or (c>= 65 and c<=90) or (c>=97 and c<=122) then
  82.                 table.insert(ss, string.char(c))
  83.             end
  84.             k = k + 1
  85.         end
  86.     end
  87.     return table.concat(ss)
  88. end
  89. if not geo.initted() then
  90.         geo.init("/usr/share/GeoIP/GeoLite2-Country.mmdb")
  91. end
  92. --如果头部信息没有指定的参数或是指定参数的值无法解析,加入IP黑名单
  93. --如果同样的头部参数键在封禁token时间内连续访问指定token访问频率计数最大值次以上,加入IP黑名单
  94. local function set_blacklist()
  95.     local header = ngx.req.get_headers();
  96.     local red = connAuth();
  97.         -- 检测ip
  98.     local res,err=geo.lookup(clientIP)
  99.     if not res then
  100.             local res, err =  red:sismember('black-list', clientIP);
  101.         if res ~= 1 then
  102.             red:sadd('black-list', clientIP)
  103.         end
  104.         close_redis(red)
  105.         return ngx.exit(401)
  106.     else
  107.         for k,v in pairs(res) do
  108.             --只获取国家
  109.             if(k == "country") then
  110.                 --获取国家编码
  111.                 for key,item in pairs(v) do
  112.                     if (key=="iso_code" and "CN" ~= item) then
  113.                         local res, err =  red:sismember('black-list', clientIP);
  114.                         if res ~= 1 then
  115.                             red:sadd('black-list', clientIP)
  116.                         end
  117.                         close_redis(red)
  118.                         return ngx.exit(401)
  119.                     end
  120.                 end
  121.             end
  122.         end
  123.     end
  124. end
  125. -- 查看是否在黑名单里面
  126. local function get_blacklist()
  127.     local red = connAuth();
  128.     local res, err =  red:sismember('black-list', clientIP);
  129.     if res == 1 then
  130.         close_redis(red);
  131.         return ngx.exit(401);
  132.     end
  133.     close_redis(red);
  134. end
  135. get_blacklist();
  136. set_blacklist();
复制代码
四、nginx域名配置引用
  1. location / {
  2.         access_by_lua_file /data/wwwroot/rsa-redis.lua;
  3.         try_files $uri $uri/ /index.html;
  4.     }
复制代码
在你必要应用的地方加上就行

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

本帖子中包含更多资源

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

×
回复

使用道具 举报

© 2001-2025 Discuz! Team. Powered by Discuz! X3.5

GMT+8, 2025-7-25 07:36 , Processed in 0.080726 second(s), 31 queries 手机版|qidao123.com技术社区-IT企服评测▪应用市场 ( 浙ICP备20004199 )|网站地图

快速回复 返回顶部 返回列表