From 812a072e1c2991dac7b2fc1d55fec9db562d35c9 Mon Sep 17 00:00:00 2001 From: atlas Date: Sat, 6 Jun 2026 12:57:02 +0200 Subject: [PATCH] fix(matrix): point the tuwunel container resolver at the bridge dnsmasq The hive-matrix nixos-container came up with an EMPTY /etc/resolv.conf even with networking.nameservers set, so tuwunel hard-failed at boot (no nameservers found). The nixos-container default useHostResolvConf=true puts in-container resolvconf in host-tracking mode: it ignores networking.nameservers and never receives the host resolv.conf across the shared-netns boundary, so resolvconf regenerates an empty file. When the hive network module is on, turn off host-tracking (mkForce, to beat the module default) so resolvconf honours networking.nameservers, pointing the resolver at the gateway-container dnsmasq at bridgeIp. Network module off -> inherit the host resolv.conf. --- nix/modules/hive-matrix.nix | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/nix/modules/hive-matrix.nix b/nix/modules/hive-matrix.nix index 7f60fc29..aef3ec2c 100644 --- a/nix/modules/hive-matrix.nix +++ b/nix/modules/hive-matrix.nix @@ -342,18 +342,25 @@ in # tuwunel hard-fails to boot if `/etc/resolv.conf` has no # `nameserver` line (`Failed to configure DNS resolver ... no # nameservers found in config` → exit 1). This declarative - # nixos-container generates its own resolv.conf via resolvconf - # and — unlike agent containers, whose resolv.conf is written by - # hive-c0re's lifecycle — it has no nameserver source, so it - # comes up empty (just `options edns0`). When the hive network - # module is on, point it at the dnsmasq resolver the module runs - # at `bridgeIp`; this container always shares the host netns + # nixos-container had it come up EMPTY (just `options edns0`) + # even with `networking.nameservers` set: the nixos-container + # default `useHostResolvConf = true` puts in-container resolvconf + # in host-tracking mode, which ignores `networking.nameservers` + # and never receives the host's resolv.conf across the + # shared-netns boundary — so resolvconf regenerates an empty file + # and tuwunel dies at boot. + # + # When the hive network module is on, turn off host-tracking so + # resolvconf honours `networking.nameservers`, pointing the + # resolver at the dnsmasq the network module runs at `bridgeIp`. + # This container always shares the host netns # (`privateNetwork = false`), so it reaches `bridgeIp` whether or # not `isolateContainers` is set. With the network module off, # inherit the host's resolv.conf (which carries the host # resolver). See `docs/network.md`. networking = lib.mkMerge [ (lib.mkIf networkCfg.enable { + useHostResolvConf = lib.mkForce false; nameservers = [ networkCfg.bridgeIp ]; }) (lib.mkIf (!networkCfg.enable) {