diff --git a/hosts.toml b/hosts.toml index f507453..d575643 100644 --- a/hosts.toml +++ b/hosts.toml @@ -14,6 +14,10 @@ system = "x86_64-linux" type = "nixos" system = "x86_64-linux" +[sire] +type = "nixos" +system = "x86_64-linux" + [zackbiene] type = "nixos" system = "aarch64-linux" diff --git a/hosts/kroma/fs.nix b/hosts/kroma/fs.nix index ad8bd16..6fd90f3 100644 --- a/hosts/kroma/fs.nix +++ b/hosts/kroma/fs.nix @@ -31,7 +31,7 @@ #}; }; zpool = with lib.disko.zfs; { - rpool = defaultZpoolOptions // {datasets = defaultZfsDatasets;}; + rpool = mkZpool {datasets = impermanenceZfsDatasets;}; }; }; diff --git a/hosts/nom/fs.nix b/hosts/nom/fs.nix index 907f291..bdd86f4 100644 --- a/hosts/nom/fs.nix +++ b/hosts/nom/fs.nix @@ -30,7 +30,7 @@ }; }; zpool = with lib.disko.zfs; { - rpool = defaultZpoolOptions // {datasets = defaultZfsDatasets;}; + rpool = mkZpool {datasets = impermanenceZfsDatasets;}; }; }; diff --git a/hosts/sentinel/fs.nix b/hosts/sentinel/fs.nix index af216db..d8fc102 100644 --- a/hosts/sentinel/fs.nix +++ b/hosts/sentinel/fs.nix @@ -20,7 +20,7 @@ }; }; zpool = with lib.disko.zfs; { - rpool = defaultZpoolOptions // {datasets = defaultZfsDatasets;}; + rpool = mkZpool {datasets = impermanenceZfsDatasets;}; }; }; diff --git a/hosts/sire/default.nix b/hosts/sire/default.nix new file mode 100644 index 0000000..1119781 --- /dev/null +++ b/hosts/sire/default.nix @@ -0,0 +1,100 @@ +{ + config, + inputs, + lib, + nodes, + minimal, + ... +}: { + imports = [ + inputs.nixos-hardware.nixosModules.common-cpu-intel + inputs.nixos-hardware.nixosModules.common-pc-ssd + ../../modules/optional/hardware/intel.nix + ../../modules/optional/hardware/physical.nix + + ../../modules + ../../modules/optional/initrd-ssh.nix + ../../modules/optional/zfs.nix + + ./fs.nix + ./net.nix + ]; + + boot.mode = "efi"; + boot.initrd.availableKernelModules = ["xhci_pci" "ahci" "nvme" "usbhid" "usb_storage" "sd_mod" "sdhci_pci" "r8169"]; + + meta.promtail = { + enable = true; + proxy = "sentinel"; + }; + + # Connect safely via wireguard to skip authentication + networking.hosts.${nodes.sentinel.config.meta.wireguard.proxy-sentinel.ipv4} = [nodes.sentinel.config.networking.providedDomains.influxdb]; + meta.telegraf = { + enable = true; + influxdb2 = { + domain = nodes.sentinel.config.networking.providedDomains.influxdb; + organization = "machines"; + bucket = "telegraf"; + node = "ward-influxdb"; + }; + }; + + # TODO track my github stats + # services.telegraf.extraConfig.inputs.github = {}; + + guests = let + mkGuest = guestName: { + autostart = true; + zfs."/state" = { + pool = "rpool"; + dataset = "local/guests/${guestName}"; + }; + zfs."/persist" = { + pool = "rpool"; + dataset = "safe/guests/${guestName}"; + }; + modules = [ + ../../modules + ./guests/common.nix + ./guests/${guestName}.nix + {node.secretsDir = ./secrets/${guestName};} + ]; + }; + + mkMicrovm = guestName: { + ${guestName} = + mkGuest guestName + // { + backend = "microvm"; + microvm = { + system = "x86_64-linux"; + macvtap = "lan"; + baseMac = config.repo.secrets.local.networking.interfaces.lan.mac; + }; + }; + }; + + # deadnix: skip + mkContainer = guestName: { + ${guestName} = + mkGuest guestName + // { + backend = "container"; + container.macvlan = "lan"; + }; + }; + in + lib.mkIf (!minimal) ( + {} + // mkMicrovm "samba" + // mkMicrovm "grafana" + // mkMicrovm "influxdb" + // mkMicrovm "loki" + // mkMicrovm "paperless" + #// mkMicrovm "minecraft" + #// mkMicrovm "immich" + #// mkMicrovm "firefly" + #// mkMicrovm "fasten-health" + ); +} diff --git a/hosts/sire/fs.nix b/hosts/sire/fs.nix new file mode 100644 index 0000000..3e4f91d --- /dev/null +++ b/hosts/sire/fs.nix @@ -0,0 +1,118 @@ +{ + config, + lib, + ... +}: { + disko.devices = { + disk = + { + m2-ssd-1 = { + type = "disk"; + device = "/dev/disk/by-id/${config.repo.secrets.local.disk.m2-ssd-1}"; + content = with lib.disko.gpt; { + type = "table"; + format = "gpt"; + partitions = [ + (partEfi "efi" "0%" "1GiB") + (partLuksZfs "rpool" "1GiB" "100%") + ]; + }; + }; + m2-ssd-2 = { + type = "disk"; + device = "/dev/disk/by-id/${config.repo.secrets.local.disk.m2-ssd-2}"; + content = lib.disko.content.luksZfs "rpool"; + }; + } + // lib.genAttrs config.repo.secrets.local.disk.hdds-tank (disk: { + type = "disk"; + device = "/dev/disk/by-id/${disk}"; + content = lib.disko.content.luksZfs "tank"; + }); + zpool = with lib.disko.zfs; { + rpool = mkZpool { + mode = "mirror"; + datasets = + impermanenceZfsDatasets + // { + "safe/guests" = unmountable; + }; + }; + tank = mkZpool { + mode = "raidz1"; + datasets = { + "safe/guests" = unmountable; + }; + }; + }; + }; + + services.zrepl = { + enable = true; + settings = { + global = { + logging = [ + { + type = "syslog"; + level = "info"; + format = "human"; + } + ]; + # TODO zrepl monitor + #monitoring = [ + # { + # type = "prometheus"; + # listen = ":9811"; + # listen_freebind = true; + # } + #]; + }; + + jobs = [ + { + name = "local-snapshots"; + type = "snap"; + filesystems = { + "rpool/local/state<" = true; + "rpool/safe<" = true; + "tank/safe<" = true; + }; + snapshotting = { + type = "periodic"; + prefix = "zrepl-"; + timestamp_format = "iso-8601"; + interval = "15m"; + }; + pruning.keep = [ + # Keep all manual snapshots + { + type = "regex"; + regex = "^zrepl-.*$"; + negate = true; + } + # Keep last n snapshots + { + type = "last_n"; + regex = "^zrepl-.*$"; + count = 10; + } + # Prune periodically + { + type = "grid"; + regex = "^zrepl-.*$"; + grid = lib.concatStringsSep " | " [ + "72x1h" + "90x1d" + "60x1w" + "24x30d" + ]; + } + ]; + } + ]; + }; + }; + + boot.initrd.luks.devices.enc-rpool.allowDiscards = true; + boot.initrd.luks.devices.enc-tank.allowDiscards = true; +} diff --git a/hosts/sire/guests/common.nix b/hosts/sire/guests/common.nix new file mode 100644 index 0000000..8052450 --- /dev/null +++ b/hosts/sire/guests/common.nix @@ -0,0 +1,27 @@ +{ + config, + lib, + nodes, + ... +}: let + sentinelCfg = nodes.sentinel.config; +in { + meta.wireguard-proxy.sentinel = {}; + meta.promtail = { + enable = true; + proxy = "sentinel"; + }; + + # Connect safely via wireguard to skip http authentication + networking.hosts.${sentinelCfg.meta.wireguard.proxy-sentinel.ipv4} = [sentinelCfg.networking.providedDomains.influxdb]; + meta.telegraf = lib.mkIf (!config.boot.isContainer) { + enable = true; + scrapeSensors = false; + influxdb2 = { + domain = sentinelCfg.networking.providedDomains.influxdb; + organization = "machines"; + bucket = "telegraf"; + node = "ward-influxdb"; + }; + }; +} diff --git a/hosts/ward/guests/grafana.nix b/hosts/sire/guests/grafana.nix similarity index 100% rename from hosts/ward/guests/grafana.nix rename to hosts/sire/guests/grafana.nix diff --git a/hosts/ward/guests/immich.nix b/hosts/sire/guests/immich.nix similarity index 100% rename from hosts/ward/guests/immich.nix rename to hosts/sire/guests/immich.nix diff --git a/hosts/ward/guests/influxdb.nix b/hosts/sire/guests/influxdb.nix similarity index 100% rename from hosts/ward/guests/influxdb.nix rename to hosts/sire/guests/influxdb.nix diff --git a/hosts/ward/guests/loki.nix b/hosts/sire/guests/loki.nix similarity index 100% rename from hosts/ward/guests/loki.nix rename to hosts/sire/guests/loki.nix diff --git a/hosts/ward/guests/paperless.nix b/hosts/sire/guests/paperless.nix similarity index 100% rename from hosts/ward/guests/paperless.nix rename to hosts/sire/guests/paperless.nix diff --git a/hosts/ward/guests/samba.nix b/hosts/sire/guests/samba.nix similarity index 100% rename from hosts/ward/guests/samba.nix rename to hosts/sire/guests/samba.nix diff --git a/hosts/sire/net.nix b/hosts/sire/net.nix new file mode 100644 index 0000000..2bca6ae --- /dev/null +++ b/hosts/sire/net.nix @@ -0,0 +1,66 @@ +{config, ...}: { + networking.hostId = config.repo.secrets.local.networking.hostId; + + boot.initrd.systemd.network = { + enable = true; + networks."10-lan" = { + address = ["192.168.1.2"]; + matchConfig.MACAddress = config.repo.secrets.local.networking.interfaces.lan.mac; + networkConfig = { + IPv6PrivacyExtensions = "yes"; + MulticastDNS = true; + }; + linkConfig.RequiredForOnline = "routable"; + }; + }; + + # Create a MACVTAP for ourselves too, so that we can communicate with + # our guests on the same interface. + systemd.network.netdevs."10-lan-self" = { + netdevConfig = { + Name = "lan-self"; + Kind = "macvlan"; + }; + extraConfig = '' + [MACVLAN] + Mode=bridge + ''; + }; + + systemd.network.networks = { + "10-lan" = { + matchConfig.MACAddress = config.repo.secrets.local.networking.interfaces.lan.mac; + # This interface should only be used from attached macvtaps. + # So don't acquire a link local address and only wait for + # this interface to gain a carrier. + networkConfig.LinkLocalAddressing = "no"; + linkConfig.RequiredForOnline = "carrier"; + extraConfig = '' + [Network] + MACVLAN=lan-self + ''; + }; + "20-lan-self" = { + address = ["192.168.1.2"]; + matchConfig.Name = "lan-self"; + networkConfig = { + IPv6PrivacyExtensions = "yes"; + MulticastDNS = true; + }; + linkConfig.RequiredForOnline = "routable"; + }; + # Remaining macvtap interfaces should not be touched. + "90-macvtap-ignore" = { + matchConfig.Kind = "macvtap"; + linkConfig.ActivationPolicy = "manual"; + linkConfig.Unmanaged = "yes"; + }; + }; + + networking.nftables.firewall = { + zones.untrusted.interfaces = ["lan-self"]; + }; + + # Allow accessing influx + meta.wireguard.proxy-sentinel.client.via = "sentinel"; +} diff --git a/hosts/ward/secrets/grafana/grafana-secret-key.age b/hosts/sire/secrets/grafana/grafana-secret-key.age similarity index 100% rename from hosts/ward/secrets/grafana/grafana-secret-key.age rename to hosts/sire/secrets/grafana/grafana-secret-key.age diff --git a/hosts/ward/secrets/grafana/host.pub b/hosts/sire/secrets/grafana/host.pub similarity index 100% rename from hosts/ward/secrets/grafana/host.pub rename to hosts/sire/secrets/grafana/host.pub diff --git a/hosts/sire/secrets/host.pub b/hosts/sire/secrets/host.pub new file mode 100644 index 0000000..93bddad --- /dev/null +++ b/hosts/sire/secrets/host.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFMbumSAJX2MOuQO+5tFoL52Fe+TRD2dZwzNCGilACQ/ diff --git a/hosts/ward/secrets/influxdb/host.pub b/hosts/sire/secrets/influxdb/host.pub similarity index 100% rename from hosts/ward/secrets/influxdb/host.pub rename to hosts/sire/secrets/influxdb/host.pub diff --git a/hosts/sire/secrets/local.nix.age b/hosts/sire/secrets/local.nix.age new file mode 100644 index 0000000..187b485 Binary files /dev/null and b/hosts/sire/secrets/local.nix.age differ diff --git a/hosts/ward/secrets/loki/host.pub b/hosts/sire/secrets/loki/host.pub similarity index 100% rename from hosts/ward/secrets/loki/host.pub rename to hosts/sire/secrets/loki/host.pub diff --git a/hosts/ward/secrets/paperless/host.pub b/hosts/sire/secrets/paperless/host.pub similarity index 100% rename from hosts/ward/secrets/paperless/host.pub rename to hosts/sire/secrets/paperless/host.pub diff --git a/hosts/ward/secrets/paperless/paperless-admin-password.age b/hosts/sire/secrets/paperless/paperless-admin-password.age similarity index 100% rename from hosts/ward/secrets/paperless/paperless-admin-password.age rename to hosts/sire/secrets/paperless/paperless-admin-password.age diff --git a/hosts/ward/secrets/samba/host.pub b/hosts/sire/secrets/samba/host.pub similarity index 100% rename from hosts/ward/secrets/samba/host.pub rename to hosts/sire/secrets/samba/host.pub diff --git a/hosts/sire/secrets/samba/local.nix.age b/hosts/sire/secrets/samba/local.nix.age new file mode 100644 index 0000000..949b563 --- /dev/null +++ b/hosts/sire/secrets/samba/local.nix.age @@ -0,0 +1,12 @@ +age-encryption.org/v1 +-> X25519 fKbik0Nwn3w0RFtyYjRx3NIRR6p1ePjwN1rQeQUKnC0 +FESp5Xwwuu3hifwpoalYD75/g994HsDJb6a7lasAH98 +-> piv-p256 xqSe8Q A/f8+j/94A2oU2/SynYRewGBZbPWy1rGU5pnUPksXkwH +n+KeTBbXvjCu9GZypD8Vmz2uuN1XaZpDfX40TNk74js +-> *:l-grease D8U!RlB wkBn7Zl4 +PLWQ+OcE+p/gZ9AaOl5RmO8C5IO5rQD3GIazmdWs/ImIbPFgSY7NM+Tb4j/qrQez + +--- 2ucK0s28/BTrnfxnm0vOvqsmOXLXBEnsxHMRHYUyLHo +boѯVo}]3Kпpp\Yi}:FH^U>ReM`0+կ놪150:FY2M^[uZMy;k]z8a~Mԟ1c/U3)rǖU>x?6x6`!R_ψ挦᷎&(.{x? rhB}̨N#g[2aRlRTϣ9W۠] I26l? +~XߵOφ#!.*Ĥmjh*C}{! +&Nm#vEFb˖3Cd\}ajR[[+p2%ȭ/|5(-ad_@g|.o+[V`tP \ No newline at end of file diff --git a/hosts/ward/secrets/samba/samba-passdb.tdb.age b/hosts/sire/secrets/samba/samba-passdb.tdb.age similarity index 100% rename from hosts/ward/secrets/samba/samba-passdb.tdb.age rename to hosts/sire/secrets/samba/samba-passdb.tdb.age diff --git a/hosts/ward/default.nix b/hosts/ward/default.nix index f4fb8f8..9424fb7 100644 --- a/hosts/ward/default.nix +++ b/hosts/ward/default.nix @@ -22,7 +22,7 @@ ]; boot.mode = "efi"; - boot.initrd.availableKernelModules = ["xhci_pci" "ahci" "nvme" "usbhid" "usb_storage" "sd_mod" "sdhci_pci" "r8169"]; + boot.initrd.availableKernelModules = ["xhci_pci" "ahci" "nvme" "usbhid" "usb_storage" "e1000e" "alx"]; meta.promtail = { enable = true; @@ -76,6 +76,7 @@ }; }; + # deadnix: skip mkContainer = guestName: { ${guestName} = mkGuest guestName @@ -88,29 +89,9 @@ lib.mkIf (!minimal) ( {} // mkMicrovm "adguardhome" - // mkMicrovm "samba" - // mkContainer "forgejo" - // mkContainer "grafana" - // mkContainer "influxdb" - // mkContainer "kanidm" - // mkContainer "loki" - // mkContainer "paperless" - // mkContainer "radicale" - // mkContainer "vaultwarden" + // mkMicrovm "forgejo" + // mkMicrovm "kanidm" + // mkMicrovm "radicale" + // mkMicrovm "vaultwarden" ); - - #ddclient = defineVm; - #samba+wsdd = defineVm; - #fasten-health = defineVm; - #immich = defineVm; - #paperless = defineVm; - #radicale = defineVm; - #minecraft = defineVm; - #firefly - - #maddy = defineVm; - #anonaddy = defineVm; - - #automatic1111 = defineVm; - #invokeai = defineVm; } diff --git a/hosts/ward/fs.nix b/hosts/ward/fs.nix index 4efef47..9181022 100644 --- a/hosts/ward/fs.nix +++ b/hosts/ward/fs.nix @@ -20,15 +20,13 @@ }; }; zpool = with lib.disko.zfs; { - rpool = - defaultZpoolOptions - // { - datasets = - defaultZfsDatasets - // { - "safe/guests" = unmountable; - }; - }; + rpool = mkZpool { + datasets = + impermanenceZfsDatasets + // { + "safe/guests" = unmountable; + }; + }; }; }; diff --git a/hosts/ward/kea.nix b/hosts/ward/kea.nix index bca90db..c651058 100644 --- a/hosts/ward/kea.nix +++ b/hosts/ward/kea.nix @@ -4,7 +4,7 @@ ... }: let inherit (lib) net; - lanCidrv4 = "192.168.100.0/24"; + lanCidrv4 = "192.168.1.0/24"; dnsIp = net.cidr.host 2 lanCidrv4; in { # TODO make meta.kea module? diff --git a/hosts/ward/net.nix b/hosts/ward/net.nix index 58e249f..f402837 100644 --- a/hosts/ward/net.nix +++ b/hosts/ward/net.nix @@ -3,7 +3,7 @@ lib, ... }: let - lanCidrv4 = "192.168.100.0/24"; + lanCidrv4 = "192.168.1.0/24"; lanCidrv6 = "fd10::/64"; in { networking.hostId = config.repo.secrets.local.networking.hostId; @@ -44,13 +44,8 @@ in { #dhcpV4Config.UseDNS = false; #dhcpV6Config.UseDNS = false; #ipv6AcceptRAConfig.UseDNS = false; - address = [ - "192.168.178.7/24" - #"fdee::1/64" - ]; - gateway = [ - "192.168.178.1" - ]; + address = ["192.168.178.2/24"]; + gateway = ["192.168.178.1"]; matchConfig.MACAddress = config.repo.secrets.local.networking.interfaces.wan.mac; networkConfig.IPv6PrivacyExtensions = "yes"; linkConfig.RequiredForOnline = "routable"; diff --git a/hosts/ward/secrets/samba/local.nix.age b/hosts/ward/secrets/samba/local.nix.age deleted file mode 100644 index e26661c..0000000 --- a/hosts/ward/secrets/samba/local.nix.age +++ /dev/null @@ -1,10 +0,0 @@ -age-encryption.org/v1 --> X25519 rGyfugBW1UJ6ufBn8FUWby1AG3ZnBDnNXMBGEXOi/GM -I87QSk3ZBL4FZjdwFd7RS2aRNizPRn/gAdQEUDrnTak --> piv-p256 xqSe8Q ArQj/8FR6hO8vrqY+1e/YN+h46hSCMg0c3tqZ6U3ApMS -+XzFGrEz4z2tU6N7b2taf6j8V4WJi4NfQq4IJHV53l0 --> #=2[OV-grease cKs OHnI -iLqxxLbFIrTYFSDGKsOtZ8j7nw ---- Uu8dPdMbw1Zvs8ZuzNbm/LBoeexh3sEiXht6IrkYf8A -!B*ZZ20&b~d-;,J2at>P}gՅzsM݄6U YF֔o@rSVŐKA7$XD 6Gmi!IDCF'ůۯC[w$iG.U:P8ӾhiɿՋ{v8Zp9uPVje׀J`C:K0W0viG!2T2CGpzV nN&28)%FogVeeUiz -"Ԥ!)%Hcsw'(ͦ"tlE U[]I`.>KfW&Qh{+7V \ No newline at end of file diff --git a/hosts/ward/secrets/samba/samba-password-hashes.age b/hosts/ward/secrets/samba/samba-password-hashes.age deleted file mode 100644 index 0d22581..0000000 Binary files a/hosts/ward/secrets/samba/samba-password-hashes.age and /dev/null differ diff --git a/hosts/zackbiene/fs.nix b/hosts/zackbiene/fs.nix index 88fb61e..306920e 100644 --- a/hosts/zackbiene/fs.nix +++ b/hosts/zackbiene/fs.nix @@ -20,7 +20,7 @@ }; }; zpool = with lib.disko.zfs; { - rpool = defaultZpoolOptions // {datasets = defaultZfsDatasets;}; + rpool = mkZpool {datasets = impermanenceZfsDatasets;}; }; }; } diff --git a/lib/disko.nix b/lib/disko.nix index 1d9dd0b..4d7cb53 100644 --- a/lib/disko.nix +++ b/lib/disko.nix @@ -1,8 +1,19 @@ -_inputs: _final: prev: { +_inputs: final: prev: { lib = prev.lib // { disko = { + content = { + luksZfs = name: { + type = "luks"; + name = "enc-${name}"; + extraOpenArgs = ["--allow-discards"]; + content = { + type = "zfs"; + pool = name; + }; + }; + }; gpt = { partGrub = name: start: end: { inherit name start end; @@ -30,19 +41,11 @@ _inputs: _final: prev: { partLuksZfs = name: start: end: { inherit start end; name = "enc-${name}"; - content = { - type = "luks"; - name = "enc-${name}"; - extraOpenArgs = ["--allow-discards"]; - content = { - type = "zfs"; - pool = name; - }; - }; + content = final.lib.disko.content.luksZfs name; }; }; zfs = rec { - defaultZpoolOptions = { + mkZpool = prev.lib.recursiveUpdate { type = "zpool"; rootFsOptions = { compression = "zstd"; @@ -57,7 +60,7 @@ _inputs: _final: prev: { options.ashift = "12"; }; - defaultZfsDatasets = { + impermanenceZfsDatasets = { "local" = unmountable; "local/root" = filesystem "/"