mirror of
https://github.com/deunix-educ/Fail2banMqttActionBanishment.git
synced 2026-08-24 03:11:58 +02:00
3.3 KiB
3.3 KiB
Reference
MQTT topics
| Topic | Direction | Role |
|---|---|---|
fail2ban/<node>/ban |
node → master | ban/notice event published by this node |
fail2ban/<node>/heartbeat |
node → master | periodic liveness proof (independent of any ban activity) |
fail2ban/<node>/ack |
node → master | acknowledgement after executing a command received from the master |
fail2ban/<node>/action |
master → node | command addressed specifically to this node |
fail2ban/broadcast/action |
master → all nodes | command broadcast to all subscribed nodes |
fail2ban/broadcast/roster |
master → all nodes | list of known nodes + global jail/country counters, periodic |
<node> in the topic segment is the mTLS client certificate's CN
(enforced by the broker's ACL) — the node's internal identifier
(uuid.getnode()) travels in the message body, not in the topic.
Master commands
| Command | Effect on the receiving node | Trigger |
|---|---|---|
SYNC_BAN |
Full ban (all ports) via a dedicated jail | Automatic: the master systematically publishes a SYNC_BAN for every ban it ingests |
ESCALATE |
Permanent ban via a dedicated jail | Automatic: the master correlates — an IP independently banned on several distinct nodes within 24h triggers an escalation |
BAN_ALLPORTS |
Full ban (all ports), same mechanism as SYNC_BAN |
Manual (targeted human decision) |
WHITELIST |
Added to ignoreip on all active jails + unbanned — in-memory, not persistent |
Manual |
RATE_LIMIT |
Throttle (10 req/s, burst 20) instead of a full block | Manual — edge case, likely false positives |
NOTIFY_ONLY |
No network action, just a visible dashboard notification | Manual — observation mode |
REPORT_ABUSE |
Report to AbuseIPDB — not broadcast to nodes, submitted directly by the master (one report per IP is enough) | Manual, dry-run until ABUSEIPDB_ENABLED/ABUSEIPDB_API_KEY are configured |
Manual commands are triggered on the master, by hand:
emitter/.venv/bin/python emitter/manage.py publish_command WHITELIST 203.0.113.5
emitter/.venv/bin/python emitter/manage.py publish_command BAN_ALLPORTS 203.0.113.5
emitter/.venv/bin/python emitter/manage.py publish_command RATE_LIMIT 203.0.113.5
emitter/.venv/bin/python emitter/manage.py publish_command REPORT_ABUSE 203.0.113.5
Geolocation of banned IPs is automatic (asynchronous, on ingestion of each event); to retry the ones left without coordinates (API failure, private IP):
emitter/.venv/bin/python emitter/manage.py retry_geolocation # all ungeolocated events
emitter/.venv/bin/python emitter/manage.py retry_geolocation --ip <ip> # a specific IP
Custom fail2ban jails
| Jail | Role |
|---|---|
emitter-admin-auth |
Dashboard /admin/ lockout (django-axes) → network ban |
master-sync |
Receiving a SYNC_BAN/BAN_ALLPORTS — never triggered by a log, only by manual injection from the master relay |
master-ratelimit |
Receiving a RATE_LIMIT |
master-escalate |
Receiving an ESCALATE — permanent ban |
emitter-admin-auth follows a reusable template
(generic/fail2ban/jail.d/app-auth.conf.template +
generic/fail2ban/filter.d/app-auth.conf) to protect any other
application exposed on the same server the same way, not just this
dashboard.