feat(synapse): restrict /_synapse/admin to LAN, track the stack
Synapse mounts its admin API on the same vhost as the client API, so publishing matrix.phasefinal.com published the admin surface too -- it answered 200 from the open internet. HMAC-protected, so not an open door, but Synapse's own guidance is to keep it off the public listener. A higher-priority router (explicit priority 100, not relying on Traefik's rule-length tie-break) scopes PathPrefix(/_synapse/admin) behind an ipallowlist. Verified from a genuinely external vantage rather than from a fleet host, since nh3-dev sits inside the allowed range and would have proved nothing: via the NH3 residential egress proxy the admin path returns 403 while the client API returns 200 and Element is unaffected. The 10.0.0.0/8 entry matches nothing today and the comment says so rather than implying fleet access exists. matrix.phasefinal.com resolves publicly, so fleet hosts hairpin out their own WAN -- a request from nh3-dev arrived as 70.230.226.88. The rule is effectively deny-all through Traefik, which is the intended posture: admin work goes through docker exec to localhost:8008 and never traverses Traefik. Allow-listing the sites' WAN addresses was considered and rejected as a maintenance trap on dynamic addresses. Also brings the stack under stacks/ with the Postgres password replaced by a required .env variable. The tracked copy and the live file have therefore DIVERGED and deploy-stack.sh must not be used until the live file reads from a .env; the README says so.
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
# synapse — Matrix homeserver (ana-docker)
|
||||
|
||||
Canonical copy of the stack running at `/opt/docker/compose/synapse/` on
|
||||
**ana-docker** (`10.250.50.70`). Serves `matrix.phasefinal.com` and
|
||||
`chat.phasefinal.com` through Traefik.
|
||||
|
||||
Deep documentation — current versions, the upgrade procedure, the appservice
|
||||
namespace decision, conventions, and the push-notification findings — lives in
|
||||
[`docs/pfi/vm-102-matrix-synapse.md`](../../docs/pfi/vm-102-matrix-synapse.md).
|
||||
This file covers only what is specific to deploying the stack.
|
||||
|
||||
## ⚠ The password is NOT in this copy
|
||||
|
||||
The live compose carries `POSTGRES_PASSWORD` **inline in plaintext**. This
|
||||
tracked copy replaces it with `${POSTGRES_PASSWORD:?set in .env}` so the secret
|
||||
is not committed.
|
||||
|
||||
**They have therefore diverged**, and `deploy-stack.sh` would push the
|
||||
placeholder over a working literal and break the database on next recreate.
|
||||
Do not deploy this stack from the repo until the live file has been converted
|
||||
to read from a `.env` — which is the right fix and is not done yet.
|
||||
|
||||
Until then: **edit the live file on the host, then re-mirror to here.**
|
||||
|
||||
## /_synapse/admin is LAN-only
|
||||
|
||||
Synapse mounts its admin API on the same vhost as the client API, so publishing
|
||||
`matrix.phasefinal.com` published the admin surface with it — it answered 200
|
||||
from the open internet until 2026-09-01.
|
||||
|
||||
A higher-priority router now scopes `PathPrefix(/_synapse/admin)` behind an
|
||||
`ipallowlist`. Verified from a genuinely external vantage (the NH3 residential
|
||||
egress proxy, not a fleet host): admin **403**, client API **200**, Element
|
||||
unaffected.
|
||||
|
||||
⚠ The `10.0.0.0/8` entry currently matches nothing, deliberately. The hostname
|
||||
resolves publicly, so fleet hosts hairpin out their own WAN and arrive as a
|
||||
public address — a request from nh3-dev measured as `70.230.226.88`. The rule is
|
||||
effectively **deny-all through Traefik**, which is intended: admin work is done
|
||||
with `docker exec synapse` against `localhost:8008`, which never touches
|
||||
Traefik. Allow-listing the sites' WAN addresses was rejected — they are dynamic,
|
||||
and a stale entry either locks us out or hands admin to whoever inherits the
|
||||
address.
|
||||
|
||||
## Upgrades
|
||||
|
||||
**Take a verified `pg_dump` first.** Schema migrations are one-way; an older
|
||||
Synapse will not start against a newer database, so rollback is restore, not
|
||||
revert. Full procedure in the docs link above.
|
||||
Reference in New Issue
Block a user