From b106bb8c876953f6308e0b308bac96f6bccb8938 Mon Sep 17 00:00:00 2001 From: atlas Date: Sun, 31 May 2026 14:06:38 +0200 Subject: [PATCH] =?UTF-8?q?nix/hive-matrix:=20argus=20=F0=9F=9F=A1=20on=20?= =?UTF-8?q?#764=20=E2=80=94=20empty-gatewayHost=20assertion=20+=20federati?= =?UTF-8?q?on=20port=20doc?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Folds both 🟡 notes from argus's #764 review: 1. **Empty-string assertion on `cfg.gatewayHost`**: same footgun as the forge.domain rejection from #754 — empty would render `.` shaped garbage in both nginx server_name (wildcard catch-all, surprising) and /etc/hosts (invalid entry). Fail loud at toplevel build with a message pointing at `null` as the right opt-out. 2. **Federation port-8448 caveat in `gatewayHost` docs**: when the gateway listens on 80, `.well-known/matrix/server` advertises `${gatewayHost}` with no port suffix → matrix federation spec falls back to port 8448 → no listener on 8448 → cross-hive federation requires either `_matrix._tcp.${gatewayHost}` SRV record OR `services.hyperhive.matrix.openFirewall = true`. Hyperhive is mostly closed/internal so this rarely bites, but the option docs now flag it for the federation-curious operator. Verified: `gatewayHost = ""` triggers the new assertion at toplevel build with the expected message; default still resolves to `matrix.` cleanly. --- nix/modules/hive-matrix.nix | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/nix/modules/hive-matrix.nix b/nix/modules/hive-matrix.nix index 0b3b612f..05b97925 100644 --- a/nix/modules/hive-matrix.nix +++ b/nix/modules/hive-matrix.nix @@ -293,6 +293,19 @@ in #660 default = bare hive-domain). `gatewayHost` is just where the API listens behind nginx. The two are different — see the matrix-spec server-discovery flow. + + **Federation port caveat**: the `.well-known/matrix/server` + delegation advertises `''${gatewayHost}` with no port suffix + when the gateway listens on 80. Per the matrix federation + spec, peers fall back to port 8448 when no explicit port is + present — but the gateway only listens on the configured + `services.hyperhive.gateway.port`. Cross-hive federation + therefore needs either: + - a DNS SRV record (`_matrix._tcp.''${gatewayHost}` → port 80), + - or `services.hyperhive.matrix.openFirewall = true` so peers + can reach tuwunel's federation port directly. + Hyperhive is mostly closed/internal, so this rarely bites in + practice — but flagging for the federation-curious operator. ''; }; @@ -439,6 +452,22 @@ in stable hostname before enabling. ''; } + { + # Same footgun as forge.domain (#754): empty string renders + # `.` shaped garbage in both nginx server_name (treated + # as wildcard catch-all, surprising) and /etc/hosts (invalid + # entry). Argus 🟡 on #764 — fail loud here rather than ship + # the surprising behaviour. + assertion = cfg.gatewayHost == null || cfg.gatewayHost != ""; + message = '' + services.hyperhive.matrix.gatewayHost = "" is rejected. The + rendered URLs would be invalid (nginx wildcard catch-all for + an empty server_name, /etc/hosts rejects empty entries). + Use `null` to disable the gateway vhost entirely (tuwunel + stays direct on httpPort), or set a non-empty hostname like + "matrix.example.com" or "homeserver.internal". + ''; + } ]; # Generate the registration token at system activation time, BEFORE