Add a reputation query API for pre-signup blocking
docker-build-push / build-push (push) Successful in 6s
docker-build-push / build-push (push) Successful in 6s
Everything the bot does today is reactive: Mastodon creates the account, the account.created webhook arrives, we classify the signup IP and email domain, and then we block the range and suspend what already exists. POST /api/reputation is the pre-emptive half. A caller asks about an IP and/or email domain; we classify it, record the answer, register the matching Admin::IpBlock / EmailDomainBlock, and only then return. A caller that runs its own block lookup immediately afterwards therefore finds a block that did not exist when its request started. The intended caller is Mastodon's signup path, which does exactly that. It writes, so unlike /api/blocks it is authenticated and refuses to serve without a key (REPUTATION_API_KEY): an unauthenticated endpoint that installs IP blocks is a denial-of-service lever, so there is no open mode. Notes on the pieces that aren't obvious: - REPUTATION_API_MAX_LOOKUPS_PER_HOUR caps *fresh* provider lookups. The caller hits this on every view of the signup form, not just on submission, so without a ceiling a crawler walking /auth/sign_up from a new range each time would set our ipapi.is bill. Over budget we answer "unknown" and install nothing -- never "flagged". Cache hits are free and uncounted, and the webhook path never spends from this budget. - Blocks installed here are recorded in their own table, keyed by the CIDR/domain rather than by account (there is no account yet), and are folded into /api/blocks and the reconcile pass so neither one under-reports as blocking shifts to the pre-signup path. The published entry shape is unchanged; a range blocked before anyone signed up from it simply reads "signups": 0. - A repeat query for an already-installed block skips the Mastodon round trip. This runs on a live signup request, so that is saved latency.
This commit is contained in:
1 parent
8490048d2d
commit
57234ca548
5 files changed
+758
-4
No files matched your search
@@ -43,6 +43,28 @@ server {
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
# Reputation query API (POST /api/reputation). Called by Mastodon on
|
||||
# mammut during signup, so it has to be reachable from off-box — unlike
|
||||
# /webhook this one is authenticated with a shared secret
|
||||
# (X-Reputation-Key) rather than an HMAC over the body, and it is gated in
|
||||
# the app by REPUTATION_API_ENABLED + REPUTATION_API_KEY: with either
|
||||
# unset the app 404s this path.
|
||||
#
|
||||
# It sits on a live signup request, so the proxy timeouts are short: the
|
||||
# caller gives up after ~2s anyway and proceeds without an answer, and a
|
||||
# request left hanging here would just hold a Puma thread on mammut for no
|
||||
# benefit.
|
||||
location = /api/reputation {
|
||||
proxy_pass http://127.0.0.1:8087;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_connect_timeout 2s;
|
||||
proxy_send_timeout 5s;
|
||||
proxy_read_timeout 5s;
|
||||
}
|
||||
|
||||
location / {
|
||||
return 404;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user