diff --git a/modules/nixos/nas/default.nix b/modules/nixos/nas/default.nix index b5c7b4a..106292c 100644 --- a/modules/nixos/nas/default.nix +++ b/modules/nixos/nas/default.nix @@ -1,18 +1,100 @@ { flake, + config, pkgs, lib, ... }: let - syncthing = import ./syncthing { inherit flake; }; - photoprism = import ./photoprism { inherit flake lib; }; - opencloud = import ./opencloud { inherit flake pkgs; }; + inherit (flake.config.people) user0; + + nasHelpers = { + ipAddress = ip: "192.168.50.${ip}"; + guestPath = user: "/mnt/storage/users/${user}/guests"; + docsPath = user: "/mnt/storage/users/${user}/home/docs"; + mediaPath = user: "/mnt/storage/users/${user}/home/media"; + miscPath = user: "/mnt/storage/users/${user}/home/misc"; + firefly = { + id0 = 70; + id1 = 71; + id2 = 72; + ssh0 = 2570; + ssh1 = 2571; + ssh2 = 2572; + }; + onlyoffice = { + id0 = 73; + id1 = 74; + id2 = 75; + ssh0 = 2573; + ssh1 = 2574; + ssh2 = 2575; + }; + opencloud = { + id0 = 76; + id1 = 77; + id2 = 78; + ssh0 = 2576; + ssh1 = 2577; + ssh2 = 2578; + }; + photoprism = { + id0 = 79; + id1 = 80; + id2 = 81; + ssh0 = 2579; + ssh1 = 2580; + ssh2 = 2581; + }; + syncthing = { + id0 = 82; + id1 = 83; + id2 = 84; + ssh0 = 2582; + ssh1 = 2583; + ssh2 = 2584; + }; + vaultwarden = { + id0 = 85; + id1 = 86; + id2 = 87; + ssh0 = 2585; + ssh1 = 2586; + ssh2 = 2587; + }; + }; + + firefly-iii = import ./guests/firefly-iii { + inherit + nasHelpers + config + flake + pkgs + ; + }; + + opencloud = import ./guests/opencloud { inherit nasHelpers flake pkgs; }; + photoprism = import ./guests/photoprism { inherit nasHelpers flake lib; }; + syncthing = import ./guests/syncthing { inherit nasHelpers flake; }; + vaultwarden = import ./guests/vaultwarden { inherit nasHelpers flake; }; in { imports = [ - syncthing - photoprism + firefly-iii opencloud + photoprism + syncthing + vaultwarden ]; + systemd.tmpfiles.rules = + let + inherit (nasHelpers) docsPath mediaPath miscPath; + homePaths = user: [ + "d ${docsPath user} 0751 microvm wheel - -" + "d ${mediaPath user} 0751 microvm wheel - -" + "d ${miscPath user} 0751 microvm wheel - -" + ]; + in + homePaths user0; + } diff --git a/modules/nixos/nas/guests/firefly-iii/config/default.nix b/modules/nixos/nas/guests/firefly-iii/config/default.nix new file mode 100644 index 0000000..acdf1a5 --- /dev/null +++ b/modules/nixos/nas/guests/firefly-iii/config/default.nix @@ -0,0 +1,243 @@ +{ + flake, + config, + ... +}: +let + inherit (flake.config.people) user0; + inherit (flake.config.services) instances; + serviceCfg = { + name = "firefly-iii"; + }; + smtpCfg = instances.smtp; + +in +{ + fireflyVM = + { + user, + ip, + mac, + userMac, + ssh, + host, + owner, + mnt, + }: + { + microvm.vms = { + "${serviceCfg.name}-${user}" = { + autostart = true; + restartIfChanged = true; + config = { + system.stateVersion = "24.05"; + time.timeZone = "America/Winnipeg"; + users.users.root.openssh.authorizedKeys.keys = flake.config.people.users.${user0}.sshKeys; + services = { + firefly-iii = { + enable = true; + enableNginx = false; + poolConfig = { + "listen.owner" = config.services.caddy.user; + "pm" = "dynamic"; + "pm.max_children" = 32; + "pm.start_servers" = 2; + "pm.min_spare_servers" = 2; + "pm.max_spare_servers" = 4; + "pm.max_requests" = 500; + }; + settings = { + APP_URL = "https://${host}"; + APP_KEY_FILE = "/etc/firefly-secrets/pass"; + DB_PASSWORD_FILE = "/etc/firefly-secrets/data"; + DB_CONNECTION = "pgsql"; + DB_HOST = "/run/postgresql"; + DB_DATABASE = "firefly-iii"; + DB_USERNAME = "firefly-iii"; + MAIL_MAILER = smtpCfg.name; + MAIL_HOST = smtpCfg.hostname; + MAIL_PORT = smtpCfg.ports.port0; + MAIL_FROM = smtpCfg.email.address0; + MAIL_USERNAME = smtpCfg.email.address0; + MAIL_PASSWORD_FILE = "/etc/firefly-secrets/smtp"; + MAIL_ENCRYPTION = "tls"; + SITE_OWNER = owner; + }; + }; + phpfpm.pools.firefly-iii.phpEnv = { + TRUSTED_PROXIES = "*"; + APP_URL = "https://${host}"; + }; + firefly-iii-data-importer = { + enable = true; + }; + caddy = { + enable = true; + virtualHosts.":80" = { + extraConfig = '' + root * ${config.services.firefly-iii.package}/public + file_server + encode gzip + php_fastcgi unix//run/phpfpm/firefly-iii.sock { + env HTTPS {http.request.header.X-Forwarded-Proto} + env HTTP_X_FORWARDED_PROTO {http.request.header.X-Forwarded-Proto} + } + ''; + }; + }; + postgresql = { + enable = true; + ensureDatabases = [ "firefly-iii" ]; + ensureUsers = [ + { + name = "firefly-iii"; + ensureDBOwnership = true; + } + ]; + }; + + openssh = { + enable = true; + settings = { + PasswordAuthentication = false; + PermitRootLogin = "prohibit-password"; + }; + }; + }; + networking.firewall.allowedTCPPorts = [ + 22 + 587 + 8084 + 8081 + ]; + systemd = { + services = { + caddy = { + after = [ "phpfpm-firefly-iii.service" ]; + requires = [ "phpfpm-firefly-iii.service" ]; + }; + fix-secrets-permissions = { + description = "Fix secrets permissions for firefly-iii"; + wantedBy = [ "multi-user.target" ]; + before = [ + "firefly-iii-setup.service" + "phpfpm-firefly-iii.service" + ]; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + }; + script = '' + mkdir -p /etc/firefly-secrets + cp /run/secrets/${user}-pass /etc/firefly-secrets/${user}-pass + cp /run/secrets/${user}-data /etc/firefly-secrets/${user}-data + cp /run/secrets/${user}-smtp /etc/firefly-secrets/${user}-smtp + chmod 755 /etc/firefly-secrets + chmod 644 /etc/firefly-secrets/* + ''; + }; + systemd-networkd.wantedBy = [ "multi-user.target" ]; + }; + network = { + enable = true; + networks."20-lan" = { + matchConfig.Name = "enp0s5"; + addresses = [ + { Address = "${ip}/24"; } + ]; + routes = [ + { + Destination = "0.0.0.0/0"; + Gateway = "192.168.50.1"; + } + ]; + dns = [ + "1.1.1.1" + "8.8.8.8" + ]; + }; + }; + tmpfiles.rules = [ + "d /var/lib/${serviceCfg.name} 0755 ${serviceCfg.name} ${serviceCfg.name} -" + ]; + }; + microvm = { + vcpu = 1; + mem = 512; + hypervisor = "qemu"; + interfaces = [ + { + type = "tap"; + id = "vm-ff-${user}"; + mac = mac; + } + { + type = "user"; + id = "vmuser-firefly"; + mac = userMac; + } + ]; + forwardPorts = [ + { + from = "host"; + host.port = ssh; + guest.port = 22; + } + ]; + shares = [ + { + mountPoint = "/nix/.ro-store"; + proto = "virtiofs"; + source = "/nix/store"; + tag = "read_only_nix_store"; + } + { + mountPoint = "/var/lib/${serviceCfg.name}"; + proto = "virtiofs"; + source = "${mnt}/${serviceCfg.name}/config"; + tag = "${serviceCfg.name}_${user}_config"; + } + { + mountPoint = "/var/lib/postgresql"; + proto = "virtiofs"; + source = "${mnt}/${serviceCfg.name}/data"; + tag = "${serviceCfg.name}_${user}_data"; + } + { + mountPoint = "/run/secrets"; + proto = "virtiofs"; + source = "/run/secrets/${serviceCfg.name}"; + tag = "host_secrets"; + } + ]; + }; + }; + }; + }; + + systemd.tmpfiles.rules = [ + "d ${mnt}/${serviceCfg.name} 0751 microvm wheel - -" + "d ${mnt}/${serviceCfg.name}/config 0751 microvm wheel - -" + "d ${mnt}/${serviceCfg.name}/data 0751 microvm wheel - -" + ]; + + sops = { + secrets = builtins.listToAttrs ( + map + (secret: { + name = "${serviceCfg.name}/${user}-${secret}"; + value = { + owner = "root"; + group = "root"; + mode = "0644"; + }; + }) + [ + "pass" + "data" + "smtp" + ] + ); + }; + }; +} diff --git a/modules/nixos/nas/guests/firefly-iii/default.nix b/modules/nixos/nas/guests/firefly-iii/default.nix new file mode 100644 index 0000000..ca03f07 --- /dev/null +++ b/modules/nixos/nas/guests/firefly-iii/default.nix @@ -0,0 +1,53 @@ +{ + config, + flake, + pkgs, + nasHelpers, + ... +}: +let + inherit (import ./config { inherit config flake pkgs; }) fireflyVM; + inherit (nasHelpers) ipAddress guestPath firefly; + inherit (flake.config.people) user0; + inherit (flake.config.people.users.${user0}) email; + inherit (flake.config.services) instances; + id0 = builtins.toString firefly.id0; + id1 = builtins.toString firefly.id1; + id2 = builtins.toString firefly.id2; + + fireflyNick = fireflyVM { + user = user0; + ip = ipAddress id0; + mac = "02:00:00:00:${id0}:${id0}"; + userMac = "02:00:00:00:00:${id0}"; + ssh = firefly.ssh0; + host = instances.firefly-iii.domains.url0; + mnt = guestPath user0; + owner = email.address2; + }; + + # fireflyStacie = fireflyVM { + # user = "stacie"; + # ip = ipAddress (id1); + # mac = "02:00:00:00:${id1}:${id1}"; + # userMac = "02:00:00:00:00:${id1}"; + # ssh = fireflyEris.ssh1; + # host = ""; + # mnt = guestPath "stacie"; + # owner = ""; + # }; + + # fireflyGarnet = fireflyVM { + # user = "garnet"; + # ip = ipAddress (id2); + # mac = "02:00:00:00:${id2}:${id2}"; + # userMac = "02:00:00:00:00:${id2}"; + # ssh = fireflyEris.ssh2; + # mnt = guestPath "garnet"; + # host = ""; + # owner = ""; + # }; + +in +fireflyNick +# // fireflyStacie // fireflyGarnet diff --git a/modules/nixos/nas/guests/minecraft/config/default.nix b/modules/nixos/nas/guests/minecraft/config/default.nix new file mode 100644 index 0000000..2ee33ea --- /dev/null +++ b/modules/nixos/nas/guests/minecraft/config/default.nix @@ -0,0 +1,162 @@ +{ + flake, + ... +}: +let + inherit (flake.config.people) user0; + serviceCfg = { + name = "minecraft"; + }; +in +{ + minecraftVM = + { + user, + ip, + mac, + userMac, + ssh, + port, + mnt, + config, + whitelist, + worldNumber, + }: + { + microvm.vms = { + "${serviceCfg.name}-${user}" = { + autostart = true; + restartIfChanged = true; + config = { + system.stateVersion = "24.05"; + time.timeZone = "America/Winnipeg"; + users.users.root.openssh.authorizedKeys.keys = flake.config.people.users.${user0}.sshKeys; + services = { + minecraft-server = { + enable = true; + eula = true; + openFirewall = true; + declarative = true; + serverProperties = { + "rcon.password" = "/etc/${serviceCfg.name}-secrets/world${worldNumber}"; + server-port = port; + } + // config; + whitelist = whitelist; + }; + openssh = { + enable = true; + settings = { + PasswordAuthentication = false; + PermitRootLogin = "prohibit-password"; + }; + }; + }; + networking.firewall.allowedTCPPorts = [ + 22 + port + ]; + systemd = { + services = { + "${serviceCfg.name}-copy-secrets" = { + description = "Copy secrets from virtiofs to local filesystem"; + before = [ "minecraft-server.service" ]; + requiredBy = [ "minecraft-server.service" ]; + + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + }; + script = '' + mkdir -p /etc/${serviceCfg.name}-secrets + cp /run/secrets/${user}-world${worldNumber} /etc/${serviceCfg.name}-secrets/${user}-world${worldNumber} + chmod 755 /etc/${serviceCfg.name}-secrets + chmod 644 /etc/${serviceCfg.name}-secrets/* + ''; + }; + systemd-networkd.wantedBy = [ "multi-user.target" ]; + }; + network = { + enable = true; + networks."20-lan" = { + matchConfig.Name = "enp0s5"; + addresses = [ + { Address = "${ip}/24"; } + ]; + routes = [ + { + Destination = "0.0.0.0/0"; + Gateway = "192.168.50.1"; + } + ]; + dns = [ + "1.1.1.1" + "8.8.8.8" + ]; + }; + }; + tmpfiles.rules = [ + "d /var/lib/${serviceCfg.name} 0755 ${serviceCfg.name} ${serviceCfg.name} -" + ]; + }; + microvm = { + vcpu = 4; + mem = 1024 * 4; + hypervisor = "qemu"; + interfaces = [ + { + type = "tap"; + id = "vm-mc${worldNumber}-${user}"; + mac = mac; + } + { + type = "user"; + id = "vmuser-craft"; + mac = userMac; + } + ]; + forwardPorts = [ + { + from = "host"; + host.port = ssh; + guest.port = 22; + } + ]; + shares = [ + { + mountPoint = "/nix/.ro-store"; + proto = "virtiofs"; + source = "/nix/store"; + tag = "read_only_nix_store"; + } + { + mountPoint = "/var/lib/${serviceCfg.name}"; + proto = "virtiofs"; + source = "${mnt}/${serviceCfg.name}/world${worldNumber}"; + tag = "${serviceCfg.name}_${user}_data"; + } + { + mountPoint = "/run/secrets"; + proto = "virtiofs"; + source = "/run/secrets/${serviceCfg.name}"; + tag = "host_secrets"; + } + ]; + }; + }; + }; + }; + networking.firewall.allowedTCPPorts = [ port ]; + + systemd.tmpfiles.rules = [ + "d ${mnt}/${serviceCfg.name} 0751 microvm wheel - -" + ]; + + sops.secrets = { + "${serviceCfg.name}/${user}-world${worldNumber}" = { + owner = "root"; + mode = "0600"; + }; + }; + }; +} diff --git a/modules/nixos/nas/guests/minecraft/default.nix b/modules/nixos/nas/guests/minecraft/default.nix new file mode 100644 index 0000000..2283125 --- /dev/null +++ b/modules/nixos/nas/guests/minecraft/default.nix @@ -0,0 +1,96 @@ +{ flake, pkgs, ... }: +let + inherit (import ./config { inherit flake pkgs; }) minecraftVM; + inherit (import ../../lib.generalHelpers) ipAddress; + inherit (import ../../lib.ceresHelpers) mntPath minecraft; + inherit (flake.config.people) user0; + id0 = builtins.toString minecraft.id0; + id1 = builtins.toString minecraft.id1; + id2 = builtins.toString minecraft.id2; + + minecraftNick01 = minecraftVM { + user = user0; + ip = ipAddress id0; + mac = "02:00:00:00:${id0}:${id0}"; + userMac = "02:00:00:00:00:${id0}"; + ssh = minecraft.ssh0; + port = 43000; + mnt = mntPath user0; + worldNumber = "01"; + config = { + allow-flight = false; + allow-nether = true; + difficulty = 2; + enable-command-block = false; + enable-rcon = true; + enable-status = true; + force-gamemode = true; + gamemode = 0; + generate-structures = true; + hardcore = false; + hide-online-players = false; + level-name = "Brix on Nix"; + level-seed = "9064150133272194"; + max-players = 10; + max-world-size = 64000000; + motd = "A cool Minecraft server powered by NixOS"; + online-mode = true; + pvp = true; + spawn-animals = true; + spawn-monsters = true; + spawn-npcs = true; + spawn-protection = 16; + view-distance = 32; + white-list = true; + }; + whitelist = { + Hefty_Chungus = "b75a9816-d408-4c54-b226-385b59ea1cb3"; + Hefty_Chungus_Jr = "c3bf8cac-e953-4ea4-ae5f-7acb92a51a85"; + EclipseMoon01 = "adef4af7-d8c6-4627-b492-e990ea1bb993"; + Fallaryn = "d8baa117-ab58-4b07-92a5-48fb1978eb49"; + }; + }; + + minecraftNick02 = minecraftVM { + user = user0; + ip = ipAddress id1; + mac = "02:00:00:00:${id1}:${id1}"; + userMac = "02:00:00:00:00:${id1}"; + ssh = minecraft.ssh1; + port = 43001; + mnt = mntPath user0; + worldNumber = "02"; + config = { + allow-flight = false; + allow-nether = true; + difficulty = 2; + enable-command-block = false; + enable-rcon = true; + enable-status = true; + force-gamemode = true; + gamemode = 0; + generate-structures = true; + hardcore = false; + hide-online-players = false; + level-name = "Cuddle Cubes"; + level-seed = "-2332803749585407299"; + max-players = 10; + max-world-size = 64000000; + motd = "A cool Minecraft server powered by NixOS"; + online-mode = true; + pvp = true; + spawn-animals = true; + spawn-monsters = true; + spawn-npcs = true; + spawn-protection = 16; + view-distance = 32; + white-list = true; + }; + whitelist = { + Hefty_Chungus = "b75a9816-d408-4c54-b226-385b59ea1cb3"; + Fallaryn = "d8baa117-ab58-4b07-92a5-48fb1978eb49"; + }; + }; + +in +minecraftNick01 // minecraftNick02 diff --git a/modules/nixos/nas/onlyoffice/default.nix b/modules/nixos/nas/guests/onlyoffice/config/default.nix similarity index 100% rename from modules/nixos/nas/onlyoffice/default.nix rename to modules/nixos/nas/guests/onlyoffice/config/default.nix diff --git a/modules/nixos/nas/guests/onlyoffice/default.nix b/modules/nixos/nas/guests/onlyoffice/default.nix new file mode 100644 index 0000000..0db3279 --- /dev/null +++ b/modules/nixos/nas/guests/onlyoffice/default.nix @@ -0,0 +1,3 @@ +{ + +} diff --git a/modules/nixos/nas/opencloud/config/default.nix b/modules/nixos/nas/guests/opencloud/config/default.nix similarity index 92% rename from modules/nixos/nas/opencloud/config/default.nix rename to modules/nixos/nas/guests/opencloud/config/default.nix index ef809cd..910bee7 100644 --- a/modules/nixos/nas/opencloud/config/default.nix +++ b/modules/nixos/nas/guests/opencloud/config/default.nix @@ -17,6 +17,7 @@ in mac, userMac, ssh, + mnt, host, }: { @@ -145,13 +146,13 @@ in { mountPoint = "/var/lib/${serviceCfg.name}"; proto = "virtiofs"; - source = "/mnt/storage/users/${user}/guests/${serviceCfg.name}/data"; + source = "${mnt}/${serviceCfg.name}/data"; tag = "${serviceCfg.name}_${user}_data"; } { mountPoint = "/etc/${serviceCfg.name}"; proto = "virtiofs"; - source = "/mnt/storage/users/${user}/guests/${serviceCfg.name}/config"; + source = "${mnt}/${serviceCfg.name}/config"; tag = "${serviceCfg.name}_${user}_config"; } { @@ -172,9 +173,9 @@ in }; }; systemd.tmpfiles.rules = [ - "d /mnt/storage/users/${user}/guests/${serviceCfg.name} 0751 microvm wheel - -" - "d /mnt/storage/users/${user}/guests/${serviceCfg.name}/config 0751 microvm wheel - -" - "d /mnt/storage/users/${user}/guests/${serviceCfg.name}/data 0751 microvm wheel - -" + "d ${mnt}/${serviceCfg.name} 0751 microvm wheel - -" + "d ${mnt}/${serviceCfg.name}/config 0751 microvm wheel - -" + "d ${mnt}/${serviceCfg.name}/data 0751 microvm wheel - -" ]; sops.secrets = { "${serviceCfg.name}/${user}-env" = { diff --git a/modules/nixos/nas/guests/opencloud/default.nix b/modules/nixos/nas/guests/opencloud/default.nix new file mode 100644 index 0000000..25ba71b --- /dev/null +++ b/modules/nixos/nas/guests/opencloud/default.nix @@ -0,0 +1,48 @@ +{ + flake, + pkgs, + nasHelpers, + ... +}: +let + inherit (import ./config { inherit flake pkgs; }) opencloudVM; + inherit (flake.config.people) user0; + inherit (flake.config.services) instances; + inherit (nasHelpers) ipAddress guestPath opencloud; + id0 = builtins.toString opencloud.id0; + id1 = builtins.toString opencloud.id1; + id2 = builtins.toString opencloud.id2; + + opencloudNick = opencloudVM { + user = user0; + ip = ipAddress id0; + mac = "02:00:00:00:${id0}:${id0}"; + userMac = "02:00:00:00:00:${id0}"; + ssh = opencloud.ssh0; + mnt = guestPath user0; + host = instances.opencloud0.domains.url0; + }; + + # opencloudStacie = opencloudVM { + # user = "stacie"; + # ip = ipAddress id1; + # mac = "02:00:00:00:${id1}:${id1}"; + # userMac = "02:00:00:00:00:${id1}"; + # ssh = opencloud.ssh1; + # mnt = guestPath "stacie"; + # host = ""; + # }; + + # opencloudGarnet = opencloudVM { + # user = "garnet"; + # ip = ipAddress id2; + # mac = "02:00:00:00:${id2}:${id2}"; + # userMac = "02:00:00:00:00:${id2}"; + # ssh = opencloud.ssh2; + # mnt = guestPath "garnet"; + # host = ""; + # }; + +in +opencloudNick +# // opencloudStacie // opencloudGarnet diff --git a/modules/nixos/nas/photoprism/config/default.nix b/modules/nixos/nas/guests/photoprism/config/default.nix similarity index 86% rename from modules/nixos/nas/photoprism/config/default.nix rename to modules/nixos/nas/guests/photoprism/config/default.nix index a8f7c20..327b885 100644 --- a/modules/nixos/nas/photoprism/config/default.nix +++ b/modules/nixos/nas/guests/photoprism/config/default.nix @@ -17,6 +17,8 @@ in mac, userMac, ssh, + mnt, + data, }: { microvm.vms = { @@ -93,12 +95,6 @@ in ]; }; }; - - # tmpfiles.rules = [ - # "d /var/lib/${serviceCfg.name} 0755 ${serviceCfg.name} ${serviceCfg.name} -" - # "d /var/lib/${serviceCfg.name}-media 0755 ${serviceCfg.name} ${serviceCfg.name} -" - # "d /var/lib/${serviceCfg.name}-media/photos 0755 ${serviceCfg.name} ${serviceCfg.name} -" - # ]; }; microvm = { @@ -136,13 +132,13 @@ in { mountPoint = "/var/lib/${serviceCfg.name}"; proto = "virtiofs"; - source = "/mnt/storage/users/${user}/guests/${serviceCfg.name}"; + source = "${mnt}/${serviceCfg.name}"; tag = "${serviceCfg.name}_${user}_data"; } { mountPoint = "/var/lib/${serviceCfg.name}-media"; proto = "virtiofs"; - source = "/mnt/storage/users/${user}/home/media"; + source = data; tag = "${serviceCfg.name}_${user}_media"; } { @@ -158,8 +154,8 @@ in }; systemd.tmpfiles.rules = [ - "d /mnt/storage/users/${user}/guests/${serviceCfg.name} 0751 microvm wheel - -" - "d /mnt/storage/users/${user}/home/media/photos 0751 microvm wheel - -" + "d ${mnt}/${serviceCfg.name} 0751 microvm wheel - -" + "d ${data}/photos 0751 microvm wheel - -" ]; sops.secrets = { diff --git a/modules/nixos/nas/guests/photoprism/default.nix b/modules/nixos/nas/guests/photoprism/default.nix new file mode 100644 index 0000000..0f1c470 --- /dev/null +++ b/modules/nixos/nas/guests/photoprism/default.nix @@ -0,0 +1,52 @@ +{ + flake, + lib, + nasHelpers, + ... +}: +let + inherit (import ./config { inherit flake lib; }) photoprismVM; + inherit (nasHelpers) + ipAddress + guestPath + mediaPath + photoprism + ; + inherit (flake.config.people) user0; + id0 = builtins.toString photoprism.id0; + id1 = builtins.toString photoprism.id1; + id2 = builtins.toString photoprism.id2; + + photoprismNick = photoprismVM { + user = user0; + ip = ipAddress id0; + mac = "02:00:00:00:${id0}:${id0}"; + userMac = "02:00:00:00:00:${id0}"; + ssh = photoprism.ssh0; + mnt = guestPath user0; + data = mediaPath user0; + }; + + # photoprismStacie = photoprismVM { + # user = "stacie"; + # ip = ipAddress id1; + # mac = "02:00:00:00:${id1}:${id1}"; + # userMac = "02:00:00:00:00:${id1}"; + # ssh = photoprism.ssh1; + # mnt = guestPath "stacie"; + # data = mediaPath "stacie"; + # }; + + # photoprismGarnet = photoprismVM { + # user = "garnet"; + # ip = ipAddress id2; + # mac = "02:00:00:00:${id2}:${id2}"; + # userMac = "02:00:00:00:00:${id2}"; + # ssh = photoprism.ssh2; + # mnt = guestPath "garnet"; + # data = mediaPath "stacie"; + # }; + +in +photoprismNick +# // photoprismStacie // photoprismGarnet diff --git a/modules/nixos/nas/syncthing/config/default.nix b/modules/nixos/nas/guests/syncthing/config/default.nix similarity index 58% rename from modules/nixos/nas/syncthing/config/default.nix rename to modules/nixos/nas/guests/syncthing/config/default.nix index fe62290..5048be1 100644 --- a/modules/nixos/nas/syncthing/config/default.nix +++ b/modules/nixos/nas/guests/syncthing/config/default.nix @@ -15,8 +15,11 @@ in mac, userMac, ssh, - syncID, - deviceIP, + mnt, + folders, + devices, + tmp, + mounts, }: { microvm.vms = { @@ -36,42 +39,8 @@ in systemService = true; guiAddress = "0.0.0.0:${toString serviceCfg.ports.port0}"; settings = { - folders = { - docs = { - enable = true; - id = "docs"; - path = "/var/lib/${serviceCfg.name}/docs"; - devices = [ - "${user}Phone" - ]; - }; - media = { - enable = true; - id = "media"; - path = "/var/lib/${serviceCfg.name}/media"; - devices = [ - "${user}Phone" - ]; - }; - misc = { - enable = true; - id = "misc"; - path = "/var/lib/${serviceCfg.name}/misc"; - devices = [ - "${user}Phone" - ]; - }; - }; - devices = { - "${user}Phone" = { - autoAcceptFolders = true; - name = "${user}Phone"; - addresses = [ - "tcp://${deviceIP}:${toString serviceCfg.ports.port2}" - ]; - id = syncID; - }; - }; + folders = folders; + devices = devices; }; }; @@ -119,13 +88,9 @@ in tmpfiles.rules = [ "d /var/lib/${serviceCfg.name} 0755 ${serviceCfg.name} ${serviceCfg.name} -" - "d /var/lib/${serviceCfg.name}/docs 0755 ${serviceCfg.name} ${serviceCfg.name} -" - "d /var/lib/${serviceCfg.name}/media 0755 ${serviceCfg.name} ${serviceCfg.name} -" - "d /var/lib/${serviceCfg.name}/misc 0755 ${serviceCfg.name} ${serviceCfg.name} -" - ]; - + ] + ++ tmp; }; - microvm = { vcpu = 1; mem = 512; @@ -159,41 +124,24 @@ in { mountPoint = "/var/lib/${serviceCfg.name}"; proto = "virtiofs"; - source = "/mnt/storage/users/${user}/guests/${serviceCfg.name}"; + source = "${mnt}/${serviceCfg.name}"; tag = "${serviceCfg.name}_${user}_data"; } - { - mountPoint = "/var/lib/${serviceCfg.name}/docs"; - proto = "virtiofs"; - source = "/mnt/storage/users/${user}/home/docs"; - tag = "${serviceCfg.name}_${user}_docs"; - } - { - mountPoint = "/var/lib/${serviceCfg.name}/media"; - proto = "virtiofs"; - source = "/mnt/storage/users/${user}/home/media"; - tag = "${serviceCfg.name}_${user}_media"; - } - { - mountPoint = "/var/lib/${serviceCfg.name}/misc"; - proto = "virtiofs"; - source = "/mnt/storage/users/${user}/home/misc"; - tag = "${serviceCfg.name}_${user}_misc"; - } { mountPoint = "/run/secrets"; proto = "virtiofs"; source = "/run/secrets/${serviceCfg.name}"; tag = "host_secrets"; } - ]; + ] + ++ mounts; }; }; }; }; systemd.tmpfiles.rules = [ - "d /mnt/storage/users/${user}/guests/${serviceCfg.name} 0751 microvm wheel - -" + "d ${mnt}/${serviceCfg.name} 0751 microvm wheel - -" ]; }; } diff --git a/modules/nixos/nas/guests/syncthing/default.nix b/modules/nixos/nas/guests/syncthing/default.nix new file mode 100755 index 0000000..1c28dc7 --- /dev/null +++ b/modules/nixos/nas/guests/syncthing/default.nix @@ -0,0 +1,123 @@ +{ flake, nasHelpers, ... }: +let + inherit (import ./config { inherit flake; }) syncthingVM; + inherit (flake.config.services) instances; + inherit (flake.config.people) user0; + inherit (nasHelpers) + ipAddress + guestPath + docsPath + mediaPath + miscPath + syncthing + ; + serviceCfg = instances.syncthing; + id0 = builtins.toString syncthing.id0; + id1 = builtins.toString syncthing.id1; + id2 = builtins.toString syncthing.id2; + + foldersHelper = user: { + docs = { + enable = true; + id = "docs"; + path = "/var/lib/${serviceCfg.name}/docs"; + devices = [ + "${user}Phone" + ]; + }; + media = { + enable = true; + id = "media"; + path = "/var/lib/${serviceCfg.name}/media"; + devices = [ + "${user}Phone" + ]; + }; + misc = { + enable = true; + id = "misc"; + path = "/var/lib/${serviceCfg.name}/misc"; + devices = [ + "${user}Phone" + ]; + }; + }; + + devicesHelper = user: syncID: device: deviceIP: { + "${user}${device}" = { + autoAcceptFolders = true; + name = "${user}${device}"; + addresses = [ + "tcp://${deviceIP}:${toString serviceCfg.ports.port2}" + ]; + id = syncID; + }; + }; + + mountsHelper = user: [ + { + mountPoint = "/var/lib/${serviceCfg.name}/docs"; + proto = "virtiofs"; + source = docsPath user; + tag = "${serviceCfg.name}_${user}_docs"; + } + { + mountPoint = "/var/lib/${serviceCfg.name}/media"; + proto = "virtiofs"; + source = mediaPath user; + tag = "${serviceCfg.name}_${user}_media"; + } + { + mountPoint = "/var/lib/${serviceCfg.name}/misc"; + proto = "virtiofs"; + source = miscPath user; + tag = "${serviceCfg.name}_${user}_misc"; + } + ]; + + tmpRules = [ + "d /var/lib/${serviceCfg.name}/docs 0755 ${serviceCfg.name} ${serviceCfg.name} -" + "d /var/lib/${serviceCfg.name}/media 0755 ${serviceCfg.name} ${serviceCfg.name} -" + "d /var/lib/${serviceCfg.name}/misc 0755 ${serviceCfg.name} ${serviceCfg.name} -" + ]; + + syncthingNick = + let + phoneID = "OALKHLZ-OODUWVX-PAC2LI7-UMZMSZO-FELLRCD-RS4DHJS-PVA5YQK-WTFXXQI"; + in + syncthingVM { + user = user0; + ip = ipAddress id0; + mac = "02:00:00:00:${id0}:${id0}"; + userMac = "02:00:00:00:00:${id0}"; + ssh = syncthing.ssh0; + mnt = guestPath user0; + folders = foldersHelper user0; + devices = devicesHelper user0 phoneID "Phone" "192.168.50.8"; + tmp = tmpRules; + mounts = mountsHelper user0; + }; + + # syncthingStacie = syncthingVM { + # user = "stacie"; + # ip = ipAddress id0; + # mac = "02:00:00:00:${id0}:${id0}"; + # userMac = "02:00:00:00:00:${id0}"; + # ssh = syncthing.ssh0; + # syncID = ""; + # deviceIP = ""; + # }; + + # syncthingGarnet = syncthingVM { + # user = "garnet"; + # ip = ipAddress id0; + # mac = "02:00:00:00:${id0}:${id0}"; + # userMac = "02:00:00:00:00:${id0}"; + # ssh = syncthing.ssh0; + # syncID = ""; + # deviceIP = ""; + # }; + +in +syncthingNick +# // syncthingStacie // syncthingGarnet diff --git a/modules/nixos/nas/guests/vaultwarden/config/default.nix b/modules/nixos/nas/guests/vaultwarden/config/default.nix new file mode 100644 index 0000000..2f28915 --- /dev/null +++ b/modules/nixos/nas/guests/vaultwarden/config/default.nix @@ -0,0 +1,166 @@ +{ + flake, + ... +}: +let + inherit (flake.config.people) user0; + inherit (flake.config.services) instances; + serviceCfg = instances.vaultwarden; + smtpCfg = instances.smtp; + +in +{ + vaultwardenVM = + { + user, + ip, + mac, + userMac, + ssh, + host, + mnt, + }: + { + microvm.vms = { + "${serviceCfg.name}-${user}" = { + autostart = true; + restartIfChanged = true; + config = { + system.stateVersion = "24.05"; + time.timeZone = "America/Winnipeg"; + users.users.root.openssh.authorizedKeys.keys = flake.config.people.users.${user0}.sshKeys; + services = { + vaultwarden = { + enable = true; + dbBackend = "sqlite"; + config = { + # Domain Configuration + DOMAIN = "https://${host}"; + + # Email Configuration + SMTP_AUTH_MECHANISM = "Plain"; + SMTP_EMBED_IMAGES = true; + SMTP_FROM = serviceCfg.email.address0; + SMTP_FROM_NAME = serviceCfg.label; + SMTP_HOST = smtpCfg.hostname; + SMTP_PORT = smtpCfg.ports.port0; + SMTP_USERNAME = smtpCfg.email.address0; + SMTP_SECURITY = "starttls"; + + # Security Configuration + DISABLE_ADMIN_TOKEN = false; + + # Event and Backup Management + EVENTS_DAYS_RETAIN = 90; + + # User Features + SENDS_ALLOWED = true; + SIGNUPS_VERIFY = true; + WEB_VAULT_ENABLED = true; + + # Rocket (Web Server) Settings + ROCKET_ADDRESS = "0.0.0.0"; + ROCKET_PORT = serviceCfg.ports.port0; + }; + + # Environment file with secrets (mounted from host) + environmentFile = "/run/secrets/${user}-env"; + }; + + openssh = { + enable = true; + settings = { + PasswordAuthentication = false; + PermitRootLogin = "prohibit-password"; + }; + }; + }; + networking.firewall.allowedTCPPorts = [ + 22 + 587 + ]; + systemd = { + services = { + systemd-networkd.wantedBy = [ "multi-user.target" ]; + }; + network = { + enable = true; + networks."20-lan" = { + matchConfig.Name = "enp0s5"; + addresses = [ + { Address = "${ip}/24"; } + ]; + routes = [ + { + Destination = "0.0.0.0/0"; + Gateway = "192.168.50.1"; + } + ]; + dns = [ + "1.1.1.1" + "8.8.8.8" + ]; + }; + }; + tmpfiles.rules = [ + "d /var/lib/${serviceCfg.name} 0755 ${serviceCfg.name} ${serviceCfg.name} -" + ]; + }; + microvm = { + vcpu = 1; + mem = 1024; + hypervisor = "qemu"; + interfaces = [ + { + type = "tap"; + id = "vm-vw-${user}"; + mac = mac; + } + { + type = "user"; + id = "vmuser-vault"; + mac = userMac; + } + ]; + forwardPorts = [ + { + from = "host"; + host.port = ssh; + guest.port = 22; + } + ]; + shares = [ + { + mountPoint = "/nix/.ro-store"; + proto = "virtiofs"; + source = "/nix/store"; + tag = "read_only_nix_store"; + } + { + mountPoint = "/var/lib/bitwarden_rs"; + proto = "virtiofs"; + source = "${mnt}/${serviceCfg.name}"; + tag = "${serviceCfg.name}_${user}_data"; + } + { + mountPoint = "/run/secrets"; + proto = "virtiofs"; + source = "/run/secrets/${serviceCfg.name}"; + tag = "host_secrets"; + } + ]; + }; + }; + }; + }; + systemd.tmpfiles.rules = [ + "d ${mnt}/${serviceCfg.name} 0751 microvm wheel - -" + ]; + sops.secrets = { + "${serviceCfg.name}/${user}-env" = { + owner = "root"; + mode = "0600"; + }; + }; + }; +} diff --git a/modules/nixos/nas/guests/vaultwarden/default.nix b/modules/nixos/nas/guests/vaultwarden/default.nix new file mode 100644 index 0000000..d58c522 --- /dev/null +++ b/modules/nixos/nas/guests/vaultwarden/default.nix @@ -0,0 +1,42 @@ +{ flake, nasHelpers, ... }: +let + inherit (import ./config { inherit flake; }) vaultwardenVM; + inherit (flake.config.people) user0; + inherit (nasHelpers) ipAddress guestPath vaultwarden; + id0 = builtins.toString vaultwarden.id0; + id1 = builtins.toString vaultwarden.id1; + id2 = builtins.toString vaultwarden.id2; + + vaultwardenNick = vaultwardenVM { + user = user0; + ip = ipAddress id0; + mac = "02:00:00:00:${id0}:${id0}"; + userMac = "02:00:00:00:00:${id0}"; + ssh = vaultwarden.ssh0; + mnt = guestPath user0; + host = ""; + }; + + # vaultwardenStacie = vaultwardenVM { + # user = "stacie"; + # ip = ipAddress id1; + # mac = "02:00:00:00:${id1}:${id1}"; + # userMac = "02:00:00:00:00:${id1}"; + # ssh = vaultwarden.ssh1; + # mnt = guestPath "stacie"; + # host = ""; + # }; + + # vaultwardenGarnet = vaultwardenVM { + # user = "garnet"; + # ip = ipAddress id2; + # mac = "02:00:00:00:${id2}:${id2}"; + # userMac = "02:00:00:00:00:${id2}"; + # ssh = vaultwarden.ssh2; + # mnt = guestPath "garnet"; + # host = ""; + # }; + +in +vaultwardenNick +# // vaultwardenStacie // vaultwardenGarnet diff --git a/modules/nixos/nas/opencloud/default.nix b/modules/nixos/nas/opencloud/default.nix deleted file mode 100644 index 636ced6..0000000 --- a/modules/nixos/nas/opencloud/default.nix +++ /dev/null @@ -1,35 +0,0 @@ -{ flake, pkgs, ... }: -let - inherit (import ./config { inherit flake pkgs; }) opencloudVM; - inherit (flake.config.people) user0; - - opencloudNick = opencloudVM { - user = user0; - ip = "192.168.50.67"; - mac = "02:00:00:00:57:67"; - userMac = "02:00:00:00:00:67"; - ssh = 2507; - host = ""; - }; - - # opencloudStacie = opencloudVM { - # user = "stacie"; - # ip = "192.168.50.68"; - # mac = "02:00:00:00:58:68"; - # userMac = "02:00:00:00:00:68"; - # ssh = 2508; - # host = ""; - # }; - - # opencloudGarnet = opencloudVM { - # user = "garnet"; - # ip = "192.168.50.69"; - # mac = "02:00:00:00:59:69"; - # userMac = "02:00:00:00:00:69"; - # ssh = 2509; - # host = ""; - # }; - -in -opencloudNick -# // opencloudStacie // opencloudGarnet diff --git a/modules/nixos/nas/photoprism/default.nix b/modules/nixos/nas/photoprism/default.nix deleted file mode 100644 index aa53dd2..0000000 --- a/modules/nixos/nas/photoprism/default.nix +++ /dev/null @@ -1,32 +0,0 @@ -{ flake, lib, ... }: -let - inherit (import ./config { inherit flake lib; }) photoprismVM; - inherit (flake.config.people) user0; - - photoprismNick = photoprismVM { - user = user0; - ip = "192.168.50.64"; - mac = "02:00:00:00:54:64"; - userMac = "02:00:00:00:00:64"; - ssh = 2504; - }; - - # photoprismStacie = photoprismVM { - # user = "stacie"; - # ip = "192.168.50.65"; - # mac = "02:00:00:00:55:65"; - # userMac = "02:00:00:00:00:65"; - # ssh = 2505; - # }; - - # photoprismGarnet = photoprismVM { - # user = "garnet"; - # ip = "192.168.50.66"; - # mac = "02:00:00:00:56:66"; - # userMac = "02:00:00:00:00:66"; - # ssh = 2506; - # }; - -in -photoprismNick -# // photoprismStacie // photoprismGarnet diff --git a/modules/nixos/nas/syncthing/default.nix b/modules/nixos/nas/syncthing/default.nix deleted file mode 100755 index 323f246..0000000 --- a/modules/nixos/nas/syncthing/default.nix +++ /dev/null @@ -1,38 +0,0 @@ -{ flake, ... }: -let - inherit (import ./config { inherit flake; }) syncthingVM; - inherit (flake.config.people) user0; - - syncthingNick = syncthingVM { - user = user0; - ip = "192.168.50.61"; - mac = "02:00:00:00:51:61"; - userMac = "02:00:00:00:00:61"; - ssh = 2501; - syncID = "OALKHLZ-OODUWVX-PAC2LI7-UMZMSZO-FELLRCD-RS4DHJS-PVA5YQK-WTFXXQI"; - deviceIP = "192.168.50.8"; - }; - - # syncthingStacie = syncthingVM { - # user = "stacie"; - # ip = "192.168.50.62"; - # mac = "02:00:00:00:52:62"; - # userMac = "02:00:00:00:00:62"; - # ssh = 2502; - # syncID = ""; - # deviceIP = ""; - # }; - - # syncthingGarnet = syncthingVM { - # user = "garnet"; - # ip = "192.168.50.63"; - # mac = "02:00:00:00:53:63"; - # userMac = "02:00:00:00:00:63"; - # ssh = 2503; - # syncID = ""; - # deviceIP = ""; - # }; - -in -syncthingNick -# // syncthingStacie // syncthingGarnet diff --git a/secrets/secrets.yaml b/secrets/secrets.yaml index af1d5af..ededd40 100755 --- a/secrets/secrets.yaml +++ b/secrets/secrets.yaml @@ -27,7 +27,7 @@ minecraft: world0: ENC[AES256_GCM,data:pz7P5g9jRL8KaARfSs2ddmN76ioKSuSv7A==,iv:ZFIhS15BPxHzTW4aPpT7A8R4rxuyNNGjPJXqJXYoBpk=,tag:aymiUs87YR519eZN8Aopyw==,type:str] world1: ENC[AES256_GCM,data:vvMvvGlyrrufdoeiTWYUcKoYSyMtuOyQ2A2xPB0V81IM,iv:gQWuyxqcSTvrgKbhKlu8dZbBj0zqGImyB+W2ZufRyJc=,tag:ykPgGmRAEZl3M3HrEdE5Aw==,type:str] vaultwarden: - env: ENC[AES256_GCM,data:1MzIqnV/PCGNNqKVwhxZfmV92vRQsn3OxuvCXUtKyCmoA2xxD91U3EmMikTqM3EOHYAMHbF66YgQC5JjivbIF06OCeXMMLpGuN8ibCUQq7M6PQ34/LDMZnqynmC3/U0FJglSU7o1KA0=,iv:novSYG6j0l17xogdE5WiS2gNPNAVKeX9lgxe5EohBHk=,tag:w43z7a/MzObvVTQh8AiSTA==,type:str] + nick-env: ENC[AES256_GCM,data:lG7pqpLJ7OsFZhWCJcPnvDxkR4Ob78buazUeLWlRSAPYEv8KarymYduecJNWCZUjUlysoU5YrHaat8tny+Vl2rYdef8oPfqlf7fITofsdmjHhAGUBJEEVQWLyEXqrEebEyeNKZwI+u8=,iv:SNptt0CPcSCTs6AAWLcC+U0/94oQapqmT1K8ZN/bIfM=,tag:2/1A+DwuWOIr0eoJmZTnwA==,type:str] dns: namecheap: ENC[AES256_GCM,data:Afxyf4cHvdnPIXYoPN3viBOzzqUOeRs3YjQ5ugerlnL9H4iSf/iAsxyzHYysOgZ/9xc0OWt6G6A7cEZHW4i82MX1+mLbvWN5ir1iHL73RtesC14=,iv:3XMTQ4TNL7iXPYFLSa+BapSgqILYuM6ZaQLMQZSJ2pc=,tag:PO69wRhCoey+CwPgnOOR6A==,type:str] cloudflare: ENC[AES256_GCM,data:H0ODjZvDZpaicYwM1qX1V05iaiCsJMUo5aIZYVzQ2bGvsVA+nQYKy7i1qCNbG796WmBOvUJOo1XJHsceTyfGB7rQpgs103RA0CXmc9WfvU74tsER+sVbnCxsGrG1kvyZvD80ACsx53s6j9nXkZO2m7uZgdM8LbEEaj/CVOMDg39YWWKwug==,iv:EALcT+2ES7q/4zEwUXDsyrDzSZnUCsYtYZLIU3xNJQs=,tag:RTyPzUpMcrQtDT4UKn4SNw==,type:str] @@ -57,9 +57,9 @@ caddy: wifi: home: ENC[AES256_GCM,data:kjidpmWRBta4EZkLBkDpVtku,iv:8SYK/6LhovjqfhKaAvgsQZj3CiTSjS5BHCDgei91pOI=,tag:RjOHpV92r0T7j7uwXmVsGA==,type:str] firefly-iii: - pass: ENC[AES256_GCM,data:WjHcoTuEzEq9pfw4QoqRjI4jhu5VPEMOXlHL0olg9dqUj4EGa1Shv5T/kIxdRFuao0y3zQ==,iv:4/fmFOxxDLzplsNGpSJMQOeoNviZw2c2pFlB1ZkRu+o=,tag:7TQ2q/kEFDU4tZxPx53ebw==,type:str] - data: ENC[AES256_GCM,data:921LhcRTWVk24eEAQoDMV+RllSP3PbSXCCIDXlQA80Mq,iv:YXEgas77DgdyPTnBZa/ySjcERBIwmdDZJbijeNKNF24=,tag:Wj25wA7tLJ2bZ/faG9DUhg==,type:str] - smtp: ENC[AES256_GCM,data:+e4MiRZ2WOZyWYpMf+By1Eb45ih4TA+svLI2+00yQk82,iv:+52+kJouMwkOSDEaOCA8V80+wT/VzNxgtCkOO68SCdk=,tag:YrtrJAXIhQpsUTEeYvrVwQ==,type:str] + nick-pass: ENC[AES256_GCM,data:98rSX++bVpZDKLIli7LJvD0LOgtu+KlSa6lr24I4KwYznHrgpWbmscePm2S1bmRgW6RPeA==,iv:bu+afc1xl0/sntJRYna7iW5lJb88u05WiSHxAnj/UiI=,tag:N9iZuA92V3kBB1H8E4wEjg==,type:str] + nick-data: ENC[AES256_GCM,data:K6nUu11WInVUE6KIb/PGGbPTX3g/d2VWM2dWxMjWMMCZ,iv:ZqjLh5kKgOed5KAJ9qcrqQnCTH8obc4wflb4EE7rGHc=,tag:A+1W4Y9eTFe+ukFJqgQ79A==,type:str] + nick-smtp: ENC[AES256_GCM,data:oWBPlGwjUZt1/7O+X4PKh1uaAF4nzOhvXJqmdmiIntpi,iv:5LVy5S+46fjX0E3JrZFwuXOpyPycT7iKMVe31zEZL88=,tag:CcFDOpbJTyNCPcOtyX8FMQ==,type:str] torrent: wireguard-pass: ENC[AES256_GCM,data:fNNHuOvaRRpiS7c9n/l6lB0A1J4VboJxIh+hrMrTfjFS2grpgRATLHhjZ/wo,iv:CVZIG3Gq+O1/qPqu0XBH/5XsTpAe9xe52/CtBHaIOPI=,tag:8RfoFjz0Ecmx8O7Bt/90ig==,type:str] qbittorrent-pass: ENC[AES256_GCM,data:W1p7cYWbBNeAtEEL7Tb0pG27TSniqTrNMN6gxFFlli27,iv:seiWOr6V8pyjioBkKKEtCXC17RctDScA37E7uFbnmzk=,tag:KYz92O6XUvJob74LnGlYNg==,type:str] @@ -86,7 +86,7 @@ sops: bXBOa1VSakoyaWxpODJEOU11QUZCaUEK8Ch9Ten3DdrPHF1DTH2qei85AlHUOaLD aNfzakake7ej+MxJYdKEU0bcWofNMKzIlZa2uM10KZSENDP8d8qlig== -----END AGE ENCRYPTED FILE----- - lastmodified: "2025-12-07T07:33:25Z" - mac: ENC[AES256_GCM,data:iVMnQYSBHlTzERNWEIFt4Zhaz2i3CR3NFRacOXqoG6mBJS9OFQvJuDS+AyBDBjft8dTNehPKJ0C/npR7n1R1yhyjyHuCgGGX9mYzMIzNoo6zNoDoGiEdVMbHyRC2fWrSHodI/PWjDHvy0rr3nXh7qIduiFvcth5w+98QjJVQ+wI=,iv:uqjvU/LA6XEuYVC8/k3rWMliFTPyFTHn2dtje3wxThA=,tag:aNQYNRgLktBA6zdnizijJg==,type:str] + lastmodified: "2025-12-08T08:47:33Z" + mac: ENC[AES256_GCM,data:1fQ7q87c3hMVIiHbW8YnCPUxvPtv647MRf//gVX/VKcxHNpO3FGX9jCvXpAh+Y2I0LiNUjZw2Ws9FIraytPMh+3uB7NAnLfCqkR9flL5rBfMLNrujaomFL/bBKCaKc5ruNTHGxF6MQ/s0a5m+lfa1hs9KPqtJnYFLBpyN/RvTQ4=,iv:J9JZlBPqsrspuQ8mgAJ2b8ih+1PATvHDvpI77oTi+yk=,tag:K75aDHyj3ohg+BugfmGqqw==,type:str] unencrypted_suffix: _unencrypted version: 3.11.0