Watch
0
0
Fork
You've already forked hyperhive
0

hive-tls: no hive leaf or hive identity on a gateway host without a hive

A self-signed gateway on a host with deploy.hive-controller.enable off
(a dedicated swarm-services host) needed the hive leaf for its catch-all,
and that leaf now comes only from hive-tls-resign with a per-hive store
identity. hive-tls-resign and its timer are now defined only where a hive
runs; elsewhere hive-gateway-self-signed-cert installs the swarm-services
leaf as the default cert, and the gateway waits for swarm-services-cert.
Also corrects the hive-gateway comments and option text that still said
the leaf is hive-CA-signed.

Refs #4588
This commit is contained in:
atlas 2026-10-04 16:56:10 +02:00 • committed by mara
commit 75a7dccee6
6 changed files with 90 additions and 24 deletions

View file

@ -25,6 +25,10 @@ let
swarmServiceDomains = config.services.hyperhive.swarm.serviceDomains;
matrixCfg = config.services.hyperhive.swarm.matrix;
matrixDeployCfg = config.services.hyperhive.deploy.matrix;
tlsStateDir = config.services.hyperhive.deploy.hive-controller.tls.stateDir;
# The hive leaf exists only where a hive runs; ../hive-tls.nix issues it
# under that same condition.
runsHive = config.services.hyperhive.deploy.hive-controller.enable;
# Every vhost claiming `default_server`, ours and the operator's
# alike. Computed once so the assertion below and the message it
@ -45,7 +49,7 @@ let
# Self-signed TLS is the implicit floor: when neither an operator cert
# (`tls.certDir`) nor ACME (`tls.acme.enable`) is configured, the gateway
# generates + serves a hive-CA-signed leaf (see hive-tls.nix). There is no
# serves a leaf the secret store issues (see hive-tls.nix). There is no
# explicit toggle and no http-only mode — matrix discovery requires https,
# so the gateway always terminates TLS.
# `cfg.useSelfSigned` (options.nix) is the derived single source of truth.
@ -57,15 +61,16 @@ let
# certs for no gain.
tlsDir = "/var/lib/hive-gateway/tls";
# TLS cert + key paths.
# - self-signed (default): the hive-CA-signed leaf, imported into the
# state dir by `hive-gateway-self-signed-cert` below.
# - self-signed (default): the hive leaf the store issues (the
# swarm-services leaf on a host with no hive), imported into the state
# dir by `hive-gateway-self-signed-cert` below.
# - tls.certDir set: the operator's own cert dir, read directly.
tlsCert =
if cfg.tls.certDir != null then "${cfg.tls.certDir}/${cfg.tls.certName}" else "${tlsDir}/cert.pem";
tlsKey =
if cfg.tls.certDir != null then "${cfg.tls.certDir}/${cfg.tls.keyName}" else "${tlsDir}/key.pem";
# The swarm-services pair, used only by the vhosts whose names this
# hive's CA cannot sign. Self-signed mode only: with an operator cert
# The swarm-services pair, used only by the vhosts whose names the
# hive leaf cannot carry. Self-signed mode only: with an operator cert
# or ACME the operator owns every name and there is no second issuer.
svcCert = "${tlsDir}/swarm-services.pem";
svcKey = "${tlsDir}/swarm-services-key.pem";
@ -244,7 +249,7 @@ in
defaults.email = cfg.tls.acme.email;
};
# Import the hive-CA leaf into nginx's state dir before nginx starts.
# Import the gateway leaves into nginx's state dir before nginx starts.
#
# 🚨 DO NOT "simplify" this into pointing nginx at the CA dir. It does
# TWO jobs: it re-modes the leaf to the 0640 root:nginx copy below (a
@ -292,18 +297,27 @@ in
# read it — a 0600 root:root key passes the master load but
# fails the pre-start config test with `BIO_new_file() …
# Permission denied`, blocking the unit. Cert is world-read.
install -m 0644 ${config.services.hyperhive.deploy.hive-controller.tls.stateDir}/gateway.pem ${tlsCert}
install -m 0640 -g nginx ${config.services.hyperhive.deploy.hive-controller.tls.stateDir}/gateway-key.pem ${tlsKey}
${
if runsHive then
''
install -m 0644 ${tlsStateDir}/gateway.pem ${tlsCert}
install -m 0640 -g nginx ${tlsStateDir}/gateway-key.pem ${tlsKey}''
else
''
# No hive here, so no hive leaf: the catch-all and any other
# vhost on the hive cert path serve the swarm-services leaf.
install -m 0644 ${tlsStateDir}/swarm-services.pem ${tlsCert}
install -m 0640 -g nginx ${tlsStateDir}/swarm-services-key.pem ${tlsKey}''
}
# The swarm-services leaf, when this host issues one. It is
# a separate pair rather than more SANs on the one above
# because no hive CA can sign these names — each is
# constrained to its own hive's domain and the service
# names are siblings of it.
# because the hive leaf's role allows only its own hive's
# domain, and the service names are siblings of it.
#
# Absent is a normal state, not a failure: the leaf exists
# only where the swarm CA is autoconfigured, and issuance
# can also fail on a host that wants one.
# Absent is a normal state, not a failure: a host fronting
# no swarm name has none, and issuance can also fail on a
# host that wants one.
#
# ⚠️ When it is absent the HIVE leaf goes to this path
# anyway, and that fallback is load-bearing rather than