diff --git a/.sops.yaml b/.sops.yaml index 981f6c0..cb7f12a 100644 --- a/.sops.yaml +++ b/.sops.yaml @@ -4,6 +4,11 @@ keys: - &eidola age1uqxzduupzes3tgfrrlret0n6thyldmlef60nqfzk689lmg6yayvsqpwxj6 - &silver age19yhycdgqczrvttszq97ccljh684x3r7f5dj4p0wdwqsrusqlcayse0vsh3 creation_rules: + - path_regex: secrets/ca\.key$ + key_groups: + - age: + - *min + - *min-two - path_regex: secrets/eidola/[^/]+$ key_groups: - age: diff --git a/.vscode/settings.json b/.vscode/settings.json index 13ffdd2..4cef9da 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,12 +1,10 @@ { - "nix.enableLanguageServer": true, - "nix.serverSettings": { - "nil": { - "formatting": { - "command": [ - "alejandra" - ] - } - } - }, -} \ No newline at end of file + "nix.enableLanguageServer": true, + "nix.serverSettings": { + "nil": { + "formatting": { + "command": ["alejandra"] + } + } + } +} diff --git a/.zed/settings.json b/.zed/settings.json new file mode 100644 index 0000000..cc3bc53 --- /dev/null +++ b/.zed/settings.json @@ -0,0 +1,22 @@ +{ + "languages": { + "Nix": { + "language_servers": ["nil", "!nixd"], + "formatter": { + "external": { + "command": "alejandra", + "arguments": ["--quiet", "--"] + } + } + }, + "JSONC": { + "tab_size": 2 + }, + "YAML": { + "tab_size": 2 + }, + "Shell Script": { + "tab_size": 2 + } + } +} diff --git a/flake.lock b/flake.lock index 7bbdbc0..b6b31b8 100644 --- a/flake.lock +++ b/flake.lock @@ -9,11 +9,11 @@ ] }, "locked": { - "lastModified": 1748064728, - "narHash": "sha256-X2XBfe+BUBWsnaLm0E8vkc6aFD4RMT1CbXII0uWsz6Q=", + "lastModified": 1764916461, + "narHash": "sha256-DPCh+/tXkNF4bIDL117APMjPuNSFdxayXL5fWbqNIPs=", "ref": "refs/heads/main", - "rev": "471649fdec9104cad4a86efa365ab616620bf859", - "revCount": 72, + "rev": "cd1b845695ef39f7c4e3bfeb221dd28d99f74d24", + "revCount": 77, "type": "git", "url": "https://git.min.rip/min/breeze.git" }, @@ -61,11 +61,11 @@ "utils": "utils" }, "locked": { - "lastModified": 1727447169, - "narHash": "sha256-3KyjMPUKHkiWhwR91J1YchF6zb6gvckCAY1jOE+ne0U=", + "lastModified": 1766051518, + "narHash": "sha256-znKOwPXQnt3o7lDb3hdf19oDo0BLP4MfBOYiWkEHoik=", "owner": "serokell", "repo": "deploy-rs", - "rev": "aa07eb05537d4cd025e2310397a6adcedfe72c76", + "rev": "d5eff7f948535b9c723d60cd8239f8f11ddc90fa", "type": "github" }, "original": { @@ -81,11 +81,11 @@ ] }, "locked": { - "lastModified": 1747742835, - "narHash": "sha256-kYL4GCwwznsypvsnA20oyvW8zB/Dvn6K5G/tgMjVMT4=", + "lastModified": 1768923567, + "narHash": "sha256-GVJ0jKsyXLuBzRMXCDY6D5J8wVdwP1DuQmmvYL/Vw/Q=", "owner": "nix-community", "repo": "disko", - "rev": "df522e787fdffc4f32ed3e1fca9ed0968a384d62", + "rev": "00395d188e3594a1507f214a2f15d4ce5c07cb28", "type": "github" }, "original": { @@ -97,11 +97,11 @@ "flake-compat": { "flake": false, "locked": { - "lastModified": 1696426674, - "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", + "lastModified": 1733328505, + "narHash": "sha256-NeCCThCEP3eCl2l/+27kNNK7QrwZB1IJCrXfrbv5oqU=", "owner": "edolstra", "repo": "flake-compat", - "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", + "rev": "ff81ac966bb2cae68946d5ed5fc4994f96d0ffec", "type": "github" }, "original": { @@ -115,11 +115,11 @@ "nixpkgs-lib": "nixpkgs-lib" }, "locked": { - "lastModified": 1743550720, - "narHash": "sha256-hIshGgKZCgWh6AYJpJmRgFdR3WUbkY04o82X05xqQiY=", + "lastModified": 1768135262, + "narHash": "sha256-PVvu7OqHBGWN16zSi6tEmPwwHQ4rLPU9Plvs8/1TUBY=", "owner": "hercules-ci", "repo": "flake-parts", - "rev": "c621e8422220273271f52058f618c94e405bb0f5", + "rev": "80daad04eddbbf5a4d883996a73f3f542fa437ac", "type": "github" }, "original": { @@ -176,32 +176,33 @@ "original": { "owner": "nix-community", "repo": "impermanence", + "rev": "4b3e914cdf97a5b536a889e939fb2fd2b043a170", "type": "github" } }, "nixpkgs": { "locked": { - "lastModified": 1748162331, - "narHash": "sha256-rqc2RKYTxP3tbjA+PB3VMRQNnjesrT0pEofXQTrMsS8=", + "lastModified": 1769089682, + "narHash": "sha256-9yA/LIuAVQq0lXelrZPjLuLVuZdm03p8tfmHhnDIkms=", "owner": "nixos", "repo": "nixpkgs", - "rev": "7c43f080a7f28b2774f3b3f43234ca11661bf334", + "rev": "078d69f03934859a181e81ba987c2bb033eebfc5", "type": "github" }, "original": { "owner": "nixos", - "ref": "nixos-25.05", + "ref": "nixos-25.11", "repo": "nixpkgs", "type": "github" } }, "nixpkgs-lib": { "locked": { - "lastModified": 1743296961, - "narHash": "sha256-b1EdN3cULCqtorQ4QeWgLMrd5ZGOjLSLemfa00heasc=", + "lastModified": 1765674936, + "narHash": "sha256-k00uTP4JNfmejrCLJOwdObYC9jHRrr/5M/a/8L2EIdo=", "owner": "nix-community", "repo": "nixpkgs.lib", - "rev": "e4822aea2a6d1cdd36653c134cacfd64c97ff4fa", + "rev": "2075416fcb47225d9b68ac469a5c4801a9c4dd85", "type": "github" }, "original": { @@ -251,11 +252,11 @@ ] }, "locked": { - "lastModified": 1747603214, - "narHash": "sha256-lAblXm0VwifYCJ/ILPXJwlz0qNY07DDYdLD+9H+Wc8o=", + "lastModified": 1768863606, + "narHash": "sha256-1IHAeS8WtBiEo5XiyJBHOXMzECD6aaIOJmpQKzRRl64=", "owner": "Mic92", "repo": "sops-nix", - "rev": "8d215e1c981be3aa37e47aeabd4e61bb069548fd", + "rev": "c7067be8db2c09ab1884de67ef6c4f693973f4a2", "type": "github" }, "original": { @@ -314,11 +315,11 @@ "systems": "systems_2" }, "locked": { - "lastModified": 1701680307, - "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", "owner": "numtide", "repo": "flake-utils", - "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index d101a40..32d97bc 100644 --- a/flake.nix +++ b/flake.nix @@ -2,7 +2,7 @@ description = "computer systems infrastructure"; inputs = { - nixpkgs.url = "github:nixos/nixpkgs/nixos-25.05"; + nixpkgs.url = "github:nixos/nixpkgs/nixos-25.11"; flake-parts.url = "github:hercules-ci/flake-parts"; @@ -15,7 +15,7 @@ deploy-rs.url = "github:serokell/deploy-rs"; deploy-rs.inputs.nixpkgs.follows = "nixpkgs"; - impermanence.url = "github:nix-community/impermanence"; + impermanence.url = "github:nix-community/impermanence/4b3e914cdf97a5b536a889e939fb2fd2b043a170"; breeze.url = "git+https://git.min.rip/min/breeze.git"; breeze.inputs.nixpkgs.follows = "nixpkgs"; @@ -24,7 +24,7 @@ sim-breeze.inputs.nixpkgs.follows = "nixpkgs"; }; - outputs = inputs @ {self, ...}: + outputs = inputs: inputs.flake-parts.lib.mkFlake {inherit inputs;} { flake = let hosts = import ./nixos/hosts {inherit inputs;}; @@ -34,12 +34,7 @@ systems = ["x86_64-linux"]; - perSystem = { - system, - pkgs, - inputs', - ... - }: { + perSystem = {pkgs, ...}: { devShells.default = pkgs.mkShell { packages = with pkgs; [ sops diff --git a/nixos/hosts/eidola/configuration.nix b/nixos/hosts/eidola/configuration.nix index 9c7e4eb..ea0df3d 100644 --- a/nixos/hosts/eidola/configuration.nix +++ b/nixos/hosts/eidola/configuration.nix @@ -24,9 +24,11 @@ nixpkgs.config.allowUnfree = true; # Basic networking - networking.firewall.enable = true; - networking.firewall.allowedTCPPorts = [5201]; - networking.firewall.allowedUDPPorts = [5201]; + networking.firewall = { + enable = true; + allowedTCPPorts = [5201]; + allowedUDPPorts = [5201]; + }; # Locales i18n.defaultLocale = "en_US.UTF-8"; @@ -68,6 +70,16 @@ port = 22; } ]; + hostKeys = [ + { + path = "/persist/etc/ssh/ssh_host_ed25519_key"; + type = "ed25519"; + } + { + path = "/persist/etc/ssh/ssh_host_rsa_key"; + type = "rsa"; + } + ]; }; # My modules diff --git a/nixos/hosts/eidola/mounts.nix b/nixos/hosts/eidola/mounts.nix index 91843a2..8cf7cc9 100644 --- a/nixos/hosts/eidola/mounts.nix +++ b/nixos/hosts/eidola/mounts.nix @@ -9,6 +9,7 @@ _: { "/var/log" "/var/lib/systemd/coredump" "/var/lib/nixos" + "/var/lib/containers" "/var/db/sudo" "/etc/zfs" @@ -32,6 +33,10 @@ _: { depends = ["/persist"]; neededForBoot = true; }; + "/var/lib/containers" = { + depends = ["/persist"]; + neededForBoot = true; + }; "/persist".neededForBoot = true; # no further config is needed, disko handles the rest }; } diff --git a/nixos/hosts/eidola/nebula.nix b/nixos/hosts/eidola/nebula.nix index da15334..68850e1 100644 --- a/nixos/hosts/eidola/nebula.nix +++ b/nixos/hosts/eidola/nebula.nix @@ -14,7 +14,7 @@ in { enable = true; enableLighthouse = false; - cert = ../../keys/n-srv-eidola.crt; + cert = ../../keys/eidola.crt; key = config.sops.secrets."nebula-key".path; extraInbound = [ diff --git a/nixos/hosts/silver/configuration.nix b/nixos/hosts/silver/configuration.nix index 1f24bd8..016809b 100644 --- a/nixos/hosts/silver/configuration.nix +++ b/nixos/hosts/silver/configuration.nix @@ -29,7 +29,11 @@ in { nixpkgs.config.allowUnfree = true; # Basic networking - networking.firewall.enable = true; + networking.firewall = { + enable = true; + allowedTCPPorts = [5201]; + allowedUDPPorts = [5201]; + }; # Networking - IP configuration networking = { @@ -81,8 +85,6 @@ in { speedtest-cli ]; environment.variables.EDITOR = "vim"; - networking.firewall.allowedTCPPorts = [5201]; - networking.firewall.allowedUDPPorts = [5201]; # Enable ssh server services.openssh = { @@ -95,6 +97,16 @@ in { port = 22; } ]; + hostKeys = [ + { + path = "/persist/etc/ssh/ssh_host_ed25519_key"; + type = "ed25519"; + } + { + path = "/persist/etc/ssh/ssh_host_rsa_key"; + type = "rsa"; + } + ]; }; # My modules diff --git a/nixos/hosts/silver/mounts.nix b/nixos/hosts/silver/mounts.nix index 6175f7c..6a18cfe 100644 --- a/nixos/hosts/silver/mounts.nix +++ b/nixos/hosts/silver/mounts.nix @@ -1,8 +1,10 @@ _: { environment.persistence."/persist" = { - hideMounts = true; + # it doesn't make a difference if mounts + # are hidden from GNOME because we aren't + # using that + hideMounts = false; directories = [ - # "/etc/secureboot" "/etc/ssh" "/etc/secrets" @@ -27,10 +29,20 @@ _: { fileSystems = { "/".neededForBoot = true; + # this only works on older versions + # of impermanence (which i'm pinned to) + # it's better to use `RequiresMountsFor`, maybe "/etc/ssh" = { depends = ["/persist"]; neededForBoot = true; }; + # this fixed "var-lib-containers.mount" reload failure + # when i was upgrading 25.05->25.11. i am not sure + # if it is a good idea or necessary or not + "/var/lib/containers" = { + depends = ["/persist"]; + neededForBoot = true; + }; "/persist".neededForBoot = true; # no further config is needed, disko handles the rest }; } diff --git a/nixos/hosts/silver/services/bustaguard.nix b/nixos/hosts/silver/services/bustaguard.nix new file mode 100644 index 0000000..95b9b8c --- /dev/null +++ b/nixos/hosts/silver/services/bustaguard.nix @@ -0,0 +1,17 @@ +{config, ...}: { + sops.secrets."svc-bustaguard-ghcr-token" = {}; + sops.secrets."svc-bustaguard-config" = {}; + + virtualisation.oci-containers.containers.bustaguard = { + image = "ghcr.io/harborseals/bustaguard:latest"; + extraOptions = ["--rm"]; + login = { + registry = "ghcr.io"; + username = "minishd"; + passwordFile = config.sops.secrets."svc-bustaguard-ghcr-token".path; + }; + volumes = [ + "${config.sops.secrets."svc-bustaguard-config".path}:/app/config.yaml" + ]; + }; +} diff --git a/nixos/hosts/silver/services/default.nix b/nixos/hosts/silver/services/default.nix index 69af10d..5b1b384 100644 --- a/nixos/hosts/silver/services/default.nix +++ b/nixos/hosts/silver/services/default.nix @@ -1,4 +1,4 @@ -{pkgs, ...}: { +_: { imports = [ ./vcnotifier.nix ./breeze.nix @@ -14,6 +14,7 @@ ./wireguard.nix ./shim-navidrome.nix ./shim-maloja.nix + ./bustaguard.nix ]; security.acme = { @@ -23,9 +24,7 @@ services.nginx = { enable = true; - package = pkgs.nginxQuic; - recommendedZstdSettings = true; recommendedGzipSettings = true; recommendedBrotliSettings = true; recommendedTlsSettings = true; diff --git a/nixos/hosts/silver/services/nebula.nix b/nixos/hosts/silver/services/nebula.nix index 0ecb745..ed2590c 100644 --- a/nixos/hosts/silver/services/nebula.nix +++ b/nixos/hosts/silver/services/nebula.nix @@ -13,7 +13,7 @@ in { enable = true; enableLighthouse = true; - cert = ../../../keys/lh-silver.crt; + cert = ../../../keys/silver.crt; key = config.sops.secrets."svc-nebula-key".path; extraInbound = []; diff --git a/nixos/hosts/silver/services/wireguard.nix b/nixos/hosts/silver/services/wireguard.nix index 1ef5533..f5bc583 100644 --- a/nixos/hosts/silver/services/wireguard.nix +++ b/nixos/hosts/silver/services/wireguard.nix @@ -6,14 +6,16 @@ interface = "wg0"; wgPort = 49090; in { - sops.secrets."svc-wireguard-key" = {}; - sops.secrets."svc-wireguard-psk-0-2" = {}; - sops.secrets."svc-wireguard-psk-1-1" = {}; - sops.secrets."svc-wireguard-psk-1-2" = {}; - sops.secrets."svc-wireguard-psk-1-3" = {}; - sops.secrets."svc-wireguard-psk-2-1" = {}; - sops.secrets."svc-wireguard-psk-3-1" = {}; - sops.secrets."svc-wireguard-psk-4-1" = {}; + sops.secrets = { + "svc-wireguard-key" = {}; + "svc-wireguard-psk-0-2" = {}; + "svc-wireguard-psk-1-1" = {}; + "svc-wireguard-psk-1-2" = {}; + "svc-wireguard-psk-1-3" = {}; + "svc-wireguard-psk-2-1" = {}; + "svc-wireguard-psk-3-1" = {}; + "svc-wireguard-psk-4-1" = {}; + }; boot.kernel.sysctl."net.ipv4.ip_forward" = true; @@ -40,7 +42,7 @@ in { ''; preShutdown = '' ${iptables} -D FORWARD -i ${interface} -o ${interface} -d 10.193.0.2 -p tcp -m multiport --dports 139,445 -j ACCEPT - ${iptables} -D FORWARD -i ${interface} -o ${interface} -d 10.193.0.2 -p tcp -m multiport --dports 139,445 -j ACCEPT + ${iptables} -D FORWARD -i ${interface} -o ${interface} -d 10.193.0.2 -p udp -m multiport --dports 139,445 -j ACCEPT ${iptables} -D FORWARD -i ${interface} -o ${interface} -d 10.193.4.1 -p tcp -m multiport --dports 49022 -j ACCEPT ${iptables} -D FORWARD -i ${interface} -o ${interface} -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT ${iptables} -D FORWARD -i ${interface} -o ${interface} -j DROP diff --git a/nixos/hosts/silver/services/xray.nix b/nixos/hosts/silver/services/xray.nix index e63b6b8..01d3eaa 100644 --- a/nixos/hosts/silver/services/xray.nix +++ b/nixos/hosts/silver/services/xray.nix @@ -32,14 +32,11 @@ in { }; # assign user/group to xray - users.users.${user} = { isSystemUser = true; inherit group; }; - users.groups.${group} = {}; - systemd.services.xray.serviceConfig = { User = user; Group = group; diff --git a/nixos/keys/ca.crt b/nixos/keys/ca.crt index 08b84ab..a9199b0 100644 --- a/nixos/keys/ca.crt +++ b/nixos/keys/ca.crt @@ -1,5 +1,5 @@ ------BEGIN NEBULA CERTIFICATE----- -CjgKBm1pbmZyYSj8vdjBBjD88ubuBjogzzw7qn0fU8HJtJpdr49EKLgMhTLFCbgA -HK1WJ8LZDN9AARJAYFxxJPsQfUI+bNDOb3HMwegSpSoWpyZp0FpDI14BcnuTbasO -DalRbIntnfs0485zdHVEEETeBBRr3rCmziY/DA== ------END NEBULA CERTIFICATE----- +-----BEGIN NEBULA CERTIFICATE V2----- +MIGGoCCABm1pbmZyYaEHBAUKDQAAEIQB/4UEaXQMj4YEcPjaj4Igt49Xxopbdu1x +M2lOkkKqlKSeK/aHv8DRSwwYrCOs6PuDQN9kGNLshq2P7NkNfjUlXvjIgTHB+SK2 +onsMVPWahwj7i3V60S/NlkGNfQU32Y6HaEtwwgOcDV39YHTmOTPMoAE= +-----END NEBULA CERTIFICATE V2----- diff --git a/nixos/keys/eidola.crt b/nixos/keys/eidola.crt new file mode 100644 index 0000000..c9060ff --- /dev/null +++ b/nixos/keys/eidola.crt @@ -0,0 +1,6 @@ +-----BEGIN NEBULA CERTIFICATE V2----- +MIGxoEuABmVpZG9sYaEHBAUKDQEBEKMKDAhpbnRlcm5hbIUEaXQTj4YEbTZ6j4cg +9J44UzZAMiD+WYDfBX8y9RzUppN5cB12we3ReFPboE2CIKNJsgonkA5Qti7MjnMs +C6dK082bmc72WnRIKbIo7iNdg0D26pZpZQAv9yjUf0ajUE+sBT9MmpY1K1+Iilak +edChqrbLLAwUOpoJTlObAmKAEnEl3j9bmijfLiPj7SMtS7AL +-----END NEBULA CERTIFICATE V2----- diff --git a/nixos/keys/lh-silver.crt b/nixos/keys/lh-silver.crt deleted file mode 100644 index b3c248e..0000000 --- a/nixos/keys/lh-silver.crt +++ /dev/null @@ -1,6 +0,0 @@ ------BEGIN NEBULA CERTIFICATE----- -CnAKCWxoLXNpbHZlchIJgYC0UICA/P8PIghpbnRlcm5hbCjvvtjBBjD78ubuBjog -5jO2THNsXEv59VasXZnNpZh6s2b3mo1WlvHC3jrCHW5KICkUiAsYMUJqlkZMvhPb -Zcs48ZEdpMaH8ZQR+/YrCR94EkB6OOguIBOxqcmfuGbNDPZap6euF+oiYT5QhfPh -6HyEIZ1eRZkW0Q9v4QUKFdDbxKQfK0moxor6KlkLGLp9E2cL ------END NEBULA CERTIFICATE----- diff --git a/nixos/keys/n-srv-eidola.crt b/nixos/keys/n-srv-eidola.crt deleted file mode 100644 index 09b50e5..0000000 --- a/nixos/keys/n-srv-eidola.crt +++ /dev/null @@ -1,6 +0,0 @@ ------BEGIN NEBULA CERTIFICATE----- -CnMKDG4tc3J2LWVpZG9sYRIJgYK0UICA/P8PIghpbnRlcm5hbCidv9jBBjD78ubu -Bjoga6Kii9Vqn9bB4mQnBUPHfQwvvJlUrKCTzbMZNsvDDTBKICkUiAsYMUJqlkZM -vhPbZcs48ZEdpMaH8ZQR+/YrCR94EkDQbthaT5aNgviM2RQH7/J3rMtRCcW8bWVW -anDTFdvSW8BLRTet38jrRT9TBiyB2AokYuHxCLcmePMmwGbh6yoO ------END NEBULA CERTIFICATE----- diff --git a/nixos/keys/silver.crt b/nixos/keys/silver.crt new file mode 100644 index 0000000..c64205e --- /dev/null +++ b/nixos/keys/silver.crt @@ -0,0 +1,6 @@ +-----BEGIN NEBULA CERTIFICATE V2----- +MIGxoEuABnNpbHZlcqEHBAUKDQABEKMKDAhpbnRlcm5hbIUEaXQNQ4YEbTZ0Q4cg +9J44UzZAMiD+WYDfBX8y9RzUppN5cB12we3ReFPboE2CIBsnWV1JH2xAuS3pIr4r +gLi10CzWDIYqupE/Va760nMQg0B35mxnvbj3Z3b8FlObhlLaB2jd0OvKP/1U8KHT +DPrCCFhRx4WlrdbJmyKTd87tIix/dNh/3fBDuVE8m6nhZj4B +-----END NEBULA CERTIFICATE V2----- diff --git a/nixos/modules/default.nix b/nixos/modules/default.nix index 3283c01..632dff1 100644 --- a/nixos/modules/default.nix +++ b/nixos/modules/default.nix @@ -25,8 +25,9 @@ nixos.enable = false; }; - # Immutable users + # User management users.mutableUsers = false; + services.userborn.enable = true; ### Nix settings ### nix = { diff --git a/nixos/modules/nebula/default.nix b/nixos/modules/nebula/default.nix index dd2001f..c6ac8f5 100644 --- a/nixos/modules/nebula/default.nix +++ b/nixos/modules/nebula/default.nix @@ -48,7 +48,7 @@ with lib; let }; }; baseClient = let - lhs = {"10.13.0.1" = ["66.23.198.122:4242"];}; + lhs = {"10.13.0.1" = ["66.23.198.122:4242"];}; # TODO: hardcoding lhsInternal = attrNames lhs; in { lighthouses = lhsInternal; diff --git a/scripts/install.sh b/scripts/install.sh index 1b80346..e884e1d 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # fail on errors -set -e +set -eo pipefail die() { echo >&2 "$@" @@ -9,32 +9,34 @@ die() { } # parse args -POSITIONAL_ARGS=() +I_ARGS=() while [[ $# -gt 0 ]]; do case $1 in -c|--nixos-config) - NAME="$2" + I_CONFIG="$2" shift # past argument shift # past value ;; -k|--key-dir) - KEYDIR="$2" + I_KEYDIR="$2" shift # past argument shift # past value ;; *) - POSITIONAL_ARGS+=("$1") # save positional arg + I_ARGS+=("$1") # save positional arg shift # past argument ;; esac done # check args -[ ! -f "$KEYDIR/host.pub" ] && die "host pubkey missing!" -[ ! -f "$KEYDIR/host" ] && die "host privkey missing!" -[ ! -f "$KEYDIR/host_initrd.pub" ] && die "host pubkey (initrd) missing!" -[ ! -f "$KEYDIR/host_initrd" ] && die "host privkey (initrd) missing!" -[ ! -f "$KEYDIR/luks-pw" ] && die "luks pw missing!" +[ -z "$I_CONFIG" -o -z "$I_KEYDIR" -o ${#I_ARGS[@]} -eq 0 ] \ + && die "usage: $0 -c|--nixos-config -k|--keydir " +[ ! -f "$I_KEYDIR/host.pub" ] && die "host pubkey missing!" +[ ! -f "$I_KEYDIR/host" ] && die "host privkey missing!" +[ ! -f "$I_KEYDIR/host_initrd.pub" ] && die "host pubkey (initrd) missing!" +[ ! -f "$I_KEYDIR/host_initrd" ] && die "host privkey (initrd) missing!" +[ ! -f "$I_KEYDIR/luks-pw" ] && die "luks pw missing!" # temp work dir temp=$(mktemp -d) @@ -47,25 +49,25 @@ trap cleanup EXIT echo "Preparing host keys.." dir="$temp/persist/etc/ssh" install -d -m755 "$dir" -cp "$KEYDIR/host" "$dir/ssh_host_ed25519_key" -cp "$KEYDIR/host.pub" "$dir/ssh_host_ed25519_key.pub" +cp "$I_KEYDIR/host" "$dir/ssh_host_ed25519_key" +cp "$I_KEYDIR/host.pub" "$dir/ssh_host_ed25519_key.pub" chmod 600 "$dir/ssh_host_ed25519_key" # prepare host keys (initrd) echo "Preparing host keys.. (initrd)" dir="$temp/persist/etc/secrets/initrd" install -d -m755 "$dir" -cp "$KEYDIR/host" "$dir/ssh_host_ed25519_key" -cp "$KEYDIR/host.pub" "$dir/ssh_host_ed25519_key.pub" +cp "$I_KEYDIR/host" "$dir/ssh_host_ed25519_key" +cp "$I_KEYDIR/host.pub" "$dir/ssh_host_ed25519_key.pub" chmod 600 "$dir/ssh_host_ed25519_key" # nixos-anywhere echo "Starting install.." nixos-anywhere \ - --disk-encryption-keys "/tmp/luks-pw" "$KEYDIR/luks-pw" \ + --disk-encryption-keys "/tmp/luks-pw" "$I_KEYDIR/luks-pw" \ --extra-files "$temp" \ - --flake .#$NAME \ - "${POSITIONAL_ARGS[@]}" + --flake .#$I_CONFIG \ + "${I_ARGS[@]}" echo -e "Finished install.\n" \ "Make sure to delete the SSH host keys from here if you are done with them." diff --git a/scripts/make_base_keys.sh b/scripts/make_base_keys.sh index 679f8da..a97f2a8 100755 --- a/scripts/make_base_keys.sh +++ b/scripts/make_base_keys.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # fail on errors -set -e +set -eo pipefail die() { echo >&2 "$@" @@ -9,11 +9,11 @@ die() { } # set up target folder -P="$1" -[[ -z "$P" || -d "$P" ]] && die "specify a non-existent path as a first argument" +TARGET="$1" +[[ -z "$TARGET" || -d "$TARGET" ]] && die "specify a non-existent path as a first argument" -mkdir "$P" -pushd "$P" >/dev/null +mkdir "$TARGET" +pushd "$TARGET" >/dev/null # host keys echo "Generating SSH host keys.." @@ -32,5 +32,5 @@ echo -n "$(openssl rand -base64 24)" > ./luks-pw # we are done popd >/dev/null -echo "Finished generating keys." \ - "Delete them or put them somewhere else once you're done with them." +echo -e "Finished generating keys." \ + "Delete them or put them somewhere else once you're done with them." diff --git a/scripts/make_vpn_ca.sh b/scripts/make_vpn_ca.sh new file mode 100755 index 0000000..db30c08 --- /dev/null +++ b/scripts/make_vpn_ca.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash + +# fail on errors +set -euo pipefail + +# operate from root of repository +SCRIPT_DIR="$(dirname "$0")" +ROOT_DIR="$(realpath "$SCRIPT_DIR/..")" +pushd "$ROOT_DIR" > /dev/null + +# constants +KEY_PATH="./secrets/ca.key" +CRT_PATH="./nixos/keys/ca.crt" + +# move old files +[ ! -f "$KEY_PATH" ] || mv "${KEY_PATH}" "${KEY_PATH}.old" +[ ! -f "$CRT_PATH" ] || mv "${CRT_PATH}" "${CRT_PATH}.old" + +# generate ca +nebula-cert ca \ + -duration 35040h0m0s \ + -name minfra \ + -networks 10.13.0.0/16 \ + -out-crt "$CRT_PATH" \ + -out-key "$KEY_PATH" + +# encrypt ca key +encrypt_fail() { + echo "failed to encrypt ca key with sops!" + rm "$KEY_PATH" + rm "$CRT_PATH" +} +sops -i -e "$KEY_PATH" || encrypt_fail + +# done +popd >/dev/null +echo -e "Generated new VPN CA.\n" \ + "(Don't forget to regenerate node keys)" diff --git a/scripts/make_vpn_keys.sh b/scripts/make_vpn_keys.sh new file mode 100755 index 0000000..81a68ff --- /dev/null +++ b/scripts/make_vpn_keys.sh @@ -0,0 +1,77 @@ +#!/usr/bin/env bash + +# fail on errors +set -eo pipefail + +die() { + echo -e >&2 "$@" + exit 1 +} + +# read arguments +while [[ $# -gt 0 ]]; do + case $1 in + -n|--name) + I_NAME="$2" + shift # past argument + shift # past value + ;; + -h|--network) + I_NETWORK="$2" + shift # past argument + shift # past value + ;; + -i|--internal) + I_GROUPS="internal" + shift # past argument + ;; + *) + shift # past argument + ;; + esac +done + +# check arguments +[ -z "$I_NAME" -o -z "$I_NETWORK" ] \ + && die "usage: $0 -n|--name -h|--network [-i|--internal]\n" \ + "+ note: network cidr should match lighthouse.\n" \ + "+ ex: for an ip of 10.13.1.1, use 10.13.1.1/16" + +# operate from root of repository +SCRIPT_DIR="$(dirname "$0")" +ROOT_DIR="$(realpath "$SCRIPT_DIR/..")" +pushd "$ROOT_DIR" > /dev/null + +# constants +CA_KEY_PATH="./secrets/ca.key" +CA_CRT_PATH="./nixos/keys/ca.crt" +CA_KEY_DECR_PATH="./secrets/.decrypted~ca.key" + +# output +OUT_CRT_PATH="${I_NAME}.crt" +OUT_KEY_PATH="${I_NAME}.key" + +# decrypt ca +echo "Decrypting CA.." +sops -d --output "$CA_KEY_DECR_PATH" "$CA_KEY_PATH" + +# generate key +echo "Generating keys.." +nebula-cert sign \ + -duration 17520h0m0s \ + -name "$I_NAME" \ + -networks "$I_NETWORK" \ + -groups "$I_GROUPS" \ + -ca-crt "$CA_CRT_PATH" \ + -ca-key "$CA_KEY_DECR_PATH" \ + -out-crt "$OUT_CRT_PATH" \ + -out-key "$OUT_KEY_PATH" + +# delete decrypted key +echo "Removing decrypted CA.." +rm "$CA_KEY_DECR_PATH" + +# we are done +popd >/dev/null +echo -e "Generated VPN keys.\n" \ + "(Delete *.key file once it's added as a secret)" diff --git a/scripts/rekey.sh b/scripts/rekey.sh index 26d2b04..92a61d1 100755 --- a/scripts/rekey.sh +++ b/scripts/rekey.sh @@ -1,12 +1,17 @@ #!/usr/bin/env bash -shopt -s globstar +# fail on errors +set -euo pipefail +# operate from root of repository SCRIPT_DIR="$(dirname "$0")" ROOT_DIR="$(realpath "$SCRIPT_DIR/..")" - pushd "$ROOT_DIR" > /dev/null +# allow globstar +shopt -s globstar + +# rekeying rekey_dir() { find $1 -type f | xargs -i sops updatekeys -y {} } diff --git a/secrets/ca.key b/secrets/ca.key new file mode 100644 index 0000000..4a52418 --- /dev/null +++ b/secrets/ca.key @@ -0,0 +1,18 @@ +{ + "data": "ENC[AES256_GCM,data:LbJEEB8K0cfp2W3OBBwiEYEVWApVzqDEr4E2pTVMUJmZWhZogMM3d32HqQtvudDiV0RDAv+LbsbNnCUwm7b4EIWhJI+9oqCguyblS8X9dEWdC00cz3OpugFKtQyUyVLMYPqKcaOmngffkJnVJpT0Qiwap9lD0tBE/eqc30r67n5WwLPM6FTAvOkcqcfT17uLwSVwxbJie3EqwZmMn1gBauk6dH8ZOlPtD9IJ86NR,iv:7Npy1qZuVVbt3a4I1spDSRQSR/VR0lF7NAdBvvAYsAM=,tag:74qB+CJacdfdPABpSS4NJg==,type:str]", + "sops": { + "age": [ + { + "recipient": "age1yubikey1qg5k0y844v5e79uwax3r00u7zdljwnjlrmwvdr3st9m5a3ra5098qy0sjdj", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IHBpdi1wMjU2IGpBdE54USBBcE10U3dM\nelNXR3AzaTF4RURlSUwzL3pLSUlxeUZ2SHBkK2d1bVk5aEJpMgpVUHF4bVI0L3dC\ncm80blpKQTg0TlJDN1pmZ1BhT0J4Q1M0cktWQXhjQ2g4Ci0tLSAxRHdOQXNES0g4\nU3h0SFliNTlzRVN5UFJjS1BwZUxSU2lPcEg2SjNoU0w0CqXKsEktdPWkZOmjyb9f\nWC0gNpnH2bi8u2WSoXXBZHUiSBY5TkDVfD2A//RlMEdkF2kDxib9BvMPGg5Ar0mP\n6HY=\n-----END AGE ENCRYPTED FILE-----\n" + }, + { + "recipient": "age1yjqjfdpajzg8a2cj4e5ax6wcg5rq3337rm9jwsfzug2tr7yj8yfq27vteh", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAxZ0RTQlc5c2NMcTFOb3Vw\nRTJaaFE3d0ZpcytxWHRRS1B0ZE45eXl0NDM4Ck9ScFdDMm9PWjIwcXhIUzVUL0tR\nQm0rRFAvMnM1bFZPbFVZeTRrWmhXQW8KLS0tIG9ZV0Y5d2FHdzdqMXUxN1I1RmZ2\nT1JwL0lWK2xMTFpQS2NVbnZ4NUh2Q0EK14BXrinNYVKC4f2+ZUIAdUtMgeCBWlwJ\nfMJd1qEfSWoijo8tYfw4EFxzu5B3SutIFkvod8Z+jlbbVN5AYqAyAw==\n-----END AGE ENCRYPTED FILE-----\n" + } + ], + "lastmodified": "2026-01-24T00:04:31Z", + "mac": "ENC[AES256_GCM,data:ZXO5WI4eb43SYSS8gl5252QV6CobOTkll85/h19SRfkZnwfiSVd7vINh7t1CCh+Y5gTQgRYyEOwBW2f9vqlNjNZTbKC+x+ZUvy4dF92I5DonRlRTzVvr0Mu1nk7kk7DB+EvR5c+sW57i9DF7yz9g52W7Bi767qErbbS76mawBwY=,iv:yimQlZwL1S7PQjtkTXPLWjO+6iH7sbZqtnVYryNnD7Y=,tag:QVSggpmecUckWuqYqQzpvA==,type:str]", + "version": "3.11.0" + } +} diff --git a/secrets/eidola/default.yaml b/secrets/eidola/default.yaml index 9e9784f..0eead77 100644 --- a/secrets/eidola/default.yaml +++ b/secrets/eidola/default.yaml @@ -1,6 +1,6 @@ root-pw: ENC[AES256_GCM,data:g/dIT5d5w+FCAbxgGRJoMISgVTySEqXoBCV/jopu9Cgm4db9zAFWzZ7kUqOr8IQpEpCXyguYClIGExt0SztbRze8YPu9NilcUmYH7QmI+8oaEanYkvwpT5jyBU/M2eG0U9pMzcGI6hl2Ew==,iv:2HmGvFkRrnwYi5gjB4Na/ZayGoCFEsM4TDoqKlzhZUg=,tag:NLuval5PJ6AnDLvPGVvm7w==,type:str] user-pw: ENC[AES256_GCM,data:gr+Dis3c5NWLWnfJG4eJUxwt574R3n40djeK68hukMNPx0qwGRAT5a7UQ5doxtDBgafcH1uCgqrsWwEmy9H5dS6WfLMivE5Uy213EcEk3YNUwI9d5vbdcbCcXWvPsyCu6sxS3x731EVVYA==,iv:4AHzVLoJD95d2UwwEAwxWP0G2gekHahBt4hDDA9ZSx0=,tag:03L3Ql070mt3oDV5YdrETg==,type:str] -nebula-key: ENC[AES256_GCM,data:kJeN4hkXIAqxszpsCznGn1ZCz/crVQL6oNVu0hKQ/Nrp6c6vSUE8zmjdhKGp26sNtSOwhz4nCXCSkUkGClfrnz+WtnI1S+nKxaXgCg1tcyGX90/NqiSsgjVUNMIFBOg/2eurJYoTLCv2bLGH2ED+BtqPky1rqYGkhllwq9Mu,iv:jgcdrQ815vyVdRRBYMa4vpRq5HQ9kK54Oi1AGXohYz0=,tag:fBysvfkA77pN4zcnYgeGLA==,type:str] +nebula-key: ENC[AES256_GCM,data:ult/inutRoz/MBJxlUlPqdiDn41OUvByDaedSPiPIM0ZIq5NbuBdBmf2dHArj0qDWQAMZLgr/ZBNwPs1eVScuqUVHtqlnhZGqji8G1c0psX/zS19rpLR8SZzorcyLPgiCuEQ8K7rhQlgkt7oSKM8LGD1QxO0a5Z9BnN9avVg,iv:LuLH1PWLYps5CIGjBjcuKT//b0SXrOrQPOr5RiWUXf4=,tag:3179IgcCs29jvu/b0tza+w==,type:str] terra-key: ENC[AES256_GCM,data:pQRlvltiRr83ndfSjX/I8n1WekS9jY2K1QyLTTcYn14TRupRVgvX47rsus1QA9QAbpT/9f0ZYld3aCrR5J0rxg==,iv:mkiu/+uLKOHG9gDjv72T7JGz6/3oaimDawAOqGs3Koo=,tag:c9Ubj3i5rDj5vaLBRpAUkQ==,type:str] wireguard-key: ENC[AES256_GCM,data:aM76YT/0gbfw87x3ThrwFMuf9DxC0IJ5aCeEFDtL+JWPGsZk3XtrN+kxW6w=,iv:ssh+sGPxMU55ubNZlWcWh+3fXvhjhJ6cNJhPZJVXEyw=,tag:2PdoFb2CyeTkV0EKfcpZiQ==,type:str] wireguard-psk: ENC[AES256_GCM,data:fEDfzuZVvEC8/HHbV4k0fSZHucRk3PLc/jaf/wl5Np+4OB1SiK6VnSyoW2o=,iv:2QnunJjHxt8V/DBG2KAuzwGQsJnmrspj6x01ufiJteY=,tag:teEVG+TuRg+QsY4jMg2DzQ==,type:str] @@ -35,7 +35,7 @@ sops: eWRoSXlMamNjTHVaenpMR3dEOXNuWDAKSmbC+fGeKYcKy0eQdWPVVMpyBVYtogur A0fYIBLXi+HMN+/7LXFb80vSnXN3v42KGQ/tzsWJo0ed3Q16wJ4eUA== -----END AGE ENCRYPTED FILE----- - lastmodified: "2025-05-27T20:27:35Z" - mac: ENC[AES256_GCM,data:cM953KDX815uNvRr7LnoVhXdfLi3UY1F6yoaibCqRg7c8Ai0rBcrXyKqa7ny6u+ltH3wzlaFfIhYtrVRhFwpfL1X4jz/WKKejaxT+PRX/ow1ht8CwMGPLcEF68gVje0Cs6BqTF/WPmXRdCwladjbetF/LyFal9LCgrfrhIgIdAM=,iv:VC5cdEVb/WONMzpoTdTZB2qLnnl7leVL38v9gcckM0Q=,tag:PMYghtOP7RTV/d/Qh+f0kg==,type:str] + lastmodified: "2026-01-24T00:34:58Z" + mac: ENC[AES256_GCM,data:g/t+H+GpBRNN8NeWwRdoxVXkprkk9JWdPOE887XKfaaupenxE1jyFXs3j4g69Vyg0+FvNZoodDveks9VQJdEOhfTRe+ln4bC4rA8HeRc93pNcs1pdduowzyHIKzvMZf8x9Vc3s6U6VnOjJH7aGWkKXJKcwX3CAsG0h2o158XwX8=,iv:CV/sgtRtfbVUF1N3mEsKeIDFRVbJbT70HHi2wPdvrCo=,tag:mRy83EbR0A5SOr/LxDwedg==,type:str] unencrypted_suffix: _unencrypted - version: 3.10.2 + version: 3.11.0 diff --git a/secrets/silver/default.yaml b/secrets/silver/default.yaml index 831119c..3786a0b 100644 --- a/secrets/silver/default.yaml +++ b/secrets/silver/default.yaml @@ -7,7 +7,7 @@ svc-breeze-deletion_secret: ENC[AES256_GCM,data:foilGTV7493fl7f/ZnN1bO7f4YLGapXl svc-sim-breeze-upload_key: ENC[AES256_GCM,data:qm93iBzGhqp7IuZ01uZ6PyL5bL45+W0oOeDyQRGEzZw=,iv:5F7BV5Sg6GUxIGQychaEZSeG7xDFF+JdRL83PJULWJA=,tag:W/Q8vGaPoLNnj1Wyvc9Cnw==,type:str] svc-synapse-synapse-config: ENC[AES256_GCM,data:r8ZYi67CfftGheassCFiLOVcFUho+sNNe0XCkyQETHT6Q/w2jqO9eAVA2EDJyK4Vk3S4MP6ppcGxwocMmTYzkAjmtwf6a7GzUyh14+Lj5VTybvIKOze0wuLlsEUUYgU=,iv:HTnPaS5/ZvdJIMKiTfPffZmemp5IGTo/mIWrpafk/Fk=,tag:2HusbhzmxqsTMz5/78WCRA==,type:str] svc-gitea-runner-env: ENC[AES256_GCM,data:M2hV8YM03dcBcgpJqbpiW6RGlhDvkfF/ExF+J1GF+39GnOsBWwPKteM5EAUB2Wrl/zRFifgfNLLdYgSEWhJsT1cBLhI3vwE5,iv:9/nvC3sS6XcLxgeKrEg/AaFhptXCm3uvGgSUMAz4p5Y=,tag:A1MnoJP6aekXuWHhlONnkw==,type:str] -svc-nebula-key: ENC[AES256_GCM,data:utJO5t4mq4tmAkAv9A2tcClM3nxLxMSWiz/bUoq8PkbnDxbNjzvdoqD7ehQfpZtK7lQlySXePEcUkQJw2JREfYx8cexOvTyxlwiuxmx2QikTOVO/MALuTG54j9hUSvPeLYnhFNF88vIlFrrjwl0ox/DVjmlrXJbxZWRq/six,iv:C/ZQ2U/brbfrzHXt4nrxfjKIorlUcuBXp0kk5ObuyYE=,tag:/BSjrGcGNuTVVBi89mUwkw==,type:str] +svc-nebula-key: ENC[AES256_GCM,data:cxNlWEzpzUG78XnuzXXo/LX0FixPe82IzBjat9+tEhf81qnVJVpafdGDbyqL1PLx3cncjqzeV/ntiTLOaBra8WCPrgC0YJ161JNPGjdrOt1pFT4C2E2Wjv0G3qONhxSUQ8BSht4QxOu+Sy0OMu8gKiRsAwvtJMDYsMy0J5CM,iv:+5OnTzeAYBcUQIf8zU9BHizgGy07KAUujMPALr52YZw=,tag:MrDn7z6MnW/c0MM+zIgAUg==,type:str] svc-wireguard-key: ENC[AES256_GCM,data:dmxJ07UnQAtet4RtlVXEMFLVKxOU44XQcUW7h7UPbLG9chiQeXGkZkkTihs=,iv:bEA9+DYDBLo1dgrCSrIpa1ig9JJEtXeJF5ZmtdsAO3s=,tag:tyLB5Dd9uolalSzddC608A==,type:str] svc-wireguard-psk-0-2: ENC[AES256_GCM,data:0sTGYa3HUe70hYJZnPy9w0iG37aRDTplmdvGdc5C8KN8Dg5XbVc2CmVS1r4=,iv:9Dnr3BYhzKKOZ7S565HY4CkhgPv1JEd3Zk7662/cd9s=,tag:Dd0BLrIjfX0F2lBan59jUg==,type:str] svc-wireguard-psk-1-1: ENC[AES256_GCM,data:YbxjRleUWTr1+rZyzZ+5vB9Po/V0T1mYhH+H8igjascGV/Oo4lPn1xoYqLg=,iv:+fcWdpRqR7GU5UXug+6GCX9Be5DoE944T5PIm0csgEU=,tag:3mGEL3KYjfSJ9uM+i6Wirg==,type:str] @@ -16,6 +16,8 @@ svc-wireguard-psk-1-3: ENC[AES256_GCM,data:66Yw2km4aWUAiy5Gk4diyeUV5AcLh4iJX+nJJ svc-wireguard-psk-2-1: ENC[AES256_GCM,data:+80iLdsHE0rtM1rVb4xUfzOwpMSOqgxtuKWg4d7Kj7kDuvrCrHPX83NruNo=,iv:HDfGq2o41qTyUU3PwfUvJJcb88JIcbW3yrfqRY8lBxY=,tag:+jWwRf5vqSriCOKdOu3Qag==,type:str] svc-wireguard-psk-3-1: ENC[AES256_GCM,data:USX+fQeT+f+ZU8R7pgIXYPBd4f+8BGrFpuJwxCLprkhhxEY2U8kz85zg8Tw=,iv:QxzQyJEIqoT7szXBgE6M2qd0MeO8Y2e4wLRY9PH0x9M=,tag:kWLwR18SVfj52xkN4tJM7g==,type:str] svc-wireguard-psk-4-1: ENC[AES256_GCM,data:gQmzz0CP3b6aLLe1ucGTHmSpTP9RHDAhpnqkQci8RLdm2gQNIxfU5ASmSW8=,iv:Klq6y+81EqjQXZNDpnmPKhq8+gCtWklq09bzlKwm9Ys=,tag:H0GoCLLcVMC8FtzFx9HyPA==,type:str] +svc-bustaguard-ghcr-token: ENC[AES256_GCM,data:43WidupowJWU3y9QorjXM1YDXzoSD8U+HawmI6vaw8jp4la2TJebnA==,iv:4k6usM+AI8pWAfa5Mq2mku+ccXVo6F3mvupYzZrUMrg=,tag:wqX8xtUCCO9/Z0eGykT9uw==,type:str] +svc-bustaguard-config: ENC[AES256_GCM,data:8xfbUvJFXNSmB0S9EiHGnqZcSzWEO618hjd/VeUNPd6zT3Zapg01ZfVgKJd3vrH+RcLmCeLVdo6Wmat49BhuheHswa20Tn3Aq89hS0+5t3JTpentjY5T,iv:tJPOJBa0O310BixH9cOMBRlQwSyHcwnMjDktPvAQCHs=,tag:B2O6j8HG48HSk3zzUc7SLQ==,type:str] sops: age: - recipient: age1yubikey1qg5k0y844v5e79uwax3r00u7zdljwnjlrmwvdr3st9m5a3ra5098qy0sjdj @@ -46,7 +48,7 @@ sops: NVREcHJGWWIvY0Z1OGt4cGN6am1RaXMKAnlb8FOJ1wO5qtcmej57s7rhWjv5wqIn nCUJX0R7s0/KH3aj98bX/4hQg2ZAw1l+xViOOIfwfRnzLWeyaAnk5A== -----END AGE ENCRYPTED FILE----- - lastmodified: "2025-05-31T03:40:23Z" - mac: ENC[AES256_GCM,data:KXxw3HwdVnQcsVhYfTvn4zxlTjmEqHHdDkKqNkY2keZ99mhQVXhHLU7P63+I5VhZy6sid4ueQ/H2+fM38+twMyDo0xLYkhkJd0pXVGgi5GiN+5JcTVf4NvR1+hEt43XEEfTLzRfeEd3resexNu1C/C9LCEZX5LK3GsOlt/xL1s0=,iv:8T0XfBS+ZSOK7gzoQpBnTu+dMis739AI8s5f48DDy1c=,tag:5lr/C1rCsPChqPsfEu7JTQ==,type:str] + lastmodified: "2026-01-24T00:50:27Z" + mac: ENC[AES256_GCM,data:NH6rNg1HYF8R9tNwSWTRy382QWnrENrJYFaSZs+UvH1XX7swljmJFqtPpMCo1TqyquzInzEPqsidwwY14HUCNuEugr9D/mN1r8Yv1pbNTE2kjoXRQJ0tlfi6DrT+xoLKnO0lgMCYVd1pdSZwQ35/4LefcvL+nVmv81AyoDYOCvw=,iv:MI1pZ2dZhrCWkJJFe8ubkt0mlqlWA7O+s2OTE+u2dDg=,tag:CSmJP9nfd1AsbZUPWGM34Q==,type:str] unencrypted_suffix: _unencrypted - version: 3.10.2 + version: 3.11.0