From be2326ded041ccf07b15dfdb7e96c6662599c413 Mon Sep 17 00:00:00 2001 From: Henri Dohmen Date: Sat, 4 Apr 2026 14:47:10 +0200 Subject: [PATCH] simplify var --- mod/common/users.nix | 2 +- secrets.nix | 17 ++++--- var/default.nix | 109 ++++++++++++++++++++++++++++++++++--------- var/hosts.nix | 47 +++++++++++++++++++ var/lan-dns.nix | 17 ------- var/ssh-keys.nix | 30 ------------ var/syncthing.nix | 27 ----------- var/wg.nix | 48 ------------------- 8 files changed, 142 insertions(+), 155 deletions(-) create mode 100644 var/hosts.nix delete mode 100644 var/lan-dns.nix delete mode 100644 var/ssh-keys.nix delete mode 100644 var/syncthing.nix delete mode 100644 var/wg.nix diff --git a/mod/common/users.nix b/mod/common/users.nix index 98696c2..2b17175 100644 --- a/mod/common/users.nix +++ b/mod/common/users.nix @@ -23,7 +23,7 @@ with lib; extraGroups = [ "wheel" ]; shell = pkgs.fish; packages = [ ]; - openssh.authorizedKeys.keys = var.ssh-keys.trusted-hd; + openssh.authorizedKeys.keys = var.ssh-keys.desktops.hd; hashedPasswordFile = config.age.secrets.hd-password.path; }; users.root = { diff --git a/secrets.nix b/secrets.nix index 49bc9cf..c25ca67 100644 --- a/secrets.nix +++ b/secrets.nix @@ -1,9 +1,10 @@ let pkgs = import { }; inherit (pkgs) lib; - ssh-keys = (import ./var { inherit lib; }).ssh-keys; + var = import ./var { inherit lib; }; + ssh-keys = var.ssh-keys; keys = ssh-keys.root; - trusted-keys = ssh-keys.trusted-root; + trusted-keys = ssh-keys.desktops.root; secrets = [ "hd-password" "roam/firefox-sync-secret" @@ -17,16 +18,14 @@ let # Can only be decrypted by clients "syncthing-password" ]; - mkSecrets = - keys: secrets: lib.mergeAttrsList (map (x: { "secrets/${x}.age".publicKeys = keys; }) secrets); - syncthingManagedClients = (lib.importJSON ./var/syncthing-managed-clients.json).managed_clients; + mkSecrets = k: s: lib.mergeAttrsList (map (x: { "secrets/${x}.age".publicKeys = k; }) s); mkSyncthingSecret = client: { "secrets/syncthing/${client}.age".publicKeys = [ ssh-keys.by-host.root.${client} ]; }; - syncthingSecrets = lib.mergeAttrsList (map mkSyncthingSecret syncthingManagedClients); + syncthingSecrets = lib.mergeAttrsList (map mkSyncthingSecret (lib.attrNames var.syncthing.managed)); in -lib.mergeAttrsList ([ +lib.mergeAttrsList [ (mkSecrets keys secrets) (mkSecrets trusted-keys trusted-secrets) - (syncthingSecrets) -]) + syncthingSecrets +] diff --git a/var/default.nix b/var/default.nix index 34bd26b..b3f1748 100644 --- a/var/default.nix +++ b/var/default.nix @@ -1,30 +1,93 @@ { - lib ? null, + lib ? (import { }).lib, }: let - lib' = if builtins.isNull lib then (import { }).lib else lib; - inputs' = { - lib = lib'; - var = outputs; - }; - load-var = x: import x inputs'; + hosts = import ./hosts.nix; - # watch out for cycles - outputs = rec { - # We list the hosts here manually instead of getting them from the flake. - # This way, var can be used standalone - nixos-desktops = [ - "c2" - "fw" - "solo" - ]; - nixos-servers = [ "roam" ]; - nixos-hosts = nixos-desktops ++ nixos-servers; + # All NixOS hosts managed by this config + nixos-managed = hosts.servers // hosts.desktops; - "lan-dns" = load-var ./lan-dns.nix; - "ssh-keys" = load-var ./ssh-keys.nix; - "wg" = load-var ./wg.nix; - "syncthing" = load-var ./syncthing.nix; + # Syncthing device IDs. Generated by bin/gen-syncthing-cert, stored in JSON + syncthing-hashes = (lib.importJSON ./syncthing-managed-clients.json).hashes; + + # Non-NixOS syncthing peers + syncthing-external = { + "supernote".id = "3LHXAND-FXDIDWR-7BYAIX4-3GW2BWY-IHTX7HH-LTEDI5T-W7ETGVC-BUP2NAF"; + "p9".id = "5QR3JDC-JAI6JGR-ZTT7R42-LLPQIN6-YQ6X47E-PWXGMGU-72RZIRA-PJR7VQZ"; }; + + # Build wg-quick-compatible peer entries from host data + mkWgEntry = + _name: h: + { + inherit (h.wg) publicKey persistentKeepalive; + ips = [ "${h.wg.ip}/32" ]; + allowedIPs = if h.wg ? allowedIPs then h.wg.allowedIPs else [ "${h.wg.ip}/32" ]; + } + // lib.optionalAttrs (h.wg ? endpoint) { inherit (h.wg) endpoint; }; + + wireguard-network = lib.mapAttrs mkWgEntry nixos-managed; + wg-ips = lib.mapAttrs (_: h: h.wg.ip) nixos-managed; + + lan-all-hosts = + lib.mapAttrs' (name: ip: { + name = "${name}.lan"; + value = ip; + }) wg-ips + // { + "git.lan" = wg-ips.roam; + "syncthing.roam.lan" = wg-ips.roam; + "qbt.lan" = wg-ips.roam; + }; + + syncthing-managed = lib.mapAttrs (_: id: { inherit id; }) syncthing-hashes; + + wg-ip-list = lib.attrValues wg-ips; + in -outputs +assert lib.assertMsg (lib.all (h: syncthing-hashes ? ${h}) ( + lib.attrNames nixos-managed +)) "Not all NixOS hosts have a syncthing hash. Run bin/gen-syncthing-cert."; +{ + desktops = lib.attrNames hosts.desktops; + servers = lib.attrNames hosts.servers; + hosts = lib.attrNames nixos-managed; + + ssh-keys = rec { + by-host = { + hd = lib.mapAttrs (_: h: h.ssh.hd) nixos-managed; + root = lib.mapAttrs (_: h: h.ssh.root) nixos-managed; + }; + hd = lib.attrValues by-host.hd; + root = lib.attrValues by-host.root; + desktops = { + hd = lib.mapAttrsToList (_: h: h.ssh.hd) hosts.desktops; + root = lib.mapAttrsToList (_: h: h.ssh.root) hosts.desktops; + }; + }; + + wg = { + keyFile = "/var/secrets/wg.key"; + inherit wireguard-network; + ips = wg-ips; + peers-for = + host: + map (lib.filterAttrs (n: _: n != "ips")) ( + lib.attrValues (lib.filterAttrs (n: _: n != host) wireguard-network) + ); + }; + + syncthing = rec { + managed = syncthing-managed; + devices = syncthing-managed // syncthing-external; + device-names = { + all = lib.attrNames devices; + desktops = lib.attrNames hosts.desktops; + }; + }; + + lan-dns = { + hosts = lan-all-hosts; + hostsFile = lib.concatStringsSep "\n" (lib.mapAttrsToList (n: v: "${v}\t${n}") lan-all-hosts); + }; +} diff --git a/var/hosts.nix b/var/hosts.nix new file mode 100644 index 0000000..28bc0ac --- /dev/null +++ b/var/hosts.nix @@ -0,0 +1,47 @@ +{ + servers = { + roam = { + ssh.hd = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEDlh8hY01wwmNtfa1eK3mVBIcytdh4n/kV05gP9z1Lc"; + ssh.root = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAID++uLcQOx/to3sEo5Nk97CenGf0Y6/dMsBbLouVTgIQ"; + wg = { + publicKey = "yUbdRfRFFVe4FPUaD7pVByLRhpF9Yl1kethxRUHpVgs="; + ip = "10.10.11.1"; + allowedIPs = [ "10.10.11.0/24" ]; # routes the whole onet subnet + endpoint = "185.163.117.158:51820"; + persistentKeepalive = 17; + }; + }; + }; + desktops = { + solo = { + ssh.hd = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEG+dd4m98aKEWfFa/7VZUlJNX0axvIlHVihT8w7RLyY"; + ssh.root = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFsl8pLaGeCL3kacGWf8pzoLQr501ga/2OzvI2wWbTZJ"; + wg = { + publicKey = "SRDguh0aN/RH8q/uB09w/OZTbP9JZZy0ABowbWIfkTk="; + ip = "10.10.11.2"; + persistentKeepalive = 13; + }; + }; + c2 = { + ssh.hd = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIsoj2+esEebRwDV2PuNRt9Vz28oolOy+Hc2THwrWTAB"; + ssh.root = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJAZaswaiA+oQ9NviADYFf7BJQHNlmdxQuocIdoJmv3o"; + wg = { + publicKey = "yJ1vrI9+qzUHuQJxeRDLCDCMRCIhF+0UNPwz3agyxTk="; + ip = "10.10.11.3"; + persistentKeepalive = 19; + }; + }; + fw = { + ssh.hd = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJmxhDwylLlklpgiUWHc0BPSCkNkuAIrXLNOHpAcgXiL"; + ssh.root = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOjfPXDS3UvVGXzJYXU8TyP5q0WDzb0anx4Std40AT+j"; + wg = { + publicKey = "xpiJJMPhZEIEvNDBYRbnOsBeDCdKN1cHdYM95b9+rUY="; + ip = "10.10.11.4"; + persistentKeepalive = 23; + }; + }; + }; + misc = { + test-vm = { }; + }; +} diff --git a/var/lan-dns.nix b/var/lan-dns.nix deleted file mode 100644 index a0adfc2..0000000 --- a/var/lan-dns.nix +++ /dev/null @@ -1,17 +0,0 @@ -# Wireguard peers hardcoded in /etc/hosts until I have a nice dns solution -{ lib, var, ... }: -let - lan-hosts = lib.mapAttrs' (name: value: { - name = "${name}.lan"; - inherit value; - }) var.wg.ips; - custom-hosts = with var.wg.ips; { - "git.lan" = roam; - "syncthing.roam.lan" = roam; - "qbt.lan" = roam; - }; -in -rec { - hosts = lan-hosts // custom-hosts; - hostsFile = lib.concatStringsSep "\n" (lib.mapAttrsToList (n: v: "${v}\t${n}") hosts); -} diff --git a/var/ssh-keys.nix b/var/ssh-keys.nix deleted file mode 100644 index 16726a8..0000000 --- a/var/ssh-keys.nix +++ /dev/null @@ -1,30 +0,0 @@ -{ lib, ... }: -let - mkKeys = k: { by-host = k; } // builtins.mapAttrs (_: lib.attrValues) k; - keys = { - hd = { - "solo" = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEG+dd4m98aKEWfFa/7VZUlJNX0axvIlHVihT8w7RLyY"; - "c2" = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIsoj2+esEebRwDV2PuNRt9Vz28oolOy+Hc2THwrWTAB"; - "roam" = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIEDlh8hY01wwmNtfa1eK3mVBIcytdh4n/kV05gP9z1Lc"; - "fw" = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJmxhDwylLlklpgiUWHc0BPSCkNkuAIrXLNOHpAcgXiL"; - }; - root = { - "solo" = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFsl8pLaGeCL3kacGWf8pzoLQr501ga/2OzvI2wWbTZJ"; - "c2" = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJAZaswaiA+oQ9NviADYFf7BJQHNlmdxQuocIdoJmv3o"; - "roam" = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAID++uLcQOx/to3sEo5Nk97CenGf0Y6/dMsBbLouVTgIQ"; - "fw" = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOjfPXDS3UvVGXzJYXU8TyP5q0WDzb0anx4Std40AT+j"; - }; - }; - keys' = mkKeys keys; - mkTrusted = - user: with keys'.by-host.${user}; [ - solo - c2 - fw - ]; -in -keys' -// { - trusted-hd = mkTrusted "hd"; - trusted-root = mkTrusted "root"; -} diff --git a/var/syncthing.nix b/var/syncthing.nix deleted file mode 100644 index 8ca16ee..0000000 --- a/var/syncthing.nix +++ /dev/null @@ -1,27 +0,0 @@ -{ var, lib, ... }: -let - inherit (lib.importJSON ./syncthing-managed-clients.json) managed_clients hashes; - unmanaged = { - "supernote".id = "3LHXAND-FXDIDWR-7BYAIX4-3GW2BWY-IHTX7HH-LTEDI5T-W7ETGVC-BUP2NAF"; - "p9".id = "5QR3JDC-JAI6JGR-ZTT7R42-LLPQIN6-YQ6X47E-PWXGMGU-72RZIRA-PJR7VQZ"; - }; -in -assert ( - lib.assertMsg (lib.all (c: lib.elem c (builtins.attrNames hashes)) - managed_clients - ) "Not all declaratively configured syncthing clients have keys. Rerun ./bin/gen-syncthing-cert" -); -assert ( - lib.assertMsg ( - [ ] == (lib.intersectLists managed_clients (builtins.attrNames unmanaged)) - ) "Syncthing clients must either be unmanaged or declaratively configured." -); -rec { - managed = builtins.mapAttrs (_: v: { id = v; }) hashes; - devices = unmanaged // managed; - - device-names = rec { - all = lib.attrNames devices; - desktops = (lib.intersectLists var.nixos-desktops all); - }; -} diff --git a/var/wg.nix b/var/wg.nix deleted file mode 100644 index b921d6f..0000000 --- a/var/wg.nix +++ /dev/null @@ -1,48 +0,0 @@ -{ lib, ... }: -rec { - publicKey = { - "roam" = "yUbdRfRFFVe4FPUaD7pVByLRhpF9Yl1kethxRUHpVgs="; - "solo" = "SRDguh0aN/RH8q/uB09w/OZTbP9JZZy0ABowbWIfkTk="; - "c2" = "yJ1vrI9+qzUHuQJxeRDLCDCMRCIhF+0UNPwz3agyxTk="; - "fw" = "xpiJJMPhZEIEvNDBYRbnOsBeDCdKN1cHdYM95b9+rUY="; - }; - wireguard-network = { - "roam" = { - publicKey = publicKey."roam"; - ips = [ "10.10.11.1/32" ]; - allowedIPs = [ "10.10.11.0/24" ]; - endpoint = "185.163.117.158:51820"; - persistentKeepalive = 17; - }; - "solo" = { - publicKey = publicKey."solo"; - ips = [ "10.10.11.2/32" ]; - allowedIPs = [ "10.10.11.2/32" ]; - persistentKeepalive = 13; - }; - "c2" = { - publicKey = publicKey."c2"; - ips = [ "10.10.11.3/32" ]; - allowedIPs = [ "10.10.11.3/32" ]; - persistentKeepalive = 19; - }; - "fw" = { - publicKey = publicKey."fw"; - ips = [ "10.10.11.4/32" ]; - allowedIPs = [ "10.10.11.4/32" ]; - persistentKeepalive = 23; - }; - }; - keyFile = "/var/secrets/wg.key"; - - # Helper method: `peers-for x` filters out `x` from wireguard-network - peers-for = - host: - map (lib.filterAttrs (n: _: n != "ips")) ( - lib.attrValues (lib.filterAttrs (n: _: n != host) wireguard-network) - ); - - ips = - with builtins; - mapAttrs (_: value: head (lib.splitString "/" (head value.ips))) wireguard-network; -}