hive-gateway: self-signed TLS for matrix-client well-known fetch (closes #837)
This commit is contained in:
parent
76d3267b55
commit
314f1774d8
2 changed files with 167 additions and 29 deletions
|
|
@ -21,11 +21,13 @@ Per-agent UIs stay sub-path because they're hyperhive-internal and base-path-awa
|
|||
|
||||
Operator points client at `<hive>`. Sequence:
|
||||
|
||||
1. Client fetches `http://<hive>/.well-known/matrix/client` → `{"m.homeserver":{"base_url":"http://matrix.<hive>"}}` (no port suffix when gateway listens on 80).
|
||||
1. Client fetches `https://<hive>/.well-known/matrix/client` → `{"m.homeserver":{"base_url":"https://matrix.<hive>"}}` (no port suffix when gateway listens on 443). With `selfSignedTls = false` the scheme drops to http and the port suffix reflects the bare `port` instead.
|
||||
2. Client connects to `matrix.<hive>/_matrix/client/...`.
|
||||
3. Gateway routes `/_matrix/*` → tuwunel at `127.0.0.1:8008`.
|
||||
|
||||
Federation peers fetch `.well-known/matrix/server` → `{"m.server":"matrix.<hive>"}` and connect to `matrix.<hive>:8448` per spec default. Gateway only listens on configured `port`; cross-hive federation needs either an SRV record (`_matrix._tcp.matrix.<hive>` → port 80) OR `matrix.openFirewall = true` so peers reach tuwunel's federation port directly. Hyperhive is mostly closed/internal, so this rarely bites.
|
||||
matrix-dart-sdk (FluffyChat etc.) hardcodes `https` for the well-known fetch regardless of input scheme, so the discovery endpoint MUST be https — see "Self-signed TLS" below for the cert generation that backs the default-on path.
|
||||
|
||||
Federation peers fetch `.well-known/matrix/server` → `{"m.server":"matrix.<hive>"}` and connect to `matrix.<hive>:8448` per spec default. Gateway only listens on configured `port` (+ `httpsPort` when TLS on); cross-hive federation needs either an SRV record (`_matrix._tcp.matrix.<hive>` → port 80 / 443) OR `matrix.openFirewall = true` so peers reach tuwunel's federation port directly. Hyperhive is mostly closed/internal, so this rarely bites.
|
||||
|
||||
## SPA fallback (Accept-header pattern)
|
||||
|
||||
|
|
@ -131,6 +133,22 @@ frontend-side derivation.
|
|||
|
||||
Next-up tracked separately: #14 (container netns isolation), TLS (#594).
|
||||
|
||||
## Self-signed TLS (`selfSignedTls`)
|
||||
|
||||
On by default since #837. The gateway generates a self-signed RSA-4096 cert at first boot (10-year validity) and listens on `httpsPort` (default 443) on every vhost beside the plain-http `port` (default 80).
|
||||
|
||||
**Why on by default**: matrix-dart-sdk (FluffyChat's SDK) hardcodes `https://<host>/.well-known/matrix/client` for homeserver discovery and refuses to fall back to plain http. Without TLS the browser client cannot bootstrap (#837). For headless agent traffic and operator dashboard reach plain http is fine, so the http listen stays in parallel — operators can keep using `http://<hive>/` from the dashboard if they don't care about the cert prompt.
|
||||
|
||||
**Cert shape**: subject CN = bare hive domain; subjectAltName covers `<hive>` + wildcard `*.<hive>` so all current and future sub-domain vhosts (matrix, forge, ...) validate under the same cert. Stored at `/var/lib/hive-gateway/tls/{cert,key}.pem` inside the gateway container (`ephemeral = false`, so persisted across container restart).
|
||||
|
||||
**Regeneration**: the generator unit (`hive-gateway-self-signed-cert.service`) is gated by `ConditionPathExists=!cert.pem`, so it's a one-shot. To rotate (e.g. cert leak, expiry approaching), delete `cert.pem` inside the gateway container and restart `nginx.service` — the generator runs as a `Before=` dependency. No automatic rotation; the cert is purely a workaround for the well-known fetch.
|
||||
|
||||
**Production**: operators fronting hyperhive with a real reverse proxy (caddy + ACME, traefik + Let's Encrypt, etc.) set `selfSignedTls = false`. The proxy handles termination upstream, the gateway listens on `port` only.
|
||||
|
||||
**Cert prompts**: browsers warn once per host on first visit. With the wildcard SAN, `https://<hive>/`, `https://matrix.<hive>/`, and `https://forge.<hive>/` are covered by the same cert, but the browser still prompts per origin (per-host security state). FluffyChat needs the user to accept both `matrix.<hive>` (the SPA itself) and `<hive>` (the well-known fetch endpoint).
|
||||
|
||||
**`.well-known/matrix/{client,server}` scheme**: switches to `https` when `selfSignedTls` is on, so matrix-dart-sdk doesn't downgrade and tuwunel federation peers get a TLS-fronted base_url. The legacy `/matrix/*` 301 redirect also flips to https.
|
||||
|
||||
## Firewall posture (host-level)
|
||||
|
||||
`hive-c0re.nix` opens the per-agent web-port range
|
||||
|
|
@ -141,6 +159,11 @@ Next-up tracked separately: #14 (container netns isolation), TLS (#594).
|
|||
firewall-open would defeat the single-front-door story (closes
|
||||
#621).
|
||||
|
||||
`services.hyperhive.gateway.openFirewall = true` opens `port` plus
|
||||
`httpsPort` when `selfSignedTls = true` (default). Operators who
|
||||
flip `selfSignedTls = false` to front the gateway with a real
|
||||
TLS-terminating reverse proxy on the host get only `port` opened.
|
||||
|
||||
Manager hashes into the same range since #753 (no more
|
||||
"manager pinned at 8000" special case), so one range opening covers
|
||||
every container.
|
||||
|
|
|
|||
Loading…
Reference in a new issue