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