simplify var
This commit is contained in:
parent
d54e653a2b
commit
be2326ded0
8 changed files with 142 additions and 155 deletions
|
|
@ -23,7 +23,7 @@ with lib;
|
||||||
extraGroups = [ "wheel" ];
|
extraGroups = [ "wheel" ];
|
||||||
shell = pkgs.fish;
|
shell = pkgs.fish;
|
||||||
packages = [ ];
|
packages = [ ];
|
||||||
openssh.authorizedKeys.keys = var.ssh-keys.trusted-hd;
|
openssh.authorizedKeys.keys = var.ssh-keys.desktops.hd;
|
||||||
hashedPasswordFile = config.age.secrets.hd-password.path;
|
hashedPasswordFile = config.age.secrets.hd-password.path;
|
||||||
};
|
};
|
||||||
users.root = {
|
users.root = {
|
||||||
|
|
|
||||||
17
secrets.nix
17
secrets.nix
|
|
@ -1,9 +1,10 @@
|
||||||
let
|
let
|
||||||
pkgs = import <nixpkgs> { };
|
pkgs = import <nixpkgs> { };
|
||||||
inherit (pkgs) lib;
|
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;
|
keys = ssh-keys.root;
|
||||||
trusted-keys = ssh-keys.trusted-root;
|
trusted-keys = ssh-keys.desktops.root;
|
||||||
secrets = [
|
secrets = [
|
||||||
"hd-password"
|
"hd-password"
|
||||||
"roam/firefox-sync-secret"
|
"roam/firefox-sync-secret"
|
||||||
|
|
@ -17,16 +18,14 @@ let
|
||||||
# Can only be decrypted by clients
|
# Can only be decrypted by clients
|
||||||
"syncthing-password"
|
"syncthing-password"
|
||||||
];
|
];
|
||||||
mkSecrets =
|
mkSecrets = k: s: lib.mergeAttrsList (map (x: { "secrets/${x}.age".publicKeys = k; }) s);
|
||||||
keys: secrets: lib.mergeAttrsList (map (x: { "secrets/${x}.age".publicKeys = keys; }) secrets);
|
|
||||||
syncthingManagedClients = (lib.importJSON ./var/syncthing-managed-clients.json).managed_clients;
|
|
||||||
mkSyncthingSecret = client: {
|
mkSyncthingSecret = client: {
|
||||||
"secrets/syncthing/${client}.age".publicKeys = [ ssh-keys.by-host.root.${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
|
in
|
||||||
lib.mergeAttrsList ([
|
lib.mergeAttrsList [
|
||||||
(mkSecrets keys secrets)
|
(mkSecrets keys secrets)
|
||||||
(mkSecrets trusted-keys trusted-secrets)
|
(mkSecrets trusted-keys trusted-secrets)
|
||||||
(syncthingSecrets)
|
syncthingSecrets
|
||||||
])
|
]
|
||||||
|
|
|
||||||
109
var/default.nix
109
var/default.nix
|
|
@ -1,30 +1,93 @@
|
||||||
{
|
{
|
||||||
lib ? null,
|
lib ? (import <nixpkgs> { }).lib,
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
lib' = if builtins.isNull lib then (import <nixpkgs> { }).lib else lib;
|
hosts = import ./hosts.nix;
|
||||||
inputs' = {
|
|
||||||
lib = lib';
|
|
||||||
var = outputs;
|
|
||||||
};
|
|
||||||
load-var = x: import x inputs';
|
|
||||||
|
|
||||||
# watch out for cycles
|
# All NixOS hosts managed by this config
|
||||||
outputs = rec {
|
nixos-managed = hosts.servers // hosts.desktops;
|
||||||
# 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;
|
|
||||||
|
|
||||||
"lan-dns" = load-var ./lan-dns.nix;
|
# Syncthing device IDs. Generated by bin/gen-syncthing-cert, stored in JSON
|
||||||
"ssh-keys" = load-var ./ssh-keys.nix;
|
syncthing-hashes = (lib.importJSON ./syncthing-managed-clients.json).hashes;
|
||||||
"wg" = load-var ./wg.nix;
|
|
||||||
"syncthing" = load-var ./syncthing.nix;
|
# 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
|
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);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
||||||
47
var/hosts.nix
Normal file
47
var/hosts.nix
Normal file
|
|
@ -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 = { };
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -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);
|
|
||||||
}
|
|
||||||
|
|
@ -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";
|
|
||||||
}
|
|
||||||
|
|
@ -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);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
48
var/wg.nix
48
var/wg.nix
|
|
@ -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;
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue