feat(security): recovery alerts, gate-block sharing, rolling-window burst and admin breakdown for CrowdSec
Gitea Actions Runner Test / test-job (push) Successful in 1s
CI / check (push) Successful in 30s
CI / tests-integration (push) Successful in 1m42s
CI / tests-unit (push) Successful in 1m50s
CI / tests-ui (push) Successful in 2m42s
CI / preflight (push) Skipped
CI / deploy (push) Successful in 2m3s

This commit is contained in:
openhands committed 2026-09-23 15:06:16 +02:00
1 parent 301edd2c9a
commit 3e1a3f92c8
8 files changed
+448 -65

No files matched your search

+15 -1
View File
@@ -348,7 +348,9 @@ async function pushSignal(input: {
body: [
{
machine_id: input.credentials.machineId,
message: "atomcms-next anti-DDoS gate blocked a community-flagged IP",
message: input.verdict.reputation
? "atomcms-next anti-DDoS gate blocked a community-flagged IP"
: "atomcms-next anti-DDoS gate blocked a repeat rate-limit offender",
scenario: SCENARIO,
scenario_version: SCENARIO_VERSION,
scenario_hash: scenarioHash(),
@@ -390,9 +392,21 @@ async function pushSignal(input: {
`signal push rejected (HTTP ${response.status}): ${await errorDetail(response)}`,
);
}
// Was the channel down before this? A first success after failures
// deserves a recovery notice (separate cooldown key from the failure).
const before = await getLastCrowdsecReport();
const status: CrowdsecReportStatus = { ok: true, at: Date.now() };
await setLastCrowdsecReport(status);
void bumpCrowdsecStat("reports");
if (before && !before.ok) {
void raiseCrowdsecAlert("report-recovered", {
type: "ddos",
severity: "info",
message:
"CrowdSec signal push recovered — detections are reaching the community again.",
context: { ip: input.ip },
});
}
logger.info("[crowdsec-report] Detection shared with the community", {
ip: input.ip,
category: input.category,