diff --git a/nix/host-modules/hive-gateway/default.nix b/nix/host-modules/hive-gateway/default.nix index 5e95ad53..f8122f13 100644 --- a/nix/host-modules/hive-gateway/default.nix +++ b/nix/host-modules/hive-gateway/default.nix @@ -155,32 +155,6 @@ in "f /var/lib/hive-gateway/conf/gateway.htpasswd 0644 hive-core hive-core - -" ]; - # ⚠️ REMOVED WITH THE CONTAINER, and each one was a workaround for the - # boundary rather than a thing nginx or dnsmasq needed: - # - # - `privateNetwork = false` — the container already shared the host - # netns, which is why nginx bound host ports and `localhost` - # upstreams reached hive-c0re. On the host that is simply true. - # - `additionalCapabilities = [ "CAP_NET_ADMIN" ]` — dnsmasq refuses - # to start with a `dhcp-range` unless it holds NET_ADMIN, and - # nspawn's bounding set dropped it for a host-netns container. - # Host root has it. - # - `networking.firewall.enable = false` — a container sharing the - # host netns would run *its* firewall.service against the HOST - # ruleset, flushing nixos-fw and deleting the nixos-nat-* chains on - # every boot. With one machine there is one firewall (below). - # - `networking.resolvconf.enable = false` + the `hive-gateway-resolv` - # path/service pair — the container's /etc/resolv.conf was a - # one-shot copy frozen at start, so a host network change left - # dnsmasq forwarding to a resolver that was gone. The whole - # watch-copy-reload machine existed to bridge two files. There is - # now one. - # - three bind mounts — /run/hive-agent, /run/hive-state, and either - # /run/hive-tls (operator cert) or /run/hive-ca (self-signed); - # those last two are mutually exclusive mkIfs, so it was never - # four. All plain host paths now. - # - # See `docs/network.md::Resolver behaviour` for the resolver history. # ACME (Let's Encrypt) integration. nginx vhosts set # `enableACME = true` via the vhost builder; this provides the # shared ACME config (acceptTerms + email). @@ -191,15 +165,14 @@ in # Import the hive-CA leaf into nginx's state dir before nginx starts. # - # 🚨 THIS LOOKS LIKE A LEFTOVER OF THE CONTAINER AND IS NOT — do not - # "simplify" it into pointing nginx at the CA dir. It does TWO jobs: + # 🚨 DO NOT "simplify" this into pointing nginx at the CA dir. It + # does TWO jobs: # # (1) It re-modes the leaf. `hive-tls-ca` writes the key 0600 # root:root; nginx's pre-start `nginx -t` runs as the nginx # *user*, so a 0600 key fails the config test with # `BIO_new_file() … Permission denied` and blocks the unit — - # hence the 0640 root:nginx copy below. That is a file-mode fact, - # not a namespace one, and it did not go away with the container. + # hence the 0640 root:nginx copy below. # (2) It guarantees that **every cert path the nginx config names # exists** — which is what the swarm-services fallback at the # bottom of the script is for. nginx refuses to load a config diff --git a/nix/host-modules/hive-gateway/dnsmasq.nix b/nix/host-modules/hive-gateway/dnsmasq.nix index bc63e9dd..d5096188 100644 --- a/nix/host-modules/hive-gateway/dnsmasq.nix +++ b/nix/host-modules/hive-gateway/dnsmasq.nix @@ -69,11 +69,8 @@ dhcp-leasefile = "/var/lib/dnsmasq/dnsmasq.leases"; # No explicit upstream: non-hive queries follow dnsmasq's # resolv.conf default — the host's own `/etc/resolv.conf`, so the - # hive always uses the host's resolvers and follows them live. This - # used to be a *copy* nixos-container made at container start, kept - # fresh by a host-side path unit that pushed in a new one and - # reloaded dnsmasq; running on the host deleted both the copy and - # the machinery that watched it. Deliberately no fallback + # hive always uses the host's resolvers and follows them live with + # no copy to go stale. Deliberately no fallback # `server=`: dnsmasq queries # all known upstreams in parallel, so a hardcoded public resolver # would take a share of *normal* traffic, not just fill in when the diff --git a/nix/host-modules/hive-matrix.nix b/nix/host-modules/hive-matrix.nix index d27441ae..89780930 100644 --- a/nix/host-modules/hive-matrix.nix +++ b/nix/host-modules/hive-matrix.nix @@ -591,14 +591,6 @@ in # boot requirement. Soft `after` ordering (not `requires`) keeps the # matrix container's lifecycle decoupled from the resolver's. # - # ⚠️ This named `container@hive-gateway.service` until the gateway - # moved onto the host: dnsmasq lived in that container, so ordering - # after the container was how you ordered after the resolver. The - # container is gone and dnsmasq is a plain host `services.dnsmasq`, - # so the ordering now names the resolver directly — which is what it - # always meant. Naming the *container* was already indirection; it - # just happened to be correct while the container existed. - # # `mkMerge`, not a bare assignment: `caTrust.containerOrdering` also # sets `after`/`requires` (so the bound trust bundle exists before # nspawn wires the mount up), and two plain assignments to the same diff --git a/nix/host-modules/hive-tls.nix b/nix/host-modules/hive-tls.nix index 7f1715fe..2199b169 100644 --- a/nix/host-modules/hive-tls.nix +++ b/nix/host-modules/hive-tls.nix @@ -316,15 +316,8 @@ in # The consumer is `hive-gateway-self-signed-cert`, which copies the # leaf into the gateway's state dir at the mode nginx can read, and # which nginx in turn `Requires=`. So this must run first or that - # copy fails under `set -eu` and takes nginx down with it. - # - # ⚠️ This used to name `container@hive-gateway.service` — ordering - # ran through the container, because the copy happened *at container - # start*. Moving the gateway onto the host retired the container - # without retiring the dependency: both units became plain host - # units with nothing sequencing them, and the copy could win the - # race on a fast disk. Order against the unit that reads the file, - # not against the thing that used to host it. + # copy fails under `set -eu` and takes nginx down with it — order + # against the unit that reads the file. before = [ "hive-gateway-self-signed-cert.service" ]; requiredBy = [ "hive-gateway-self-signed-cert.service" ]; # The issuance below needs the swarm root key on disk, and (for the @@ -482,16 +475,10 @@ in # the source therefore changes nothing on its own — the copy has to be # remade and nginx reloaded, which is what the two calls below do. # - # ⚠️ Both calls used to be `systemctl -M hive-gateway … || true`, from - # when nginx lived in a container: `-M` entered the machine, and the - # `|| true` covered a *stopped* container, which was a normal state - # ("its next boot imports the rotated leaf anyway"). The container is - # gone, so `-M hive-gateway` names a machine nothing creates — both - # calls failed, both failures were swallowed, and the unit logged - # "propagating" and exited 0 while nginx kept serving the stale copy - # until it expired. A host unit failing is NOT a normal state: no - # `-M`, and no `|| true` either, so a broken propagation fails the - # timer loudly instead of reporting success. + # ⚠️ Neither call is `|| true`: a swallowed propagation failure means + # the leaf rotates on disk while nginx keeps serving the old copy + # until it expires, with this unit reporting success the whole time. + # A failure here must fail the timer. systemd.services.hive-tls-resign = { description = "Re-sign the gateway TLS leaf and reload nginx"; # hive-tls-ca must have run first so the CA key exists before we try