diff --git a/hosts/darwin/default.nix b/hosts/darwin/default.nix index 446b163..f100ec3 100644 --- a/hosts/darwin/default.nix +++ b/hosts/darwin/default.nix @@ -3,48 +3,12 @@ pkgs, config, inputs, + lib, ... }: let - mossnetResolver = pkgs.writeShellScript "sync-mossnet-resolver" '' - set -eu - - resolver_dir=/etc/resolver - resolver_file="$resolver_dir/mossnet.lan" - lan_dns=192.168.1.240 - wg_dns=10.0.69.4 - wanted_dns="" - - resolve_with() { - ${pkgs.bind}/bin/dig +time=1 +tries=1 +short @"$1" read.mossnet.lan A >/dev/null 2>&1 - } - - if ${pkgs.wireguard-tools}/bin/wg show wg0 >/dev/null 2>&1 && resolve_with "$wg_dns"; then - wanted_dns="$wg_dns" - elif resolve_with "$lan_dns"; then - wanted_dns="$lan_dns" - fi - - if [ -n "$wanted_dns" ]; then - wanted_config="nameserver $wanted_dns" - current_config="" - - if [ -f "$resolver_file" ]; then - current_config="$(${pkgs.coreutils}/bin/tr -d '\n' < "$resolver_file")" - fi - - ${pkgs.coreutils}/bin/mkdir -p "$resolver_dir" - if [ "$current_config" != "$wanted_config" ]; then - ${pkgs.coreutils}/bin/printf '%s\n' "$wanted_config" > "$resolver_file" - /usr/bin/dscacheutil -flushcache - /usr/bin/killall -HUP mDNSResponder - fi - elif [ -f "$resolver_file" ]; then - ${pkgs.coreutils}/bin/rm -f "$resolver_file" - /usr/bin/dscacheutil -flushcache - /usr/bin/killall -HUP mDNSResponder - fi - ''; + mossnet = import ../profiles/mossnet-hosts/hosts.nix; + mossnetHostsBlock = lib.concatMapStringsSep "\n" (name: "${mossnet.lanIP} ${name}") mossnet.names; in { imports = [ @@ -76,14 +40,43 @@ in age.secrets.openaiToken.file = "${self}/secrets/openaiToken.age"; age.secrets.openaiToken.owner = "anishlakhwara"; + # Maintain a marked block in /etc/hosts pointing mossnet.lan hostnames at the + # LAN IP for the box. Needed because nix-darwin lacks networking.extraHosts / + # networking.hosts, and because the corporate ScoutDNS agent (127.0.0.1:53) does + # not resolve .lan names, breaking browser access despite /etc/resolver entries. + system.activationScripts.extraActivation.text = '' + set -eu + hosts_file=/etc/hosts + begin_marker='# >>> mossnet hosts (managed by nix-darwin) >>>' + end_marker='# <<< mossnet hosts (managed by nix-darwin) <<<' + desired=$(cat <<'EOF' +${mossnetHostsBlock} +EOF +) + + tmp=$(/usr/bin/mktemp) + # Strip any existing block, then append the fresh one. + /usr/bin/sed "/$begin_marker/,/$end_marker/d" "$hosts_file" > "$tmp" + # Trim trailing blank lines from the stripped output so we get clean spacing. + /usr/bin/awk 'BEGIN{blank=0} /^$/{blank++; next} {for(i=0;i "$tmp.compact" + { + cat "$tmp.compact" + printf '\n%s\n%s\n%s\n' "$begin_marker" "$desired" "$end_marker" + } > "$hosts_file.new" + /bin/chmod 644 "$hosts_file.new" + /usr/sbin/chown root:wheel "$hosts_file.new" + /bin/mv "$hosts_file.new" "$hosts_file" + /bin/rm -f "$tmp" "$tmp.compact" + /usr/bin/dscacheutil -flushcache || true + /usr/bin/killall -HUP mDNSResponder 2>/dev/null || true + ''; + networking.wg-quick.interfaces = { wg0 = { address = [ "10.0.69.7/24" ]; listenPort = 60990; # to match firewall allowedUDPPorts (without this wg uses random port numbers) privateKeyFile = config.age.secrets.work-wg.path; # dns = [ "10.0.69.4" ]; - postUp = "${mossnetResolver}"; - postDown = "${mossnetResolver}"; peers = [ # For a client configuration, one peer entry for the server will suffice. { @@ -97,14 +90,6 @@ in }; }; - launchd.daemons.mossnet-resolver = { - serviceConfig = { - ProgramArguments = [ "${mossnetResolver}" ]; - RunAtLoad = true; - StartInterval = 60; - }; - }; - # Auto upgrade nix package and the daemon service. # services.nix-daemon.enable = true; # removed in newer nix-darwin nixpkgs.hostPlatform = "aarch64-darwin"; diff --git a/hosts/profiles/mossnet-hosts/default.nix b/hosts/profiles/mossnet-hosts/default.nix index ebb59bb..e87d77e 100644 --- a/hosts/profiles/mossnet-hosts/default.nix +++ b/hosts/profiles/mossnet-hosts/default.nix @@ -1,28 +1,8 @@ +{ lib, ... }: +let + data = import ./hosts.nix; + lines = lib.concatMapStringsSep "\n" (name: "${data.lanIP} ${name}") data.names; +in { - # TODO use the list from DNS - networking.extraHosts = '' - 192.168.1.240 mossnet.lan - 192.168.1.240 links.mossnet.lan - 192.168.1.240 read.mossnet.lan - 192.168.1.240 headphones.mossnet.lan - 192.168.1.240 transmission.mossnet.lan - 192.168.1.240 music.mossnet.lan - 192.168.1.240 stats.mossnet.lan - 192.168.1.240 file.mossnet.lan - 192.168.1.240 task.mossnet.lan - 192.168.1.240 fin.mossnet.lan - 192.168.1.240 paper.mossnet.lan - 192.168.1.240 books.mossnet.lan - 192.168.1.240 archive.mossnet.lan - 192.168.1.240 music.mossnet.lan - 192.168.1.240 tracks.mossnet.lan - 192.168.1.240 grasp.mossnet.lan - 192.168.1.240 photos.mossnet.lan - 192.168.1.240 pod.mossnet.lan - ''; - # 10.0.69.4 mossnet.lan - # 10.0.69.4 links.mossnet.lan - # 10.0.69.4 read.mossnet.lan - # 10.0.69.4 stats.mossnet.lan + networking.extraHosts = lines + "\n"; } - diff --git a/hosts/profiles/mossnet-hosts/hosts.nix b/hosts/profiles/mossnet-hosts/hosts.nix new file mode 100644 index 0000000..d31964b --- /dev/null +++ b/hosts/profiles/mossnet-hosts/hosts.nix @@ -0,0 +1,29 @@ +# Single source of truth for mossnet.lan host -> IP mappings. +# Consumed by: +# - hosts/profiles/mossnet-hosts/default.nix (NixOS, via networking.extraHosts) +# - hosts/darwin/default.nix (nix-darwin, via /etc/hosts activation script) +{ + lanIP = "192.168.1.240"; + wgIP = "10.0.69.4"; + + # Hostnames that should resolve to the box. + names = [ + "mossnet.lan" + "links.mossnet.lan" + "read.mossnet.lan" + "headphones.mossnet.lan" + "transmission.mossnet.lan" + "music.mossnet.lan" + "stats.mossnet.lan" + "file.mossnet.lan" + "task.mossnet.lan" + "fin.mossnet.lan" + "paper.mossnet.lan" + "books.mossnet.lan" + "archive.mossnet.lan" + "tracks.mossnet.lan" + "grasp.mossnet.lan" + "photos.mossnet.lan" + "pod.mossnet.lan" + ]; +}