Skip to content

Commit

Permalink
[#1460] Add "service" field in bans and reports
Browse files Browse the repository at this point in the history
  • Loading branch information
TheophileDiot committed Oct 23, 2024
1 parent 609dfc3 commit 0d6fdbd
Show file tree
Hide file tree
Showing 11 changed files with 56 additions and 26 deletions.
18 changes: 13 additions & 5 deletions src/bw/lua/bunkerweb/api.lua
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ api.global.POST["^/ban$"] = function(self)
ip = "",
exp = 86400,
reason = "manual",
service = "unknown",
}
ban.ip = ip["ip"]
if ip["exp"] then
Expand All @@ -233,10 +234,14 @@ api.global.POST["^/ban$"] = function(self)
if ip["reason"] then
ban.reason = ip["reason"]
end
if ip["service"] then
ban.service = ip["service"]
end
datastore:set(
"bans_ip_" .. ban["ip"],
encode({
reason = ban["reason"],
service = ban["service"],
date = os.time(),
}),
ban["exp"]
Expand Down Expand Up @@ -267,12 +272,15 @@ api.global.GET["^/bans$"] = function(self)
local ban_data
ok, ban_data = pcall(decode, result)
if not ok then
ban_data = { reason = result, date = -1 }
ban_data = { reason = result, service = "unknown", date = -1 }
end
table.insert(
data,
{ ip = k:sub(9, #k), reason = ban_data["reason"], date = ban_data["date"], exp = math.floor(ttl) }
)
table.insert(data, {
ip = k:sub(9, #k),
reason = ban_data["reason"],
service = ban_data["service"],
date = ban_data["date"],
exp = math.floor(ttl),
})
end
end
return self:response(HTTP_OK, "success", data)
Expand Down
3 changes: 2 additions & 1 deletion src/bw/lua/bunkerweb/utils.lua
Original file line number Diff line number Diff line change
Expand Up @@ -714,10 +714,11 @@ utils.is_banned = function(ip)
return false, "not banned"
end

utils.add_ban = function(ip, reason, ttl)
utils.add_ban = function(ip, reason, ttl, service)
-- Set on local datastore
local ban_data = encode({
reason = reason,
service = service or "unknown",
date = os.time(),
})
local ok, err = datastore:set("bans_ip_" .. ip, ban_data, ttl)
Expand Down
9 changes: 7 additions & 2 deletions src/common/cli/CLI.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ def unban(self, ip: str) -> Tuple[bool, str]:
def ban(self, ip: str, exp: float, reason: str) -> Tuple[bool, str]:
if self.__redis:
try:
ok = self.__redis.set(f"bans_ip_{ip}", dumps({"reason": reason, "date": time()}))
ok = self.__redis.set(f"bans_ip_{ip}", dumps({"reason": reason, "date": time(), "service": "bwcli"}))
if not ok:
self.__logger.error(f"Failed to ban {ip} in redis")
self.__redis.expire(f"bans_ip_{ip}", int(exp))
Expand Down Expand Up @@ -260,7 +260,12 @@ def bans(self) -> Tuple[bool, str]:
banned_date = f"the {datetime.fromtimestamp(ban['date']).strftime('%Y-%m-%d at %H:%M:%S %Z')} "
if ban["exp"] != -1:
remaining = f"for {format_remaining_time(ban['exp'])} remaining"
cli_str += f"- {ban['ip']} ; banned {banned_date}{remaining} with reason \"{ban.get('reason', 'no reason given')}\"\n"
cli_str += f"- {ban['ip']} ; banned {banned_date}{remaining} with reason \"{ban.get('reason', 'no reason given')}\""

if ban.get("service", "unknown") != "unknown":
cli_str += f" by {ban['service'] if ban['service'] != '_' else 'default server'}"

cli_str += "\n"
cli_str += "\n"

return True, cli_str
Expand Down
7 changes: 4 additions & 3 deletions src/common/core/badbehavior/badbehavior.lua
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ function badbehavior:log()
tonumber(self.variables["BAD_BEHAVIOR_COUNT_TIME"]),
tonumber(self.variables["BAD_BEHAVIOR_BAN_TIME"]),
tonumber(self.variables["BAD_BEHAVIOR_THRESHOLD"]),
self.use_redis
self.use_redis,
self.ctx.bw.server_name
)
if not ok then
return self:ret(false, "can't create increase timer : " .. err)
Expand All @@ -62,7 +63,7 @@ function badbehavior:log_stream()
end

-- luacheck: ignore 212
function badbehavior.increase(premature, ip, count_time, ban_time, threshold, use_redis)
function badbehavior.increase(premature, ip, count_time, ban_time, threshold, use_redis, server_name)
-- Instantiate objects
local logger = require "bunkerweb.logger":new("badbehavior")
local datastore = require "bunkerweb.datastore":new()
Expand Down Expand Up @@ -102,7 +103,7 @@ 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)
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
Expand Down
1 change: 1 addition & 0 deletions src/common/core/metrics/metrics.lua
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ function metrics:log(bypass_checks)
status = ngx.status,
user_agent = self.ctx.bw.http_user_agent or "",
reason = reason,
server_name = self.ctx.bw.server_name,
data = data,
}
-- Get current requests
Expand Down
10 changes: 6 additions & 4 deletions src/ui/app/models/instance.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,9 @@ def restart(self) -> str:
return f"Instance {self.hostname} has been restarted."
return f"Can't restart instance {self.hostname}"

def ban(self, ip: str, exp: float, reason: str) -> str:
def ban(self, ip: str, exp: float, reason: str, service: str) -> str:
try:
result = self.apiCaller.send_to_apis("POST", "/ban", data={"ip": ip, "exp": exp, "reason": reason})[0]
result = self.apiCaller.send_to_apis("POST", "/ban", data={"ip": ip, "exp": exp, "reason": reason, "service": service})[0]
except BaseException as e:
return f"Can't ban {ip} on instance {self.hostname}: {e}"

Expand Down Expand Up @@ -193,8 +193,10 @@ def reload_instances(self, *, instances: Optional[List[Instance]] = None) -> Uni
instance.name for instance in instances or self.get_instances() if instance.status == "down" or instance.reload().startswith("Can't reload")
] or "Successfully reloaded instances"

def ban(self, ip: str, exp: float, reason: str, *, instances: Optional[List[Instance]] = None) -> Union[list[str], str]:
return [instance.name for instance in instances or self.get_instances(status="up") if instance.ban(ip, exp, reason).startswith("Can't ban")] or ""
def ban(self, ip: str, exp: float, reason: str, service: str, *, instances: Optional[List[Instance]] = None) -> Union[list[str], str]:
return [
instance.name for instance in instances or self.get_instances(status="up") if instance.ban(ip, exp, reason, service).startswith("Can't ban")
] or ""

def unban(self, ip: str, *, instances: Optional[List[Instance]] = None) -> Union[list[str], str]:
return [instance.name for instance in instances or self.get_instances(status="up") if instance.unban(ip).startswith("Can't unban")] or ""
Expand Down
4 changes: 2 additions & 2 deletions src/ui/app/routes/bans.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,12 @@ def bans_ban():
ban_end = (ban_end - current_time).total_seconds()

if redis_client:
ok = redis_client.set(f"bans_ip_{ban['ip']}", dumps({"reason": reason, "date": time()}))
ok = redis_client.set(f"bans_ip_{ban['ip']}", dumps({"reason": reason, "date": time(), "service": "web UI"}))
if not ok:
flash(f"Couldn't ban {ban['ip']} on redis", "error")
redis_client.expire(f"bans_ip_{ban['ip']}", int(ban_end))

resp = BW_INSTANCES_UTILS.ban(ban["ip"], ban_end, reason)
resp = BW_INSTANCES_UTILS.ban(ban["ip"], ban_end, reason, "web UI")
if resp:
flash(f"Couldn't ban {ban['ip']} on the following instances: {', '.join(resp)}", "error")
else:
Expand Down
18 changes: 11 additions & 7 deletions src/ui/app/static/js/pages/bans.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ $(document).ready(function () {
viewTotal: true,
cascadePanes: true,
collapse: false,
columns: [1, 4],
columns: [1, 4, 5],
},
},
topStart: {},
Expand Down Expand Up @@ -336,7 +336,7 @@ $(document).ready(function () {
targets: -1,
},
{
targets: [1, 4],
targets: [1, 5],
render: function (data, type, row) {
if (type === "display" || type === "filter") {
const date = new Date(data);
Expand Down Expand Up @@ -396,31 +396,31 @@ $(document).ready(function () {
{
label: "Next 24 hours",
value: function (rowData, rowIdx) {
const date = new Date(rowData[4]);
const date = new Date(rowData[5]);
const now = new Date();
return date - now < 24 * 60 * 60 * 1000;
},
},
{
label: "Next 7 days",
value: function (rowData, rowIdx) {
const date = new Date(rowData[4]);
const date = new Date(rowData[5]);
const now = new Date();
return date - now < 7 * 24 * 60 * 60 * 1000;
},
},
{
label: "Next 30 days",
value: function (rowData, rowIdx) {
const date = new Date(rowData[4]);
const date = new Date(rowData[5]);
const now = new Date();
return date - now < 30 * 24 * 60 * 60 * 1000;
},
},
{
label: "More than 30 days",
value: function (rowData, rowIdx) {
const date = new Date(rowData[4]);
const date = new Date(rowData[5]);
const now = new Date();
return date - now >= 30 * 24 * 60 * 60 * 1000;
},
Expand All @@ -429,10 +429,14 @@ $(document).ready(function () {
combiner: "or",
orderable: false,
},
targets: 5,
},
{
searchPanes: { show: true },
targets: 4,
},
],
order: [[4, "asc"]],
order: [[5, "asc"]],
autoFill: false,
responsive: true,
select: {
Expand Down
4 changes: 2 additions & 2 deletions src/ui/app/static/js/pages/reports.js
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ $(function () {
viewTotal: true,
cascadePanes: true,
collapse: false,
columns: [1, 2, 3, 4, 5, 7],
columns: [1, 2, 3, 4, 5, 7, 8],
},
},
topStart: {},
Expand Down Expand Up @@ -460,7 +460,7 @@ $(function () {
},
{
searchPanes: { show: true },
targets: [1, 2, 3, 4, 5, 7],
targets: [1, 2, 3, 4, 5, 7, 8],
},
],
order: [[0, "desc"]],
Expand Down
4 changes: 4 additions & 0 deletions src/ui/app/templates/bans.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@
<th data-bs-toggle="tooltip"
data-bs-placement="bottom"
data-bs-original-title="The reason why the Report was created">Reason</th>
<th data-bs-toggle="tooltip"
data-bs-placement="bottom"
data-bs-original-title="The service that created the ban">Service</th>
<th data-bs-toggle="tooltip"
data-bs-placement="bottom"
data-bs-original-title="The end date of the Ban">End date</th>
Expand All @@ -46,6 +49,7 @@
<td class="ban-start-date">{{ ban["start_date"] }}</td>
<td>{{ ban["ip"] }}</td>
<td>{{ ban["reason"] }}</td>
<td>{{ ban["service"] if ban["service"] != "_" else "default server" }}</td>
<td class="ban-end-date">{{ ban["end_date"] }}</td>
<td>{{ ban["remain"] }}</td>
<td>
Expand Down
4 changes: 4 additions & 0 deletions src/ui/app/templates/reports.html
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@
<th data-bs-toggle="tooltip"
data-bs-placement="bottom"
data-bs-original-title="The reason why the Report was created">Reason</th>
<th data-bs-toggle="tooltip"
data-bs-placement="bottom"
data-bs-original-title="The Server name that created the report">Server name</th>
<th data-bs-toggle="tooltip"
data-bs-placement="bottom"
data-bs-original-title="Additional data about the Report">Data</th>
Expand Down Expand Up @@ -69,6 +72,7 @@
<td>{{ report["status"] }}</td>
<td>{{ report["user_agent"] }}</td>
<td>{{ report["reason"] }}</td>
<td>{{ report["server_name"] }}</td>
<td>{{ report["data"] }}</td>
</tr>
{% endfor %}
Expand Down

0 comments on commit 0d6fdbd

Please sign in to comment.