aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKumar Damani <me@kumardamani.net>2026-07-01 04:09:21 +0000
committerKumar Damani <me@kumardamani.net>2026-07-01 04:12:25 +0000
commit02926f70770ceb90cf382da2b54f888ba969f423 (patch)
tree0a7cc1fc1c68ae91ae49070bea5cd3708b875819
parentbc1ad567d2eac46088285ed7d2d688fffc91a82f (diff)
nix based config
-rwxr-xr-x.gitignore3
-rw-r--r--nix/.sops.yaml17
-rw-r--r--nix/README.md30
-rwxr-xr-xnix/deploy.sh50
-rw-r--r--nix/flake.lock48
-rw-r--r--nix/flake.nix40
-rwxr-xr-xnix/generate-keys.sh12
-rw-r--r--nix/per-host/base/configuration.nix67
-rw-r--r--nix/per-host/rproxy-2/configuration.nix190
-rw-r--r--nix/per-host/torrents-2/configuration.nix64
-rw-r--r--nix/secrets/rproxy-2.yaml26
-rw-r--r--nix/secrets/torrents-2.yaml25
12 files changed, 572 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index c55d3b2..c3513ce 100755
--- a/.gitignore
+++ b/.gitignore
@@ -10,5 +10,8 @@ terraform/*.tfvars
ansible/vaultkey
ansible/playbooks/artifacts/
+nix/host-keys
+nix/result
+
.devenv
.direnv
diff --git a/nix/.sops.yaml b/nix/.sops.yaml
new file mode 100644
index 0000000..d03cddc
--- /dev/null
+++ b/nix/.sops.yaml
@@ -0,0 +1,17 @@
+keys:
+ - &admin_me age12teny70e5cm3992z7atx9g9606d4a60dsl8nskzkpp234uelnctq82mqaa
+ - &server_torrents_2 age1cunp9vshd45hlfqdxd4pdvg0qgfllk7mctff65s02wm447xgde7qar7z25
+ - &server_rproxy_2 age1h58rh5q0d7rg984g3e3qfrgwzu3ujzkkcg8f0ls5jlsvdy44f5ls3aywyx
+
+creation_rules:
+ - path_regex: 'secrets/torrents.*\.yaml$'
+ key_groups:
+ - age:
+ - *admin_me
+ - *server_torrents_2
+
+ - path_regex: 'secrets/rproxy.*\.yaml$'
+ key_groups:
+ - age:
+ - *admin_me
+ - *server_rproxy_2
diff --git a/nix/README.md b/nix/README.md
new file mode 100644
index 0000000..08d7305
--- /dev/null
+++ b/nix/README.md
@@ -0,0 +1,30 @@
+Build base image:
+```sh
+nixos-rebuild build-image --image-variant proxmox --flake .#base
+```
+
+Copy base image to a Proxmox node:
+```sh
+scp result/vzdump-qemu-nixos-26.05.20260401.6201e20.vma.zst root@192.168.0.85:/var/lib/vz/dump/
+```
+
+Restore on Proxmox.
+
+Convert to Proxmox Template.
+
+Run TF as usual using clone against the Template.
+
+```sh
+# first time only
+./generate-keys.sh torrents--2
+
+# edit the .sops.yaml to include the host's age key
+
+sops secrets/rproxy-2.yaml
+
+./deploy.sh torrents-2 root
+```
+
+Sources:
+https://github.com/nix-community/nixos-generators
+https://gist.github.com/joshleecreates/e6892ca21b0e6b7c24d96ca2a24bf23e
diff --git a/nix/deploy.sh b/nix/deploy.sh
new file mode 100755
index 0000000..d3ad649
--- /dev/null
+++ b/nix/deploy.sh
@@ -0,0 +1,50 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+HOST="$1"
+FLAKE=".#${HOST}"
+KEY_DIR="./host-keys/${HOST}"
+USER="${2:-root}"
+
+# Validate
+if [ ! -d "$KEY_DIR" ]; then
+ echo "❌ No host key directory found for '${HOST}'"
+ exit 1
+fi
+
+# Validate the per-host secrets file exists
+SECRETS_FILE="secrets/${HOST}.yaml"
+if [ ! -f "$SECRETS_FILE" ]; then
+ echo "❌ No secrets file found at ${SECRETS_FILE}"
+ echo " Run: sops ${SECRETS_FILE}"
+ exit 1
+fi
+
+
+# ---- Compare host key fingerprints and replace if different ----
+LOCAL_FINGERPRINT=$(ssh-keygen -lf "${KEY_DIR}/ssh_host_ed25519_key.pub" 2>/dev/null | awk '{print $2}')
+REMOTE_FINGERPRINT=$(ssh "${USER}@${HOST}" ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub 2>/dev/null | awk '{print $2}')
+
+if [ "$LOCAL_FINGERPRINT" != "$REMOTE_FINGERPRINT" ]; then
+ echo "→ [${HOST}] Host key mismatch! Replacing..."
+ echo " Local: ${LOCAL_FINGERPRINT}"
+ echo " Remote: ${REMOTE_FINGERPRINT}"
+
+ # Copy the pre-generated key to replace the VM's auto-generated one
+ scp "${KEY_DIR}/ssh_host_ed25519_key" "${USER}@${HOST}:/etc/ssh/ssh_host_ed25519_key"
+ scp "${KEY_DIR}/ssh_host_ed25519_key.pub" "${USER}@${HOST}:/etc/ssh/ssh_host_ed25519_key.pub"
+ ssh "${USER}@${HOST}" chmod 600 /etc/ssh/ssh_host_ed25519_key
+ ssh "${USER}@${HOST}" chmod 644 /etc/ssh/ssh_host_ed25519_key.pub
+
+ echo "→ [${HOST}] Key replaced. You may get a WARNING on next SSH (host key changed)."
+ echo " Remove old key with: ssh-keygen -R ${HOST}"
+else
+ echo "→ [${HOST}] Host keys match, no action needed"
+fi
+
+# Deploy
+echo "→ [${HOST}] Deploying with nixos-rebuild..."
+nixos-rebuild switch \
+ --flake "$FLAKE" \
+ --target-host "${USER}@${HOST}" \
+ --sudo
diff --git a/nix/flake.lock b/nix/flake.lock
new file mode 100644
index 0000000..6ff8928
--- /dev/null
+++ b/nix/flake.lock
@@ -0,0 +1,48 @@
+{
+ "nodes": {
+ "nixpkgs": {
+ "locked": {
+ "lastModified": 1775036866,
+ "narHash": "sha256-ZojAnPuCdy657PbTq5V0Y+AHKhZAIwSIT2cb8UgAz/U=",
+ "owner": "nixos",
+ "repo": "nixpkgs",
+ "rev": "6201e203d09599479a3b3450ed24fa81537ebc4e",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nixos",
+ "ref": "nixos-unstable",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "root": {
+ "inputs": {
+ "nixpkgs": "nixpkgs",
+ "sops-nix": "sops-nix"
+ }
+ },
+ "sops-nix": {
+ "inputs": {
+ "nixpkgs": [
+ "nixpkgs"
+ ]
+ },
+ "locked": {
+ "lastModified": 1776771786,
+ "narHash": "sha256-DRFGPfFV6hbrfO9a1PH1FkCi7qR5FgjSqsQGGvk1rdI=",
+ "owner": "Mic92",
+ "repo": "sops-nix",
+ "rev": "bef289e2248991f7afeb95965c82fbcd8ff72598",
+ "type": "github"
+ },
+ "original": {
+ "owner": "Mic92",
+ "repo": "sops-nix",
+ "type": "github"
+ }
+ }
+ },
+ "root": "root",
+ "version": 7
+}
diff --git a/nix/flake.nix b/nix/flake.nix
new file mode 100644
index 0000000..e4cde5f
--- /dev/null
+++ b/nix/flake.nix
@@ -0,0 +1,40 @@
+{
+ description = "NixOS configurations";
+
+ inputs = {
+ nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable";
+ sops-nix = {
+ url = "github:Mic92/sops-nix";
+ inputs.nixpkgs.follows = "nixpkgs";
+ };
+ };
+
+ outputs = inputs@{ nixpkgs, sops-nix, ... }: {
+ nixosConfigurations = {
+ "base" = nixpkgs.lib.nixosSystem {
+ system = "x86_64-linux";
+ modules = [
+ ./per-host/base/configuration.nix
+ ];
+ };
+
+ "torrents-2" = nixpkgs.lib.nixosSystem {
+ system = "x86_64-linux";
+ modules = [
+ ./per-host/base/configuration.nix
+ ./per-host/torrents-2/configuration.nix
+ sops-nix.nixosModules.sops
+ ];
+ };
+
+ "rproxy-2" = nixpkgs.lib.nixosSystem {
+ system = "x86_64-linux";
+ modules = [
+ ./per-host/base/configuration.nix
+ ./per-host/rproxy-2/configuration.nix
+ sops-nix.nixosModules.sops
+ ];
+ };
+ };
+ };
+}
diff --git a/nix/generate-keys.sh b/nix/generate-keys.sh
new file mode 100755
index 0000000..611d931
--- /dev/null
+++ b/nix/generate-keys.sh
@@ -0,0 +1,12 @@
+#!/usr/bin/env bash
+# Generate a host key for a specific host
+set -euo pipefail
+
+HOST="$1"
+mkdir -p "./host-keys/${HOST}"
+ssh-keygen -t ed25519 -f "./host-keys/${HOST}/ssh_host_ed25519_key" -N ""
+echo "✅ Generated host key for ${HOST}"
+echo ""
+echo "👉 Derive age public key with:"
+# echo " cat ./host-keys/${HOST}/ssh_host_ed25519_key.pub | nix run nixpkgs#ssh-to-age"
+echo " cat ./host-keys/${HOST}/ssh_host_ed25519_key.pub | ssh-to-age"
diff --git a/nix/per-host/base/configuration.nix b/nix/per-host/base/configuration.nix
new file mode 100644
index 0000000..8b34249
--- /dev/null
+++ b/nix/per-host/base/configuration.nix
@@ -0,0 +1,67 @@
+{ config, pkgs, modulesPath, lib, system, ... }:
+
+{
+ imports = [
+ (modulesPath + "/profiles/qemu-guest.nix")
+ ];
+
+ config = {
+ #Provide a default hostname
+ networking.hostName = lib.mkDefault "base";
+ networking.useDHCP = lib.mkDefault true;
+
+ # Enable QEMU Guest for Proxmox
+ services.qemuGuest.enable = lib.mkDefault true;
+
+ # Use the boot drive for grub
+ boot.loader.grub.enable = lib.mkDefault true;
+ boot.loader.grub.devices = [ "nodev" ];
+
+ boot.growPartition = lib.mkDefault true;
+
+ # Allow remote updates with flakes and non-root users
+ nix.settings.trusted-users = [ "root" "@wheel" ];
+ nix.settings.experimental-features = [ "nix-command" "flakes" ];
+
+ # Some sane packages we need on every system
+ environment.systemPackages = with pkgs; [
+ vim # for emergencies
+ git # for pulling nix flakes
+ python3 # for ansible
+ ];
+
+ # Don't ask for passwords
+ security.sudo.wheelNeedsPassword = false;
+
+ # Enable ssh
+ services.openssh = {
+ enable = true;
+ settings.PasswordAuthentication = false;
+ settings.KbdInteractiveAuthentication = false;
+ };
+ programs.ssh.startAgent = true;
+
+ # Add an admin user
+ users.users.jefe = {
+ isNormalUser = true;
+ description = "el jefe";
+ extraGroups = [ "networkmanager" "wheel" ];
+ };
+ users.users.jefe.openssh.authorizedKeys.keys = [
+ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAYYjB+fK4JFlJSY6Ax48p38eSuDG12VQVqP+WSrWGuO"
+ ];
+
+ users.users.root.openssh.authorizedKeys.keys = [
+ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAYYjB+fK4JFlJSY6Ax48p38eSuDG12VQVqP+WSrWGuO"
+ ];
+
+ # Default filesystem
+ fileSystems."/" = lib.mkDefault {
+ device = "/dev/disk/by-label/nixos";
+ autoResize = true;
+ fsType = "ext4";
+ };
+
+ system.stateVersion = lib.mkDefault "25.11";
+ };
+}
diff --git a/nix/per-host/rproxy-2/configuration.nix b/nix/per-host/rproxy-2/configuration.nix
new file mode 100644
index 0000000..d1580e8
--- /dev/null
+++ b/nix/per-host/rproxy-2/configuration.nix
@@ -0,0 +1,190 @@
+{ config, pkgs, modulesPath, lib, system, ... }:
+
+{
+ config = {
+ sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
+ sops.defaultSopsFile = ../../secrets/rproxy-2.yaml;
+ sops.secrets."caddy/env" = {
+ owner = "caddy";
+ restartUnits = [ "caddy.service" ];
+ };
+
+ networking.hostName = "rproxy-2";
+ networking.firewall.allowedTCPPorts = [ 80 443 ];
+
+ services.caddy = {
+ enable = true;
+ package = pkgs.caddy.withPlugins {
+ plugins = [ "github.com/caddy-dns/namecheap@v1.0.0" ];
+ hash = "sha256-G+iBYwqKNB0kyQ060R9J2brbwsRl/WgvB6Tkc6MC5yU=";
+ };
+ environmentFile = config.sops.secrets."caddy/env".path;
+
+ # Test config only
+ # virtualHosts."rproxy2.kumardamani.net:80".extraConfig = ''
+ # respond "Hello, world! {$NAMECHEAP_API_USER}"
+ # tls internal
+ # '';
+
+ virtualHosts."lidarr.kumardamani.net:443".extraConfig = ''
+ reverse_proxy med-dl:8686
+ tls {
+ dns namecheap {
+ api_key {$NAMECHEAP_API_KEY}
+ user {$NAMECHEAP_API_USER}
+ }
+ }
+ '';
+
+ virtualHosts."radarr.kumardamani.net:443".extraConfig = ''
+ reverse_proxy med-dl:7878
+ tls {
+ dns namecheap {
+ api_key {$NAMECHEAP_API_KEY}
+ user {$NAMECHEAP_API_USER}
+ }
+ }
+ '';
+
+ virtualHosts."sonarr.kumardamani.net:443".extraConfig = ''
+ reverse_proxy med-dl:8989
+ tls {
+ dns namecheap {
+ api_key {$NAMECHEAP_API_KEY}
+ user {$NAMECHEAP_API_USER}
+ }
+ }
+ '';
+
+ virtualHosts."namemydragon.lol:443".extraConfig = ''
+ reverse_proxy sites:84
+ tls {
+ dns namecheap {
+ api_key {$NAMECHEAP_API_KEY}
+ user {$NAMECHEAP_API_USER}
+ }
+ }
+ '';
+
+ virtualHosts."www.namemydragon.lol:443".extraConfig = ''
+ reverse_proxy sites:84
+ tls {
+ dns namecheap {
+ api_key {$NAMECHEAP_API_KEY}
+ user {$NAMECHEAP_API_USER}
+ }
+ }
+ '';
+
+ virtualHosts."metrics2.kumardamani.net:443".extraConfig = ''
+ reverse_proxy monitoring:9090
+ tls {
+ dns namecheap {
+ api_key {$NAMECHEAP_API_KEY}
+ user {$NAMECHEAP_API_USER}
+ }
+ }
+ '';
+
+ virtualHosts."torrents.kumardamani.net:443".extraConfig = ''
+ reverse_proxy torrents:9091
+ tls {
+ dns namecheap {
+ api_key {$NAMECHEAP_API_KEY}
+ user {$NAMECHEAP_API_USER}
+ }
+ }
+ '';
+
+ virtualHosts."vault.kumardamani.net:443".extraConfig = ''
+ reverse_proxy vault:8989
+ tls {
+ dns namecheap {
+ api_key {$NAMECHEAP_API_KEY}
+ user {$NAMECHEAP_API_USER}
+ }
+ }
+ '';
+
+ virtualHosts."nc.kumardamani.net:443".extraConfig = ''
+ reverse_proxy nc-kumar:11000
+ tls {
+ dns namecheap {
+ api_key {$NAMECHEAP_API_KEY}
+ user {$NAMECHEAP_API_USER}
+ }
+ }
+ '';
+
+ virtualHosts."kumardamani.net:443".extraConfig = ''
+ reverse_proxy sites:83
+ tls {
+ dns namecheap {
+ api_key {$NAMECHEAP_API_KEY}
+ user {$NAMECHEAP_API_USER}
+ }
+ }
+ '';
+
+ virtualHosts."www.kumardamani.net:443".extraConfig = ''
+ reverse_proxy sites:83
+ tls {
+ dns namecheap {
+ api_key {$NAMECHEAP_API_KEY}
+ user {$NAMECHEAP_API_USER}
+ }
+ }
+ '';
+
+ virtualHosts."damanistuff.net:443".extraConfig = ''
+ reverse_proxy sites:82
+ tls {
+ dns namecheap {
+ api_key {$NAMECHEAP_API_KEY}
+ user {$NAMECHEAP_API_USER}
+ }
+ }
+ '';
+
+ virtualHosts."www.damanistuff.net:443".extraConfig = ''
+ reverse_proxy sites:82
+ tls {
+ dns namecheap {
+ api_key {$NAMECHEAP_API_KEY}
+ user {$NAMECHEAP_API_USER}
+ }
+ }
+ '';
+
+ virtualHosts."kavisjourneys.com".extraConfig = ''
+ reverse_proxy sites:81
+ tls {
+ dns namecheap {
+ api_key {$NAMECHEAP_API_KEY}
+ user {$NAMECHEAP_API_USER}
+ }
+ }
+ '';
+
+ virtualHosts."www.kavisjourneys.com".extraConfig = ''
+ reverse_proxy sites:81
+ tls {
+ dns namecheap {
+ api_key {$NAMECHEAP_API_KEY}
+ user {$NAMECHEAP_API_USER}
+ }
+ }
+ '';
+
+ virtualHosts."*.min.kumardamani.net".extraConfig = ''
+ reverse_proxy minio:9000
+ tls {
+ dns namecheap {
+ api_key {$NAMECHEAP_API_KEY}
+ user {$NAMECHEAP_API_USER}
+ }
+ }
+ '';
+ };
+ };
+}
diff --git a/nix/per-host/torrents-2/configuration.nix b/nix/per-host/torrents-2/configuration.nix
new file mode 100644
index 0000000..6e7cd49
--- /dev/null
+++ b/nix/per-host/torrents-2/configuration.nix
@@ -0,0 +1,64 @@
+{ config, pkgs, modulesPath, lib, system, ... }:
+
+{
+ config = {
+ sops.age.sshKeyPaths = [ "/etc/ssh/ssh_host_ed25519_key" ];
+ sops.defaultSopsFile = ../../secrets/torrents-2.yaml;
+ # sops.secrets."foo" = {
+ # owner = "transmission";
+ # };
+
+ networking.hostName = "torrents-2";
+ networking.firewall.allowedTCPPorts = [ 80 443 9091 ];
+
+ hardware.graphics = {
+ enable = true;
+ };
+
+ hardware.nvidia = {
+ modesetting.enable = true;
+ nvidiaPersistenced = true;
+ powerManagement.enable = false;
+ powerManagement.finegrained = false;
+ open = false;
+ nvidiaSettings = true;
+ package = config.boot.kernelPackages.nvidiaPackages.legacy_580;
+ };
+
+ nixpkgs.config.allowUnfree = true;
+
+ services.xserver.videoDrivers = [ "nvidia" ];
+
+ sops.templates."transmission-rpc-password.json" = {
+ content = ''
+ {
+ "rpc-password": "${config.sops.placeholder.foo}"
+ }
+ '';
+ owner = "transmission";
+ restartUnits = [ "transmission.service" ];
+ };
+
+ services.transmission = {
+ enable = true;
+ package = pkgs.transmission_4;
+ credentialsFile = config.sops.templates."transmission-rpc-password.json".path;
+ settings = {
+ rpc-authentication-required = true;
+ rpc-username = "kdam0";
+ # testpass
+ # rpc-password = "{b55cdbfcac290fff79d3bdb3441082dca8f278aay.bodWGn";
+ # rpc-password-file = config.sops.secrets."foo".path;
+ rpc-bind-address = "0.0.0.0";
+ # rpc-host-whitelist = "torrents2.kumardamani.net";
+ rpc-whitelist-enabled = true;
+ rpc-whitelist = "127.0.0.1,10.10.*.*";
+ };
+ };
+
+ fileSystems."/mnt/data" = {
+ device = "nas.bacala:/mnt/tank/customers/kumar/media";
+ fsType = "nfs";
+ };
+ };
+}
diff --git a/nix/secrets/rproxy-2.yaml b/nix/secrets/rproxy-2.yaml
new file mode 100644
index 0000000..f597e7a
--- /dev/null
+++ b/nix/secrets/rproxy-2.yaml
@@ -0,0 +1,26 @@
+caddy:
+ env: ENC[AES256_GCM,data:QwDHxZpSn1Z64qw3EJtlLLL+zbjMFxkVq11Fvu2uYQ876MfO1nqNqY8chJkmM3hGVhnSc+t9G9rv+/IXYvPngd+XKuHgi2bNp47jFuXHi8U=,iv:3q7xMBDyx+zhIV472gNZEkWiTdZIdCRFZjCNOwox5nc=,tag:Kl+xhznyzatyYsRBPlwh/A==,type:str]
+sops:
+ age:
+ - recipient: age12teny70e5cm3992z7atx9g9606d4a60dsl8nskzkpp234uelnctq82mqaa
+ enc: |
+ -----BEGIN AGE ENCRYPTED FILE-----
+ YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBhQnptb3QrM0NVeGY3NFVx
+ c21TMlQ0NTAvN2c1enRybFBKY2ptT2lFbUdBCldwNGNkVjdiaE5hOGlpWGRoQ0pV
+ VXIzT3dqZ2hDM29YVm1jRldRTDJXSUkKLS0tIGNFZEdSMjhVTTlOZTEzY1NTMW41
+ dEZZNHhhN1FBZEJHMGFab29iWXFLMW8KjjC/mHCG1R1899rVyhUMXdyxoi9PevKl
+ dSKlV0b9cVuI5Ad8/FQdI+h5FAMBXLpORB/5GGjvqlzVL4Bz0MXvwg==
+ -----END AGE ENCRYPTED FILE-----
+ - recipient: age1h58rh5q0d7rg984g3e3qfrgwzu3ujzkkcg8f0ls5jlsvdy44f5ls3aywyx
+ enc: |
+ -----BEGIN AGE ENCRYPTED FILE-----
+ YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSArUkRFZ2RJU1ovS2U3WUxi
+ OGJCSGtseTdkdmxMMitwOUNlUHVyT0F1R3ljCklSY1o4MFUzZXVsNzZYZkJWNC9v
+ dWZPdDBhN3Bab3YrQWkvZXRpTkFZSHMKLS0tIFJWRWU3TGpYTmU4eU80NEI3TzVV
+ dDdGemVxVklRNkdNbGFiR3Vvd2pOVUkKjUSql5h+otnIRviVg2N5RF1JSYvBeAMJ
+ lWVy7HGPuzzBk0SZUP5C0cdnGymklZtXE+5qHBlmOUFF5MOqoGEgqw==
+ -----END AGE ENCRYPTED FILE-----
+ lastmodified: "2026-07-01T02:40:11Z"
+ mac: ENC[AES256_GCM,data:b4dO1T1HHX3GQKv1imZMQHrSLzc+Au6WB4r/PjvA+bHMj9SSlU7JxVOQia1pGC4fv9B9i9TLrzyC1WLNk4cpss3+mFTWu/Ep8hk0409LoH8cvQTeyOIVs9vIeDV7+ENTTNyJMMPQu/gwpODRP9Xs6YGfGomMth0ntUdyufMRAlk=,iv:ndO9Ijbxw+2lRwCtDxgpG+P9cIAGap4j4GhxML4V04k=,tag:fik52goMxEry4Ei3vDTLag==,type:str]
+ unencrypted_suffix: _unencrypted
+ version: 3.12.2
diff --git a/nix/secrets/torrents-2.yaml b/nix/secrets/torrents-2.yaml
new file mode 100644
index 0000000..584d092
--- /dev/null
+++ b/nix/secrets/torrents-2.yaml
@@ -0,0 +1,25 @@
+foo: ENC[AES256_GCM,data:nxgkp0a10nLbVqs=,iv:ywxB2H2a/NBW4hwBkFV/JcTpgpnLjHZ4++XS8vpylDA=,tag:wLEnmbpPDsUlacDGqkBajw==,type:str]
+sops:
+ age:
+ - recipient: age12teny70e5cm3992z7atx9g9606d4a60dsl8nskzkpp234uelnctq82mqaa
+ enc: |
+ -----BEGIN AGE ENCRYPTED FILE-----
+ YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBpQ050aEhkQUc0bHJnR3d2
+ WDBVSXFBc09uMDdxdGNMa05JY0FMbmRzQ1Y0ClN2ME1WMGxiSXVhRWxqY0t1ZmZQ
+ a3VremtsaHloWEkxYjBUN0Zyd053YkUKLS0tIHJzUjhpVzEwYXIvQXN5RWxBMTRW
+ MnJVb2FRR29jZ052YTJuS2NvaDFaS00KgjvJEcRYbp/2jhIwCVs8P3ITPrxxpHyu
+ 3iNcGydW+r6KFOjKfYKeXEjJFEPj3G/ipd7EdNi7FwG9e41QehvZYQ==
+ -----END AGE ENCRYPTED FILE-----
+ - recipient: age1cunp9vshd45hlfqdxd4pdvg0qgfllk7mctff65s02wm447xgde7qar7z25
+ enc: |
+ -----BEGIN AGE ENCRYPTED FILE-----
+ YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBzZzVFbzhsNVliSktiRm16
+ N3lNSEtUUytJaDNVdDFML1M2RzloYnFpem5nClMrTHh1N3NBMFN5T1pueU45UlEw
+ aVhuZGhQL1VEaUdCTGRZUWo4MTZtUHMKLS0tIFFxdm02MXlrZEN6Z0VhRkc5S3lU
+ V2g0KzJzZmlGTlBIR3gwdDZUbUViTjgK2QuhL/4Wop3EP8mwoToF8u2UAiHEEknQ
+ I8DRcA7P5rea4pnuaJTYvhz1JzZN0fUr5EOVO6O7YZ9bdlKeDJ+sMw==
+ -----END AGE ENCRYPTED FILE-----
+ lastmodified: "2026-06-29T02:18:04Z"
+ mac: ENC[AES256_GCM,data:ZdhR3KRHMDNB7d05fZO+2TIIijNn3r8jKwAaoB8wSsTon2oPkPMB3iDl0G0Sy2mC/idZNKC8UOSpxcrV0vBjwxjibOOgyUL0faBda8l3NASGLyxd2NcP3M0xIwnLJlqhVjfdkpZ2JwTRkHxmUiZMHLd7fwL1zZaWjs8OCgeLqnw=,iv:nVWOXwygqHXZdUE/dX3cl9c/IcgWfhKj/M+TWaHWWVY=,tag:anNJVNhUYV37BGnkbsTJXQ==,type:str]
+ unencrypted_suffix: _unencrypted
+ version: 3.12.2