floonet-strfry: co-locate the name authority on the relay domain (toggle)
Serve the authority's NIP-05 lookup on the relay's own domain so `name@relay.example` resolves, without giving the authority a second vhost/cert. Live on us-east: relay.floonet.dev now answers /.well-known/nostr.json from the co-located authority (127.0.0.1:8193) while the WebSocket relay and NIP-11 stay untouched. * deploy/us-east/colocated-authority.conf The nginx opt-in: an exact-match `location = /.well-known/nostr.json` proxied to the authority ahead of the relay's WebSocket catch-all. Only the READ path is exposed; registration and the rest of /api/* stay on the authority's own domain. Sets X-Real-IP (the per-IP rate limiter keys off it). Same proxy shape as nm.floonet.dev.conf. * README.md — "Co-locating names on the relay domain": the Caddy/compose stack is co-located by default (single FLOONET_DOMAIN); a split nginx deploy opts in with the snippet. Documents FLOONET_AUTHORITY_COLOCATED. * deploy/Caddyfile, .env.example — note the single-domain stack is co-located by default and point split deploys at the snippet. The box vhost mirrors this snippet exactly; applied with nginx -t + reload (no restart), firewalld untouched.
This commit is contained in:
@@ -19,6 +19,13 @@ FLOONET_BASE_URL=https://floonet.example
|
||||
# at your own wss:// URL (normally wss://FLOONET_DOMAIN).
|
||||
FLOONET_RELAYS=wss://floonet.example
|
||||
|
||||
# Co-located names (FLOONET_AUTHORITY_COLOCATED): this compose stack is single
|
||||
# domain, so names AND the relay are already served on FLOONET_DOMAIN
|
||||
# (`name@FLOONET_DOMAIN` resolves) — on by default, nothing to set here. Only a
|
||||
# SPLIT deploy that puts the relay and the authority on separate subdomains
|
||||
# behind nginx needs to opt in; see "Co-locating names on the relay domain" in
|
||||
# the README and deploy/us-east/colocated-authority.conf.
|
||||
|
||||
# --- The kind whitelist (the keystone) ---
|
||||
|
||||
# Comma-separated event kinds the relay stores. DEFAULT-DENY: anything not
|
||||
|
||||
@@ -155,6 +155,35 @@ NIP-98 requests are verified fully: signature, kind 27235, `u`/`method`/
|
||||
`payload` tags against `FLOONET_BASE_URL`, a freshness window, and one-time
|
||||
event ids (replay rejection).
|
||||
|
||||
## Co-locating names on the relay domain
|
||||
|
||||
`FLOONET_AUTHORITY_COLOCATED` controls whether the authority's NIP-05 lookup
|
||||
(`/.well-known/nostr.json`) is served on the **relay's own domain**, so
|
||||
`name@relay.example` resolves without the authority needing its own hostname.
|
||||
|
||||
- **Docker Compose / Caddy: on by default.** The whole stack lives on one
|
||||
`FLOONET_DOMAIN`; `deploy/Caddyfile` routes `/.well-known/nostr.json` (and
|
||||
`/api/*`) to the authority and everything else to the relay, so
|
||||
`name@FLOONET_DOMAIN` just works. Nothing to configure.
|
||||
|
||||
- **Split nginx deploy: opt in.** When the relay and the authority run on
|
||||
separate subdomains (the `deploy/us-east/` pattern — relay on
|
||||
`relay.example`, the authority's own vhost on `nm.example`), enable it by
|
||||
including the shipped snippet in the relay vhost's `:443` server block,
|
||||
ahead of the WebSocket catch-all:
|
||||
|
||||
```nginx
|
||||
# inside server { listen ...:443 ssl ...; server_name relay.example; }
|
||||
# BEFORE location / { ...websocket... }
|
||||
include /etc/nginx/snippets/floonet-colocated-authority.conf; # deploy/us-east/colocated-authority.conf
|
||||
```
|
||||
|
||||
Then `nginx -t && nginx -s reload`, and
|
||||
`https://relay.example/.well-known/nostr.json?name=<n>` returns the
|
||||
authority's JSON. Only the exact-match read path is co-located; registration
|
||||
and the rest of `/api/*` stay on the authority's own domain. The snippet sets
|
||||
`X-Real-IP` (load-bearing — the authority's per-IP rate limiter keys off it).
|
||||
|
||||
## Mixnet exit (optional)
|
||||
|
||||
Uncomment `COMPOSE_PROFILES=exit` in `.env` and the package also runs
|
||||
|
||||
+6
-3
@@ -17,9 +17,12 @@
|
||||
# forwardable client header.
|
||||
|
||||
# NIP-05 resolution and the registration/paid API go to the authority.
|
||||
# gzip is scoped here (HTTP/JSON) and deliberately NOT applied to the
|
||||
# relay path: strfry already negotiates permessage-deflate on the
|
||||
# WebSocket.
|
||||
# This single-domain stack is co-located by design: names AND the relay
|
||||
# answer on FLOONET_DOMAIN (the FLOONET_AUTHORITY_COLOCATED=on default;
|
||||
# a split nginx deploy opts in via deploy/us-east/colocated-authority.conf
|
||||
# instead — see the README). gzip is scoped here (HTTP/JSON) and
|
||||
# deliberately NOT applied to the relay path: strfry already negotiates
|
||||
# permessage-deflate on the WebSocket.
|
||||
@authority {
|
||||
path /.well-known/nostr.json /.well-known/nostr.json/* /api/*
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
# Co-located Floonet name authority — the FLOONET_AUTHORITY_COLOCATED=on toggle.
|
||||
#
|
||||
# Serve NIP-05 names on the RELAY's own domain (so `name@relay.example`
|
||||
# resolves) WITHOUT giving the authority its own vhost/cert. This is only
|
||||
# needed for a split deploy where the relay and the authority live on separate
|
||||
# subdomains behind nginx (the deploy/us-east/ pattern: relay.floonet.dev +
|
||||
# nm.floonet.dev). The Docker Compose / Caddy stack is already co-located on a
|
||||
# single FLOONET_DOMAIN, so it does not need this file.
|
||||
#
|
||||
# ENABLE (== FLOONET_AUTHORITY_COLOCATED=on): include this inside the relay's
|
||||
# `:443` server block, BEFORE its `location /` WebSocket catch-all, e.g.
|
||||
#
|
||||
# include /etc/nginx/snippets/floonet-colocated-authority.conf;
|
||||
#
|
||||
# then `nginx -t && nginx -s reload`. DISABLE by removing the include.
|
||||
#
|
||||
# Only the exact-match READ lookup is exposed; registration and the rest of
|
||||
# /api/* stay on the authority's own domain. The `location =` exact match wins
|
||||
# over the relay catch-all regardless of file order, but keep it above
|
||||
# `location /` for readability.
|
||||
#
|
||||
# Port 8193 is this box's authority bind (FLOONET_NAMES_BIND); the compose
|
||||
# stack uses 8191 — match your own. X-Real-IP is SECURITY-CRITICAL: the
|
||||
# authority keys ALL per-IP rate limiting off it, so a missing value collapses
|
||||
# every client into one bucket and defeats the limiter.
|
||||
location = /.well-known/nostr.json {
|
||||
proxy_pass http://127.0.0.1:8193;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
}
|
||||
Reference in New Issue
Block a user