Read mesh host map from clan zerotier vars instead of hardcoding

The control/ns1/ns2 mesh IPs and the /88 subnet were duplicated literals in
mesh-hosts.nix. clan-core's zerotier generator already writes each machine's IP
as a public var (vars/per-machine/<m>/zerotier/zerotier-ip), so read from there
and derive the subnet from zerotier-network-id. Pure refactor: the rendered
values are identical and the system derivation hash is unchanged.
This commit is contained in:
Berwn
2026-06-17 11:53:56 +07:00
parent 8ac96b2d10
commit 848c4ec47d
4 changed files with 29 additions and 13 deletions
+2 -2
View File
@@ -1,7 +1,7 @@
{ config, pkgs, ... }:
{ config, lib, pkgs, ... }:
let
# ZeroTier addresses — zone transfers run over the mesh, not the public net.
mesh = import ../mesh-hosts.nix;
mesh = import ../mesh-hosts.nix { inherit config lib; };
ns1zt = mesh.hosts.ns1;
ns2zt = mesh.hosts.ns2;
in
+25 -9
View File
@@ -1,14 +1,30 @@
# ZeroTier (clan mesh) addresses — the private IPv6 overlay every machine shares.
# DNS zone transfers and metrics scraping ride this mesh, never the public net.
rec {
hosts = {
control = "fd06:1bad:ece2:92ad:ba99:9306:1bad:ece2";
ns1 = "fd06:1bad:ece2:92ad:ba99:939d:766d:8974";
ns2 = "fd06:1bad:ece2:92ad:ba99:9323:61be:a09e";
};
#
# Rather than hardcoding the addresses, we read them from the public clan vars
# that clan-core's zerotier generator already writes per machine
# (vars/per-machine/<m>/zerotier/zerotier-ip/value). This keeps the mesh map in
# lockstep with the actual identities: regenerate or re-key a node and its
# address here follows automatically. Call as: import ../mesh-hosts.nix { inherit config lib; }.
{ config, lib }:
let
dir = config.clan.core.settings.directory;
# RFC 4193 /88 prefix of this ZeroTier network (fd + 8-byte network id + the
# 0x9993 marker). Covers every mesh peer — servers and admin laptops alike —
readVar =
machine: file:
builtins.readFile "${dir}/vars/per-machine/${machine}/zerotier/${file}/value";
hosts = lib.genAttrs [ "control" "ns1" "ns2" ] (m: readVar m "zerotier-ip");
# RFC 4193 prefix of this ZeroTier network: fd + the 8-byte network id + the
# 0x9993 marker. The network id is a public var on the controller (control).
# The /88 (11 bytes) covers fd + network id + 0x99 + 0x93, i.e. every mesh peer,
# and is used to scope mesh-only firewall rules.
subnet = "fd06:1bad:ece2:92ad:ba99:9300::/88";
networkId = readVar "control" "zerotier-network-id";
full = "fd" + networkId + "9993"; # 22 hex chars = 11 bytes
hextet = i: builtins.substring (i * 4) 4 full;
subnet = "${hextet 0}:${hextet 1}:${hextet 2}:${hextet 3}:${hextet 4}:${builtins.substring 20 2 full}00::/88";
in
{
inherit hosts subnet;
}
+1 -1
View File
@@ -9,7 +9,7 @@
...
}:
let
mesh = import ../mesh-hosts.nix;
mesh = import ../mesh-hosts.nix { inherit config lib; };
knotEnabled = config.services.knot.enable;
# node_exporter on every host; knot-exporter only where Knot runs.
ports = [ 9100 ] ++ lib.optional knotEnabled 9433;
+1 -1
View File
@@ -9,7 +9,7 @@
...
}:
let
mesh = import ../mesh-hosts.nix;
mesh = import ../mesh-hosts.nix { inherit config lib; };
vmPort = 8428;
grafanaPort = 3000;
controlV6 = mesh.hosts.control;