bunkerized-nginx/core/badbehavior/badbehavior.lua
2022-06-03 17:24:14 +02:00

73 lines
2.5 KiB
Lua

local _M = {}
_M.__index = _M
local utils = require "utils"
local datastore = require "datastore"
local logger = require "logger"
local cjson = require "cjson"
function _M.new()
local self = setmetatable({}, _M)
return self, nil
end
function _M:log()
self.use = utils.get_variable("USE_BAD_BEHAVIOR")
self.ban_time = utils.get_variable("BAD_BEHAVIOR_BAN_TIME")
self.status_codes = utils.get_variable("BAD_BEHAVIOR_STATUS_CODES")
self.threshold = utils.get_variable("BAD_BEHAVIOR_THRESHOLD")
self.count_time = utils.get_variable("BAD_BEHAVIOR_COUNT_TIME")
if self.use ~= "yes" then
return true, "bad behavior not activated"
end
if not self.status_codes:match(tostring(ngx.status)) then
return true, "not increasing counter"
end
local count, err = datastore:get("plugin_badbehavior_count_" .. ngx.var.remote_addr)
if not count and err ~= "not found" then
return false, "can't get counts from the datastore : " .. err
end
local new_count = 1
if count ~= nil then
new_count = count + 1
end
local ok, err = datastore:set("plugin_badbehavior_count_" .. ngx.var.remote_addr, new_count)
if not ok then
return false, "can't save counts to the datastore : " .. err
end
local function decrease_callback(premature, ip)
local count, err = datastore:get("plugin_badbehavior_count_" .. ip)
if err then
logger.log(ngx.ERR, "BAD-BEHAVIOR", "(decrease_callback) Can't get counts from the datastore : " .. err)
return
end
if not count then
logger.log(ngx.ERR, "BAD-BEHAVIOR", "(decrease_callback) Count is null")
return
end
local new_count = count - 1
if new_count <= 0 then
datastore:delete("plugin_badbehavior_count_" .. ip)
return
end
local ok, err = datastore:set("plugin_badbehavior_count_" .. ip, new_count)
if not ok then
logger.log(ngx.ERR, "BAD-BEHAVIOR", "(decrease_callback) Can't save counts to the datastore : " .. err)
end
end
local hdr, err = ngx.timer.at(tonumber(self.count_time), decrease_callback, ngx.var.remote_addr)
if not ok then
return false, "can't create decrease timer : " .. err
end
if new_count > tonumber(self.threshold) then
local ok, err = datastore:set("bans_ip_" .. ngx.var.remote_addr, "bad behavior", tonumber(self.ban_time))
if not ok then
return false, "can't save ban to the datastore : " .. err
end
logger.log(ngx.WARN, "BAD-BEHAVIOR", "IP " .. ngx.var.remote_addr .. " is banned for " .. tostring(self.ban_time) .. "s (" .. tostring(new_count) .. "/" .. tostring(self.threshold) .. ")")
end
return true, "success"
end
return _M