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

一、验证lua geoIp2是否缺少依赖

1、执行命令

复制代码
/usr/local/openresty/bin/opm get anjia0532/lua-resty-maxminddb

执行安装命令报错,缺少Digest/MD5依赖

2、Digest/MD5依赖

复制代码
yum -y install perl-Digest-MD5

GeoIP2 lua库依赖动态库安装,lua库依赖libmaxminddb实现对mmdb的高效访问

二、安装libmaxminddb数据库

复制代码
cd /data/file/
wget https://github.com/maxmind/libmaxminddb/releases/download/1.12.2/libmaxminddb-1.12.2.tar.gz
tar -zxf libmaxminddb-1.12.2.tar.gz
cd libmaxminddb-1.12.2
./configure
make && make install

sh -c "echo /usr/local/lib  >> /etc/ld.so.conf.d/local.conf"
ldconfig

三、编写操作geoIp的lua脚本

复制代码
--引入Redis
local redis = require "resty.redis";
--引入rsa
local rsa = require "resty.rsa";
--引入maxminddb库
local geo=require 'resty.maxminddb';
--Redis链接ip
local ip = "192.168.0.145"
--Redis链接端口
local port = 6379
--Redis连接密码
local pass = "aa123456"
--鉴权Redis
local function connAuth()
	local red = redis:new();
	local connCount, err = red:connect(ip, port);
	if not connCount then
		ngx.say("failed to connect: ", err)
		close_redis(red)
		return
	end
	red:set_timeouts(2000);
	local ok, err = red:auth(pass)
	if not ok then
		ngx.say("failed to auth: ", err)
		close_redis(red)
		return
	end
	return red
end

--关闭Redis
local function close_redis(red)
    if not red then
        return
    end
    --释放连接(连接池实现)
    local pool_max_idle_time = 10000
    local pool_size = 100
    local ok, err = red:set_keepalive(pool_max_idle_time, pool_size)
    if not ok then
        ngx.say("set keepalive error : ", err)
    end
end

--获取请求者IP
local function getIp()
    local clientIP = ngx.req.get_headers()["X-Real-IP"]
    if clientIP == nil then
        clientIP = ngx.req.get_headers()["x_forwarded_for"]
    end
    if clientIP == nil then
        clientIP = ngx.var.remote_addr
    end
    return clientIP
end
--获取用户访问IP
local clientIP = getIp();
--封禁token时间(秒)
local token_block_time= 120
--指定token访问频率计数最大值(次)
local token_max_count = 3

--如果数据为空的情况下
local function is_empty(value)
    if type(value) == "table" then
        return next(value) == nil
    elseif type(value) == "string" then
        return #value == 0
    elseif type(value) == "nil" then
        return true
    end
        return false
end

--过滤特殊字符串(只保留字母与数字,字母不区分大小写)
local function filter_special_chars(s)
    local ss = {}
    local k = 1
    while true do
        if k > #s then break end
        local c = string.byte(s,k)
        if not c then break end
        if c<192 then
            if (c>=48 and c<=57) or (c>= 65 and c<=90) or (c>=97 and c<=122) then
                table.insert(ss, string.char(c))
            end
            k = k + 1
        end
    end
    return table.concat(ss)
end

if not geo.initted() then
        geo.init("/usr/share/GeoIP/GeoLite2-Country.mmdb")
end

--如果头部信息没有指定的参数或是指定参数的值无法解析,加入IP黑名单
--如果同样的头部参数键在封禁token时间内连续访问指定token访问频率计数最大值次以上,加入IP黑名单
local function set_blacklist()
    local header = ngx.req.get_headers();
    local red = connAuth();
	-- 检测ip
    local res,err=geo.lookup(clientIP)
    if not res then
	    local res, err =  red:sismember('black-list', clientIP);
        if res ~= 1 then
            red:sadd('black-list', clientIP)
        end
        close_redis(red)
        return ngx.exit(401)
    else
        for k,v in pairs(res) do
            --只获取国家
            if(k == "country") then
                --获取国家编码
                for key,item in pairs(v) do
                    if (key=="iso_code" and "CN" ~= item) then
                        local res, err =  red:sismember('black-list', clientIP);
                        if res ~= 1 then
                            red:sadd('black-list', clientIP)
                        end
                        close_redis(red)
                        return ngx.exit(401)
                    end
                end
            end
        end
    end
end

-- 查看是否在黑名单里面
local function get_blacklist()
    local red = connAuth();
    local res, err =  red:sismember('black-list', clientIP);
    if res == 1 then
        close_redis(red);
        return ngx.exit(401);
    end
    close_redis(red);
end

get_blacklist();
set_blacklist();

四、nginx域名配置引用

复制代码
location / {
        access_by_lua_file /data/wwwroot/rsa-redis.lua;
        try_files $uri $uri/ /index.html;
    }

在你需要应用的地方加上就行

相关推荐
珹洺9 分钟前
计算机操作系统(十四)互斥锁,信号量机制与整型信号量
java·redis·缓存
cubicjin36 分钟前
Redis Stack常见拓展
数据库·redis·缓存
千层冷面5 小时前
Redis 的内存回收机制
数据库·redis·缓存
jllllyuz5 小时前
Redis 5 种基础数据结构?
redis
熙曦Sakura13 小时前
【Redis】基本架构
数据库·redis·架构
{⌐■_■}14 小时前
【Redis】热点key问题,的原因和处理,一致性哈希,删除大key的方法
数据库·redis·哈希算法
多多*15 小时前
中间件redis 功能篇 过期淘汰策略和内存淘汰策略 力扣例题实现LRU
linux·javascript·数据库·redis·sql·log4j·bootstrap
哈喽姥爷16 小时前
苍穹外卖--Redis
redis·苍穹外卖·黑马
Hello.Reader17 小时前
Redis C语言连接教程
c语言·数据库·redis
.生产的驴17 小时前
SpringBoot 执行Lua脚本 服务端执行 减少性能损耗 优化性能 优化连接性能
java·数据库·spring boot·后端·junit·maven·lua