Commit Graph
10 Commits
Author SHA1 Message Date
pmb 1bfbcfdac3 Add welcomebot-reputation CLI and a --reputation log filter
docker-build-push / build-push (push) Successful in 4s
The pre-signup path had no inspection tool. Its activity landed in docker logs
and two sqlite tables with nothing to read them, while the reactive path has
had welcomebot-signups and welcomebot-suspicious all along.

welcomebot-reputation reads reputation_query and reputation_block directly so
it survives log rotation: recent answers, --stats for volume and flag/block
rate by source, --blocks for what is actually in force, and --deferred to see
whether the hourly provider-lookup ceiling is biting. --blocks marks rows GONE
once the reconcile pass finds the block no longer on the Mastodon side, so
"we installed this" and "this is in force" stay distinguishable.

welcomebot-logs --reputation covers the raw lines (pre-blocks, budget
refusals, width-cap narrowings).
2026-09-13 16:35:11 -07:00
pmb 8966de2a1d Add text format, CORS, and an importer so other instances can use the list
docker-build-push / build-push (push) Successful in 4s
Mastodon has no RBL/DNSBL support — nothing in it consults an outside
list when deciding whether to accept a signup, confirmed against v4.7.1
(the only outbound lookup in that path is EmailMxValidator's MX
resolution, which feeds the local email_domain_blocks table). So a
shared blocklist has to be imported rather than queried live, the same
way Garden Fence and other community lists propagate. These are the
pieces that make ours importable.

- ?format=txt on both per-list endpoints: one entry per line under a '#'
  comment header, the form blocklists are traded in and the form a cron
  job can consume without a JSON parser. The combined /api/blocks stays
  JSON-only — a text rendering would mix CIDRs with domains in one file,
  defeating the point. An unrecognised ?format is a 400 rather than a
  silent fallback to JSON, and the enabled-gate still runs first so a
  disabled deployment 404s either way.
- Access-Control-Allow-Origin: * on blocklist responses, so browser-side
  admin tooling can read them. The data is already public.
- bin/yttrx-blocklist-import: standard-library-only importer another
  admin can run against their own instance. Dry run unless --apply;
  422 from Mastodon counts as "already blocked", not an error.

The importer defaults IP entries to sign_up_requires_approval rather
than the sign_up_block yttrx uses itself. The entries are whole ASN
routes, which suits yttrx because a flagged signup here is nearly always
datacenter/VPN/proxy space — that calibration isn't transferable, so an
importer gets the reviewable severity by default and has to opt into the
hard one.
2026-09-13 00:59:12 -07:00
pmb af49aab79c Backfill block_cidr so /api/blocks reports real ranges
docker-build-push / build-push (push) Successful in 3s
Every row blocked before the block_cidr column existed had nothing to
report, so the endpoint fell back to the signup IP's /32 — the address
that signed up rather than the range that was blocked, which is the
opposite of what the list is for.

The range is recoverable from the bot's own ipapi range cache, which
stores the CIDR each classification was cached under — the same value
that was handed to register_ip_block. Run once on admin.yttrx.com:
of 154 blocked rows, 65 gained their real range, 79 genuinely were
single-address blocks (no asn.route from ipapi.is), and 10 with no cache
entry stay as a /32, since under-reporting beats claiming a range is
blocked when it isn't. Rows classified before 2026-07-15 are skipped —
range-blocking didn't exist yet, so only the /32 was ever registered.

Live output went from 150 entries (all /32) to 145, of which 59 are
real networks.
2026-09-13 00:48:20 -07:00
pmb 0356fe7997 Replace RDAP/ipwhois signup-IP classifier with ipapi.is
Flags datacenter, vpn, proxy, tor, and independently-scored abuser
signals instead of regex-matching RDAP org names; anonymous tier
covers 1000 req/day, well above signup volume.
2026-07-06 08:57:55 -07:00
pmb 9924e06b5a Add suspicious-signup sweep: suspend flagged signups with no activity
Watches every account flagged by IP-scrutiny or email-domain scrutiny at
signup and, once it goes live, records a baseline post/follow count. A
scheduled sweep (app/suspicious_sweep.py, run via cron on admin.yttrx.com)
suspends any watch past SUSPICIOUS_GRACE_HOURS with zero new posts and
zero new follows since that baseline; any activity clears the watch.

Works whether yttrx is open-registration or requires moderator approval,
since the watch starts at whichever event actually makes the account live
(account.created vs account.approved), same dual handling the welcome flow
already uses. Needs ABUSE_BOT_TOKEN re-minted with admin:read:accounts.
2026-07-05 10:22:39 -07:00
pmb 0fd6f1c142 Fix welcomebot-signups: heredoc instead of -c string to avoid bash/python quote clash 2026-07-02 16:56:21 -07:00
pmb 00dec0266c Fix f-string quote escaping bug in welcomebot-signups 2026-07-02 16:54:14 -07:00
pmb 37577fbb56 Add welcomebot-signups CLI to inspect signup-IP classification history 2026-07-02 16:53:36 -07:00
pmb 0a196c3788 Add --ip filter to welcomebot-logs for signup-scrutiny decisions 2026-07-02 16:51:24 -07:00
pmb c0e5df3cc4 Initial commit: welcome-bot, abuse-bot, dormant-sweep, IP signup scrutiny 2026-07-02 16:22:30 -07:00