From 4bb44daf03004803cb1acca644cd2a066e568e10 Mon Sep 17 00:00:00 2001 From: atlas Date: Thu, 10 Sep 2026 22:24:58 +0200 Subject: [PATCH] swarm-nats, swarm-victorialogs: correct two comments that describe a topology we do not have MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both claims are load-bearing prose, and both are wrong in a way nothing in the tree reads (#4168). swarm-nats says the queue is "reachable from every agent container on the hive" because the container shares the host netns — in a comment, and again in the operator-facing `calloutUserPublicKey` description, which renders into the options doc. Agent containers do not share it: `PRIVATE_NETWORK=1` is written unconditionally (hive-priv/src/main.rs, and hive-priv-sock says "isolation is the only supported mode"), and hive-network.nix states the shared-netns mode was removed. The bridge firewall opens 53/67/80/443 plus `exposeHostPorts`, whose only consumer tree-wide is otel — the queue's port is in none of them, and no gateway route exists either (`grep -c nats` in hive-gateway/default.nix -> 0; control `forge` -> 3, so the zero means something). Its actual clients are host-side: HIVE_C0RE_NATS_URL and SWARM_CONTROLLER_NATS_URL, both 127.0.0.1 on a single-host swarm, plus each remote hive dialling a routable address. swarm-victorialogs says the ingest endpoint has "no authentication of its own". Upstream offers Basic Auth via -httpAuth.username / -httpAuth.password (and -metricsAuthKey / -deleteAuthKey / -pprofAuthKey); this module sets none of it. "The software offers nothing" and "we configure nothing" send a later reader to different places, so the wording now says the second one. Neither conclusion changes. The queue must still refuse everyone until the callout responder exists, and the logs endpoint must still be pinned to loopback — only the reasons were false. Checked while here: swarm-authelia's identical "no authentication of its own" is TRUE (upstream's telemetry.metrics has exactly enabled, address, buffers, timeouts), and otel.nix's "reachable from agent containers and nowhere else" is true and better-founded than it claims — the receiver binds the bridge IP, not just a firewall hole. Refs #4168. --- nix/host-modules/swarm-nats.nix | 19 ++++++++++++------- nix/host-modules/swarm-victorialogs.nix | 7 ++++--- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/nix/host-modules/swarm-nats.nix b/nix/host-modules/swarm-nats.nix index 9acd2e56..84b9e930 100644 --- a/nix/host-modules/swarm-nats.nix +++ b/nix/host-modules/swarm-nats.nix @@ -347,8 +347,9 @@ in callout approval — it is the one that answers auth requests, so it cannot wait for itself. **That exemption is exactly why it needs a credential of its own**: without one the escape hatch is - an open door, and on a container sharing the host netns it is an - open door reachable from every agent container. + an open door, and it stands open to everything that can reach the + queue — every process on the host serving it, and every remote + hive in a multi-host swarm. An nkey rather than a password for the same reason `calloutIssuerPublicKey` is: only the public half appears here, @@ -569,13 +570,17 @@ in # Journal files on the host, not inside the container: nixpkgs hardcodes # --link-journal=try-guest, and EXTRA_NSPAWN_FLAGS expands after it. extraFlags = [ "--link-journal=host" ]; - # Shared host netns, like every sibling container. + # Shared host netns, like every sibling swarm container. # # ⚠️ Which is exactly why the server below must refuse everyone - # until the callout responder exists: on this netns the queue is - # reachable from every agent container on the hive, so an - # unauthenticated interim state would be a hole rather than a - # rough edge. + # until the callout responder exists: the queue is on the host's + # own loopback, in reach of every process there and every sibling + # on this netns, and each remote hive in a multi-host swarm dials + # it directly. An unauthenticated interim state would be a hole + # rather than a rough edge. + # + # Not agent containers, though: they have a netns of their own and + # the bridge firewall does not open this port. privateNetwork = false; # Binds only the public trust bundle, read-only. Empty when the gateway # is not self-signed, so the whole trust path drops out cleanly. diff --git a/nix/host-modules/swarm-victorialogs.nix b/nix/host-modules/swarm-victorialogs.nix index ddead0d2..ca91ea12 100644 --- a/nix/host-modules/swarm-victorialogs.nix +++ b/nix/host-modules/swarm-victorialogs.nix @@ -264,9 +264,10 @@ in # ⚠️ PINNED TO LOOPBACK for the same reason the metrics store is, # and it matters more here: upstream's default listens on every - # interface, and this endpoint accepts writes as well as reads - # with no authentication of its own. The bind address is the - # boundary. + # interface, and this endpoint accepts writes as well as reads. + # Nothing authenticates it either — upstream offers one basic-auth + # pair (`-httpAuth.username` / `-httpAuth.password`) and this + # module sets neither. The bind address is the boundary. listenAddress = "127.0.0.1:${toString cfg.port}"; extraOptions = [ "-retentionPeriod=${deployCfg.victorialogs.retentionPeriod}" ];