Problem
A spammer is repeatedly joining the Official River room under a small set of fixed
nicknames (TORMENTA, FURIA, Presagio). They have been banned 20+ times and keep
returning. Two independent causes; this issue covers the upstream one.
gkapi's per-IP invite limit is defeated by Tor circuit rotation.
rate_limit.rs allows MAX_INVITES_PER_WINDOW = 20 per IP. That is sound against a
single host, but the abuser rotates Tor exit nodes, so each request presents a fresh
IP and the limit never engages.
Evidence from /var/lib/gkapi/invite_rate_limits.json on vega (2026-07-25, UTC):
| 15-min bucket |
invites |
from Tor exits |
| baseline (18:00-22:00) |
30-36 |
0 |
02:40 |
85 |
59 |
02:50 |
143 |
93 |
Organic quickstart traffic runs ~30-36 invites per 15 min with zero Tor-exit
origin. The 02:40-02:58 burst was 228 invites in ~18 minutes, 67% of them from
135 distinct Tor exit IPs (192.42.116.x, 185.220.101.x, 185.220.100.x,
109.70.100.x, 171.25.193.x, 45.84.107.x). No individual IP came close to the
20-request limit.
Because every invite yields a fresh keypair, per-identity banning cannot converge:
the abuser mints new identities faster than a moderator can ban them.
Why this is not simply "block Tor"
Freenet is a privacy project and the quickstart is the main onboarding path.
Blocking Tor exits would stop this abuser today at the cost of excluding exactly
the users the project exists to serve. That is a values decision, not a technical
one, so this issue documents options rather than picking one.
Options
- Global burst limit (Tor-agnostic). Cap total issuance network-wide (e.g. N/min
across all IPs) and shed load above it. Blunt, but the burst signature here (143 in
15 min vs a 30-36 baseline) is ~4x baseline and trivially separable. Does not
discriminate by origin.
- Proof-of-work on
/create-invite. Makes bulk minting cost CPU while staying
near-free for one genuine user. Preserves Tor access. Costs some onboarding latency.
- Per-/24 or per-ASN limiting. Raises the cost of rotation somewhat, but Tor exits
span many ASNs, so this is partial at best.
- Block Tor exit nodes. Effective immediately; carries the values cost above.
- Do nothing upstream and rely on the moderation-side mitigations already applied
(see below).
My read: (2) is the only option that actually fixes the asymmetry without excluding
Tor users, and (1) is a cheap stopgap that could ship first. But this is your call.
Already applied (moderation side, no code change)
max_user_bans on the Official room raised 10 -> 200. This was the more
immediate cause: the ban list is a FIFO, it was full at 10/10, and every new ban
evicted the oldest — allowing a previously-banned identity to walk back in
unchanged. Ban list went from 10 to 63 retained bans the instant the cap rose,
with several identities appearing 2-3 times (banned, evicted, returned, re-banned).
~/bin/river-official-autoban.sh + */5 cron on nova: sweeps the member list and
bans exact-nickname matches from a watchlist, so the manual toil stops.
Neither of these fixes the root asymmetry — they just stop the bleeding.
[AI-assisted - Claude]
Problem
A spammer is repeatedly joining the Official River room under a small set of fixed
nicknames (TORMENTA, FURIA, Presagio). They have been banned 20+ times and keep
returning. Two independent causes; this issue covers the upstream one.
gkapi's per-IP invite limit is defeated by Tor circuit rotation.
rate_limit.rsallowsMAX_INVITES_PER_WINDOW = 20per IP. That is sound against asingle host, but the abuser rotates Tor exit nodes, so each request presents a fresh
IP and the limit never engages.
Evidence from
/var/lib/gkapi/invite_rate_limits.jsonon vega (2026-07-25, UTC):02:4002:50Organic quickstart traffic runs ~30-36 invites per 15 min with zero Tor-exit
origin. The 02:40-02:58 burst was 228 invites in ~18 minutes, 67% of them from
135 distinct Tor exit IPs (
192.42.116.x,185.220.101.x,185.220.100.x,109.70.100.x,171.25.193.x,45.84.107.x). No individual IP came close to the20-request limit.
Because every invite yields a fresh keypair, per-identity banning cannot converge:
the abuser mints new identities faster than a moderator can ban them.
Why this is not simply "block Tor"
Freenet is a privacy project and the quickstart is the main onboarding path.
Blocking Tor exits would stop this abuser today at the cost of excluding exactly
the users the project exists to serve. That is a values decision, not a technical
one, so this issue documents options rather than picking one.
Options
across all IPs) and shed load above it. Blunt, but the burst signature here (143 in
15 min vs a 30-36 baseline) is ~4x baseline and trivially separable. Does not
discriminate by origin.
/create-invite. Makes bulk minting cost CPU while stayingnear-free for one genuine user. Preserves Tor access. Costs some onboarding latency.
span many ASNs, so this is partial at best.
(see below).
My read: (2) is the only option that actually fixes the asymmetry without excluding
Tor users, and (1) is a cheap stopgap that could ship first. But this is your call.
Already applied (moderation side, no code change)
max_user_banson the Official room raised 10 -> 200. This was the moreimmediate cause: the ban list is a FIFO, it was full at 10/10, and every new ban
evicted the oldest — allowing a previously-banned identity to walk back in
unchanged. Ban list went from 10 to 63 retained bans the instant the cap rose,
with several identities appearing 2-3 times (banned, evicted, returned, re-banned).
~/bin/river-official-autoban.sh+*/5cron on nova: sweeps the member list andbans exact-nickname matches from a watchlist, so the manual toil stops.
Neither of these fixes the root asymmetry — they just stop the bleeding.
[AI-assisted - Claude]