Multiplayer mode
Report your bans; pull crowd-sourced bans.
Your server knows which addresses are attacking it. So does everyone else's. Multiplayer mode is how we help each other.
It is handled by the separate minsec-sync binary, so the resident daemon
is tiny, fast, and auditable.
What is sent
One record per automatic ban:
| Field | Example | Notes |
|---|---|---|
ts | 1724371190 | when the ban fired |
ip | 203.0.113.7/32 | the attacker's network, IPv6 aggregated to /64 |
filter | sshd | the rule that matched — an opaque name, not free text |
count | 5 | matching hits inside the ban window |
ban_ttl | 3600 | local ban length, in seconds |
escalation | 2 | repeat-offender depth for this attacker; omitted on a first ban |
No log lines, usernames, hostnames, or anything about your users or your traffic. Manual bans and unbans are not reported.
Reports are signed with a per-install Ed25519 key generated at first enrollment. The server identifies the installation by a random UUID, nothing derived from your hardware or network. Full privacy statement.
Opting in
sudo install -m 0644 /usr/share/doc/minsec/sync.toml.example /etc/minsec/sync.toml
sudo systemctl enable --now minsec-sync.timer
The config file's presence is the switch. The timer runs minsec-sync run once an
hour: it enrolls automatically on the first run (solving a small proof-of-work, a
few seconds of one core), then reports new bans and refreshes the blocklist.
Report and pull are independent:
# /etc/minsec/sync.toml
report = true # contribute your automatic bans
pull = true # pull the crowd blocklist
You can pull without contributing, or contribute without pulling. See
minsec-sync.toml(5).
Opting out
sudo rm /etc/minsec/sync.toml
sudo nft flush set inet minsec crowd4
sudo nft flush set inet minsec crowd6
Removing the file stops everything at the next timer tick; the two flush commands
clear the already-pulled list immediately.
The dynamic blocklist
The crowd list goes into its own nftables sets, crowd4 and crowd6, enforced
after your allowlist and after your local bans. They are separate from ban4/ban6
so you can always tell which blocks came from the crowd:
sudo nft list set inet minsec crowd4
Full replaces are one atomic nft transaction; most refreshes are a delta or a
304 Not Modified.
Commands
minsec-sync status # enrollment, cursor and feed state — start here
minsec-sync enroll # generate key + enroll (run does this automatically)
minsec-sync report # submit new automatic bans from the events log
minsec-sync pull # refresh crowd4/crowd6
minsec-sync pull --dry-run # print the nft script instead of applying it
minsec-sync run # report + pull; what the timer runs
pull --dry-run is the honest answer to "what is this about to do to my
firewall?" — it prints the exact nft script and applies nothing.
State — the key, the host id, the events-log cursor, the feed cursors — lives in
/var/lib/minsec/sync/.
How an address gets listed
Nothing is published on one report. An address enters the feed only when enough independent installations agree on it, each vote weighted by that reporter's standing, and quorum is counted per abuse category rather than in aggregate. Independence is counted by enrollment network rather than by key, so minting extra keys buys no extra votes. New agents start on probation: their reports carry weight but do not count toward quorum until the probation period is up. Each agent has a daily ceiling on what it can store; an agent that keeps pushing past it is quarantined and its reports accepted-and-discarded. One noisy or hostile agent moves nothing.
Expiry happens server-side, on a 48-hour horizon unless the address is seen again, and arrives as removals in the next delta.
The crowd sets also expire on their own, as a failsafe. Entries are added with a
24-hour kernel timeout, and any pull that finds the last full replace more than
12 hours old refetches the whole list and rewrites the set, restarting the clock.
A working sync never lets anything expire; a sync that stops — dead network,
backend outage, a timer someone disabled — drains crowd4 and crowd6 within a
day, instead of enforcing a frozen snapshot until the machine reboots. Your own
bans in ban4/ban6 are untouched.
minsec-sync status prints the age of the last successful pull and of each
family's last full replace, so a sync that has quietly stopped is visible.
Details of the tiers and the delta protocol: blocklist feed.
Wrongly listed?
Mail delist@minsec.io with the address. Delisting removes it from the blocklist
feed and the DNSBL together, and takes effect at the next scoring
tick — usually a few minutes. The DNSBL and the feed are correct
from that moment; agents drop the address at their next hourly pull.