abuseipdb — report the banished

Not a blocker at all: reports banned IPs to AbuseIPDB via its v2 REST API, the equivalent of the fail2ban abuseipdb action. A ban files a report; nothing is ever blocked by this kur itself.

Its natural home is inside a gate, next to a real blocker — one command through the gate blocks locally and reports upstream:

[kur.sshd]
backend   = "pf"
ports     = [ "22" ]
protocols = [ "tcp" ]

[kur.sshd.options]
kill = 1

[kur.sshd-report]
backend = "abuseipdb"

[kur.sshd-report.options]
key        = "your-abuseipdb-api-key"
categories = [ "18", "22" ]
comment    = "ssh brute force"

[kur.baphomet]
fan_out = [ "sshd", "sshd-report" ]

The reporting semantics — read this part

Reports cannot be withdrawn, so this backend's lifecycle is deliberately lopsided:

AbuseIPDB-side setup

An account and an API key (webmaster/user tier is fine). Free tier allows 1,000 reports/day — pace your ban sources accordingly.

Requirements

Settings

Options

| option | default | what | |--------------|-----------------------------|----------------------------------------------------------| | key | (required) | AbuseIPDB API key | | categories | 18 | category numbers, array or comma string — see below | | comment | banned by <prefix>_<name> | report comment; %%%BAN%%% → the IP; blank = none | | timeout | 30 | HTTP timeout in seconds |

Categories are AbuseIPDB's numeric taxonomy (https://www.abuseipdb.com/categories) — 18 is Brute-Force, 22 SSH, 14 Port Scan, 21 Web App Attack. Pick per kur to match what the ban source actually saw.

Comments are public on the reported IP's AbuseIPDB page. Do not template in log lines, usernames, or anything else you would not publish.

What each operation does

| operation | API traffic | |------------|-------------------------------------------------------------------------------| | init | GET /api/v2/check?ipAddress=127.0.0.2&maxAgeInDays=1 — verifies the key | | ban | POST /api/v2/report with ip, categories, comment (429 tolerated) | | unban | nothing | | list | no API call — the kur's own ban book | | check | same probe as init | | flush | nothing (ban book cleared) | | re_init | teardown (no-op) + init | | teardown | nothing (ban book kept) |

self_heal

There is nothing on the AbuseIPDB side to establish, so there is nothing to repair — the re_init after a failed check just probes again. check re-runs init's credential probe (catching a revoked or expired key), so a kur stuck failing it has a credentials problem, not a firewall one.

Gotchas