bw - improve security mode feature

This commit is contained in:
fl0ppy-d1sk 2024-11-15 15:50:43 +01:00
parent 14a0b7dc1c
commit 51e658cd3e
No known key found for this signature in database
GPG key ID: 93EE47CC3D061500
5 changed files with 84 additions and 36 deletions

View file

@ -12,6 +12,7 @@ local timer_at = ngx.timer.at
local add_ban = utils.add_ban
local is_whitelisted = utils.is_whitelisted
local is_banned = utils.is_banned
local get_security_mode = utils.get_security_mode
local tostring = tostring
function badbehavior:initialize(ctx)
@ -36,6 +37,8 @@ function badbehavior:log()
if is_banned(self.ctx.bw.remote_addr) then
return self:ret(true, "already banned")
end
-- Get security mode
local security_mode = get_security_mode(self.ctx)
-- Call increase function later and with cosocket enabled
local ok, err = timer_at(
0,
@ -45,7 +48,8 @@ function badbehavior:log()
tonumber(self.variables["BAD_BEHAVIOR_BAN_TIME"]),
tonumber(self.variables["BAD_BEHAVIOR_THRESHOLD"]),
self.use_redis,
self.ctx.bw.server_name
self.ctx.bw.server_name,
security_mode
)
if not ok then
return self:ret(false, "can't create increase timer : " .. err)
@ -63,7 +67,7 @@ function badbehavior:log_stream()
end
-- luacheck: ignore 212
function badbehavior.increase(premature, ip, count_time, ban_time, threshold, use_redis, server_name)
function badbehavior.increase(premature, ip, count_time, ban_time, threshold, use_redis, server_name, security_mode)
-- Instantiate objects
local logger = require "bunkerweb.logger":new("badbehavior")
local datastore = require "bunkerweb.datastore":new()
@ -103,23 +107,38 @@ function badbehavior.increase(premature, ip, count_time, ban_time, threshold, us
end
-- Store local ban
if counter > threshold then
ok, err = add_ban(ip, "bad behavior", ban_time, server_name)
if not ok then
logger:log(ERR, "(increase) can't save ban : " .. err)
return
if security_mode == "block" then
ok, err = add_ban(ip, "bad behavior", ban_time, server_name)
if not ok then
logger:log(ERR, "(increase) can't save ban : " .. err)
return
end
logger:log(
WARN,
"IP "
.. ip
.. " is banned for "
.. ban_time
.. "s ("
.. tostring(counter)
.. "/"
.. tostring(threshold)
.. ")"
)
else
logger:log(
WARN,
"detected IP "
.. ip
.. " ban for "
.. ban_time
.. "s ("
.. tostring(counter)
.. "/"
.. tostring(threshold)
.. ")"
)
end
logger:log(
WARN,
"IP "
.. ip
.. " is banned for "
.. ban_time
.. "s ("
.. tostring(counter)
.. "/"
.. tostring(threshold)
.. ")"
)
end
logger:log(
NOTICE,

View file

@ -13,6 +13,7 @@ local has_variable = utils.has_variable
local get_multiple_variables = utils.get_multiple_variables
local is_whitelisted = utils.is_whitelisted
local regex_match = utils.regex_match
local security_mode = utils.get_security_mode
local time = os.time
local date = os.date
local encode = cjson.encode
@ -159,21 +160,40 @@ function limit:access()
-- Limit reached
if limited then
self:set_metric("counters", "limited_uri_" .. self.ctx.bw.uri, 1)
return self:ret(
true,
"client IP "
.. self.ctx.bw.remote_addr
.. " is limited for URL "
.. self.ctx.bw.uri
.. " (current rate = "
.. current_rate
.. "r/"
.. rate_time
.. " and max rate = "
.. rate
.. ")",
HTTP_TOO_MANY_REQUESTS
)
local security_mode = get_security_mode(self.ctx)
if security_mode == "block" then
return self:ret(
true,
"client IP "
.. self.ctx.bw.remote_addr
.. " is limited for URL "
.. self.ctx.bw.uri
.. " (current rate = "
.. current_rate
.. "r/"
.. rate_time
.. " and max rate = "
.. rate
.. ")",
HTTP_TOO_MANY_REQUESTS
)
else
return self:ret(
true,
"detected client IP "
.. self.ctx.bw.remote_addr
.. " limit for URL "
.. self.ctx.bw.uri
.. " (current rate = "
.. current_rate
.. "r/"
.. rate_time
.. " and max rate = "
.. rate
.. ")",
HTTP_TOO_MANY_REQUESTS
)
end
end
-- Limit not reached
return self:ret(

View file

@ -8,6 +8,7 @@ local ngx = ngx
local HTTP_NOT_ALLOWED = ngx.HTTP_NOT_ALLOWED
local HTTP_BAD_REQUEST = ngx.HTTP_BAD_REQUEST
local HTTP_MOVED_PERMANENTLY = ngx.HTTP_MOVED_PERMANENTLY
local get_security_mode = utils.get_security_mode
local regex_match = utils.regex_match
function misc:initialize(ctx)
@ -43,7 +44,11 @@ function misc:access()
end
end
self:set_metric("counters", "failed_method", 1)
return self:ret(true, "method " .. method .. " is not allowed", HTTP_NOT_ALLOWED)
local security_mode = get_security_mode(self.ctx)
if security_mode == "block" then
return self:ret(true, "method " .. method .. " is not allowed", HTTP_NOT_ALLOWED)
end
return self:ret(true, "detected method " .. method .. " not allowed")
end
function misc:header()

View file

@ -351,6 +351,10 @@
"id": "security-mode",
"label": "Security mode",
"regex": "^(detect|block)$",
"type": "check"
"type": "select",
"select": [
"detect",
"block"
]
}
}

View file

@ -436,7 +436,7 @@ $(function () {
const reports_table = new DataTable("#reports", {
columnDefs: [
{ orderable: false, targets: -1 },
{ visible: false, targets: [6, -1] },
{ visible: false, targets: [6, 9] },
{ type: "ip-address", targets: 1 },
{
targets: 0,