matrix apiUrl: default to https on the gateway vhost
hive-c0re logs in with the hive's matrix sender token and creates the Space and rooms over swarm.matrix.apiUrl. On a hive that does not run the homeserver that crosses the network, so the default is now https://<gatewayHost>. hive-c0re already verifies against the hive trust bundle (SSL_CERT_FILE: system CAs, swarm root and the store's services root), which covers the gateway's leaf for that name. Also drops the remaining loopback-default wording in hive-c0re's matrix module and the openFirewall description, and pins the https default on a hive host without the homeserver in module-eval-matrix-core.
This commit is contained in:
parent
bed4358e19
commit
55a67e38fa
7 changed files with 56 additions and 35 deletions
|
|
@ -83,11 +83,18 @@ pin the value before the homeserver mints any ids under the default.
|
||||||
## Default-closed firewall
|
## Default-closed firewall
|
||||||
|
|
||||||
`deploy.matrix.openFirewall` defaults to `false`: hive-c0re and agent
|
`deploy.matrix.openFirewall` defaults to `false`: hive-c0re and agent
|
||||||
containers on every hive reach the homeserver at `chat.<swarm-domain>`
|
containers reach the homeserver at `chat.<swarm-domain>` via the gateway,
|
||||||
via the gateway, so the firewall hole only matters for direct access to
|
so the firewall hole only matters for direct access to `httpPort` from
|
||||||
`httpPort` from *outside* the host. Flip to `true` when
|
*outside* the host. Flip to `true` when announcing the homeserver to
|
||||||
announcing the homeserver to other hives or when an external matrix
|
other hives or when an external matrix client needs to reach the
|
||||||
client needs to reach the client-server API directly.
|
client-server API directly.
|
||||||
|
|
||||||
|
hive-c0re provisions matrix (its own sender login, the hive Space and
|
||||||
|
chat room, invites) through `swarm.matrix.apiUrl`, which defaults to
|
||||||
|
`https://<swarm.matrix.gatewayHost>` on every hive. That login carries
|
||||||
|
the hive's matrix access token, and on a hive that doesn't run the
|
||||||
|
homeserver it crosses the network, so the default is TLS; hive-c0re
|
||||||
|
verifies the gateway's certificate against the hive trust bundle.
|
||||||
|
|
||||||
Federation port 8448 is intentionally not opened here — tuwunel
|
Federation port 8448 is intentionally not opened here — tuwunel
|
||||||
serves the federation API on the same `httpPort` as client-server
|
serves the federation API on the same `httpPort` as client-server
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,8 @@ use reqwest::StatusCode;
|
||||||
/// fallback: `localhost:8008` is right only when the homeserver happens to
|
/// fallback: `localhost:8008` is right only when the homeserver happens to
|
||||||
/// share this daemon's netns, and an address baked into the binary is one
|
/// share this daemon's netns, and an address baked into the binary is one
|
||||||
/// that builds fine and then talks to the wrong machine. The nix module
|
/// that builds fine and then talks to the wrong machine. The nix module
|
||||||
/// supplies the loopback address when it is itself the thing running
|
/// defaults it to `https://` on the homeserver's gateway vhost, on every
|
||||||
/// tuwunel, where it is not a guess but a fact about what it just started.
|
/// hive whichever host runs tuwunel.
|
||||||
///
|
///
|
||||||
/// Also not an agent-facing address either way. An agent has its own netns;
|
/// Also not an agent-facing address either way. An agent has its own netns;
|
||||||
/// agents are handed the gateway vhost via `HIVE_MATRIX_URL`, and get
|
/// agents are handed the gateway vhost via `HIVE_MATRIX_URL`, and get
|
||||||
|
|
@ -126,12 +126,9 @@ pub fn hive_chat_room_id_path() -> PathBuf {
|
||||||
|
|
||||||
/// Whether this hive has a homeserver to provision against.
|
/// Whether this hive has a homeserver to provision against.
|
||||||
///
|
///
|
||||||
/// **A configured API URL, not a local container.** It used to scan
|
/// **A configured API URL, not a local container**: whether the homeserver
|
||||||
/// `nixos-container list` for `hive-matrix`, which answers a different
|
/// runs on this host is a different question, and a remote homeserver is
|
||||||
/// question — "is the homeserver a container on this host" — and so made a
|
/// provisioned through the same URL.
|
||||||
/// remote homeserver silently no-op no matter how it was addressed. The
|
|
||||||
/// nix module still supplies the loopback URL whenever it runs tuwunel
|
|
||||||
/// itself, so a co-located hive behaves exactly as before.
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn is_present() -> bool {
|
pub fn is_present() -> bool {
|
||||||
matrix_http().is_some()
|
matrix_http().is_some()
|
||||||
|
|
|
||||||
|
|
@ -126,15 +126,12 @@ in
|
||||||
imports = [
|
imports = [
|
||||||
./options.nix
|
./options.nix
|
||||||
./theme.nix
|
./theme.nix
|
||||||
# Hive-CA trust for this daemon's outbound TLS. Nothing it is given by
|
# Hive-CA trust for this daemon's outbound TLS. The matrix provisioning
|
||||||
# default is https — the forge and matrix URLs are plain http, and the
|
# URL (`swarm.matrix.apiUrl`) defaults to https on the homeserver's
|
||||||
# queue's TLS is verified against `HIVE_C0RE_OIDC_CA_FILE`
|
# gateway vhost, which serves a leaf chaining to the store's services
|
||||||
# (../hive-tls.nix), not this bundle — so this
|
# root or the swarm root — CAs generated at runtime, which no
|
||||||
# changes nothing on an all-local hive. It matters for the split-host
|
# build-time trust store can contain. The queue's TLS is verified
|
||||||
# shape the options invite: `swarm.matrix.apiUrl`'s own example is
|
# against `HIVE_C0RE_OIDC_CA_FILE` (../hive-tls.nix), not this bundle.
|
||||||
# `https://matrix.example.com`, and pointing it at another hive's
|
|
||||||
# gateway means verifying a leaf signed by a CA generated at runtime,
|
|
||||||
# which no build-time trust store can contain.
|
|
||||||
#
|
#
|
||||||
# ⚠️ `SSL_CERT_FILE` REPLACES the trust store, and unlike the other
|
# ⚠️ `SSL_CERT_FILE` REPLACES the trust store, and unlike the other
|
||||||
# consumers of this helper, hive-c0re already makes a *public*-TLS call:
|
# consumers of this helper, hive-c0re already makes a *public*-TLS call:
|
||||||
|
|
|
||||||
|
|
@ -181,9 +181,9 @@ in
|
||||||
# Client-server API base hive-c0re uses to provision matrix (register
|
# Client-server API base hive-c0re uses to provision matrix (register
|
||||||
# agent users, create the hive space + chat room, invite members).
|
# agent users, create the hive space + chat room, invite members).
|
||||||
# Supplied by `services.hyperhive.swarm.matrix.apiUrl`, which defaults to
|
# Supplied by `services.hyperhive.swarm.matrix.apiUrl`, which defaults to
|
||||||
# the same gateway vhost as HIVE_MATRIX_URL above but is its own option,
|
# the same gateway vhost as HIVE_MATRIX_URL above, over https because it
|
||||||
# so an operator can point provisioning elsewhere without changing what
|
# carries the hive's matrix token and may cross the network. Its own
|
||||||
# agents are handed.
|
# option, so provisioning can point elsewhere without changing agents.
|
||||||
HIVE_MATRIX_API_URL = config.services.hyperhive.swarm.matrix.apiUrl;
|
HIVE_MATRIX_API_URL = config.services.hyperhive.swarm.matrix.apiUrl;
|
||||||
}
|
}
|
||||||
// {
|
// {
|
||||||
|
|
|
||||||
|
|
@ -64,10 +64,10 @@ in
|
||||||
|
|
||||||
apiUrl = lib.mkOption {
|
apiUrl = lib.mkOption {
|
||||||
type = lib.types.nullOr lib.types.str;
|
type = lib.types.nullOr lib.types.str;
|
||||||
default = if cfg.gatewayHost == null then null else "http://${cfg.gatewayHost}";
|
default = if cfg.gatewayHost == null then null else "https://${cfg.gatewayHost}";
|
||||||
defaultText = lib.literalExpression ''
|
defaultText = lib.literalExpression ''
|
||||||
if services.hyperhive.swarm.matrix.gatewayHost == null then null
|
if services.hyperhive.swarm.matrix.gatewayHost == null then null
|
||||||
else "http://''${services.hyperhive.swarm.matrix.gatewayHost}"
|
else "https://''${services.hyperhive.swarm.matrix.gatewayHost}"
|
||||||
'';
|
'';
|
||||||
example = "https://matrix.example.com";
|
example = "https://matrix.example.com";
|
||||||
description = ''
|
description = ''
|
||||||
|
|
@ -77,10 +77,14 @@ in
|
||||||
`hyperhive.matrix.url`, which is the gateway vhost handed to
|
`hyperhive.matrix.url`, which is the gateway vhost handed to
|
||||||
each agent's `hive-matrix-daemon`.
|
each agent's `hive-matrix-daemon`.
|
||||||
|
|
||||||
Defaults to the homeserver's gateway vhost (`gatewayHost`), the
|
Defaults to `https://` on the homeserver's gateway vhost
|
||||||
same name on every hive whichever host runs tuwunel, and `null`
|
(`gatewayHost`), the same name on every hive whichever host runs
|
||||||
when there is no vhost. Set it explicitly when the homeserver is
|
tuwunel, and `null` when there is no vhost. hive-c0re logs in
|
||||||
reachable only some other way.
|
with the hive's matrix sender token over this URL, so it crosses
|
||||||
|
the network whenever hive-c0re is not on the homeserver's host:
|
||||||
|
an `http://` value sends that token in cleartext. hive-c0re
|
||||||
|
verifies the gateway's certificate against the hive trust bundle
|
||||||
|
(system CAs plus the swarm and services roots).
|
||||||
|
|
||||||
`null` means hive-c0re has no homeserver to provision against
|
`null` means hive-c0re has no homeserver to provision against
|
||||||
and matrix provisioning no-ops. There is deliberately no
|
and matrix provisioning no-ops. There is deliberately no
|
||||||
|
|
|
||||||
|
|
@ -431,10 +431,10 @@ in
|
||||||
example = true;
|
example = true;
|
||||||
description = ''
|
description = ''
|
||||||
Open `httpPort` in the host firewall. Off by default
|
Open `httpPort` in the host firewall. Off by default
|
||||||
(secure-by-default): the host reaches the homeserver on
|
(secure-by-default): hive-c0re and agent containers reach the
|
||||||
loopback, and agent containers reach it at `gatewayHost`'s vhost
|
homeserver at `gatewayHost`'s vhost (`chat.<swarm-domain>` by
|
||||||
(`chat.<swarm-domain>` by default) via the gateway — so the firewall open only matters for
|
default) via the gateway, so the open port only matters for
|
||||||
access from outside the host. Flip to `true` when announcing
|
direct access to `httpPort` from outside the host. Flip to `true` when announcing
|
||||||
the homeserver to other hives or when an external matrix
|
the homeserver to other hives or when an external matrix
|
||||||
client needs to reach the client-server API directly.
|
client needs to reach the client-server API directly.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,10 @@ let
|
||||||
# The same hive with the identity taken away, which separates "a homeserver
|
# The same hive with the identity taken away, which separates "a homeserver
|
||||||
# is deployed" from "this host can authenticate to the store".
|
# is deployed" from "this host can authenticate to the store".
|
||||||
matrixNoBaoIdentity = hive { deploy.matrix.enable = true; };
|
matrixNoBaoIdentity = hive { deploy.matrix.enable = true; };
|
||||||
|
|
||||||
|
# A hive host that does not run the homeserver: its hive-c0re reaches the
|
||||||
|
# homeserver across the network.
|
||||||
|
matrixElsewhere = hive { };
|
||||||
cases = [
|
cases = [
|
||||||
{
|
{
|
||||||
# Absence arm, and what makes the one above able to fail: with no leaf
|
# Absence arm, and what makes the one above able to fail: with no leaf
|
||||||
|
|
@ -74,6 +78,18 @@ let
|
||||||
&& !(s.hive-c0re.environment ? BAO_ADDR)
|
&& !(s.hive-c0re.environment ? BAO_ADDR)
|
||||||
&& !(lib.any (c: lib.hasPrefix "bao-" c) s.hive-c0re.serviceConfig.LoadCredential);
|
&& !(lib.any (c: lib.hasPrefix "bao-" c) s.hive-c0re.serviceConfig.LoadCredential);
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
# hive-c0re logs in with the hive's matrix token over this URL, and on a
|
||||||
|
# host without the homeserver that login crosses the network, so the
|
||||||
|
# default must be TLS all the way to the daemon's environment.
|
||||||
|
name = "hive-c0re provisions matrix over https from a hive that does not run it";
|
||||||
|
ok =
|
||||||
|
!matrixElsewhere.services.hyperhive.deploy.matrix.enable
|
||||||
|
&& matrixElsewhere.services.hyperhive.swarm.matrix.apiUrl == "https://chat.t.local"
|
||||||
|
&&
|
||||||
|
matrixElsewhere.systemd.services.hive-c0re.environment.HIVE_MATRIX_API_URL
|
||||||
|
== "https://chat.t.local";
|
||||||
|
}
|
||||||
];
|
];
|
||||||
in
|
in
|
||||||
runGroup "matrix-core" cases
|
runGroup "matrix-core" cases
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue