diff --git a/.gitattributes b/.gitattributes index 45b5ca3..b1c9c58 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1,3 @@ secrets/** filter=git-crypt diff=git-crypt +usb-secrets/usb-secrets/usb-secrets-key filter=git-crypt diff=git-crypt + diff --git a/age-secrets.nix b/age-secrets.nix new file mode 100644 index 0000000..7560906 --- /dev/null +++ b/age-secrets.nix @@ -0,0 +1,64 @@ +{ + config, + lib, + pkgs, + ... +}: +{ + # Configure all agenix secrets + age.secrets = { + # ZFS encryption key + zfs-key = { + file = ./secrets/zfs-key.age; + mode = "0400"; + owner = "root"; + group = "root"; + }; + + # Secureboot keys archive + secureboot-tar = { + file = ./secrets/secureboot.tar.age; + mode = "0400"; + owner = "root"; + group = "root"; + }; + + # System passwords + hashedPass = { + file = ./secrets/hashedPass.age; + mode = "0400"; + owner = "root"; + group = "root"; + }; + + # Service authentication + caddy_auth = { + file = ./secrets/caddy_auth.age; + mode = "0400"; + owner = "root"; + group = "root"; + }; + + jellyfin-api-key = { + file = ./secrets/jellyfin-api-key.age; + mode = "0400"; + owner = "root"; + group = "root"; + }; + + slskd_env = { + file = ./secrets/slskd_env.age; + mode = "0400"; + owner = "root"; + group = "root"; + }; + + # Network configuration + wg0-conf = { + file = ./secrets/wg0.conf.age; + mode = "0400"; + owner = "root"; + group = "root"; + }; + }; +} diff --git a/configuration.nix b/configuration.nix index 34e811c..815384b 100644 --- a/configuration.nix +++ b/configuration.nix @@ -14,6 +14,8 @@ ./hardware.nix ./zfs.nix ./impermanence.nix + ./usb-secrets.nix + ./age-secrets.nix ./services/postgresql.nix ./services/jellyfin.nix @@ -26,8 +28,6 @@ ./services/qbittorrent.nix ./services/bitmagnet.nix - # ./services/matrix.nix - # ./services/owntracks.nix ./services/soulseek.nix ./services/llama-cpp.nix @@ -111,16 +111,18 @@ }; system.activationScripts = { - # extract all my secureboot keys - # TODO! awful secrets management, it's globally readable in /nix/store - "secureboot-keys".text = '' - #!/bin/sh - rm -fr ${config.boot.lanzaboote.pkiBundle} || true - mkdir -p ${config.boot.lanzaboote.pkiBundle} - ${pkgs.gnutar}/bin/tar xf ${./secrets/secureboot.tar} -C ${config.boot.lanzaboote.pkiBundle} - chown -R root:wheel ${config.boot.lanzaboote.pkiBundle} - chmod -R 500 ${config.boot.lanzaboote.pkiBundle} - ''; + # extract secureboot keys from agenix-decrypted tar + "secureboot-keys" = { + deps = [ "agenix" ]; + text = '' + #!/bin/sh + rm -fr ${config.boot.lanzaboote.pkiBundle} || true + mkdir -p ${config.boot.lanzaboote.pkiBundle} + ${pkgs.gnutar}/bin/tar xf ${config.age.secrets.secureboot-tar.path} -C ${config.boot.lanzaboote.pkiBundle} + chown -R root:wheel ${config.boot.lanzaboote.pkiBundle} + chmod -R 500 ${config.boot.lanzaboote.pkiBundle} + ''; + }; }; environment.etc = { @@ -286,7 +288,7 @@ ]; # TODO! use proper secrets management - hashedPassword = lib.strings.trim (builtins.readFile ./secrets/hashedPass); + hashedPasswordFile = config.age.secrets.hashedPass.path; openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO4jL6gYOunUlUtPvGdML0cpbKSsPNqQ1jit4E7U1RyH" # laptop diff --git a/flake.lock b/flake.lock index b4fd566..752925f 100644 --- a/flake.lock +++ b/flake.lock @@ -1,5 +1,28 @@ { "nodes": { + "agenix": { + "inputs": { + "darwin": "darwin", + "home-manager": "home-manager", + "nixpkgs": [ + "nixpkgs" + ], + "systems": "systems" + }, + "locked": { + "lastModified": 1754433428, + "narHash": "sha256-NA/FT2hVhKDftbHSwVnoRTFhes62+7dxZbxj5Gxvghs=", + "owner": "ryantm", + "repo": "agenix", + "rev": "9edb1787864c4f59ae5074ad498b6272b3ec308d", + "type": "github" + }, + "original": { + "owner": "ryantm", + "repo": "agenix", + "type": "github" + } + }, "crane": { "locked": { "lastModified": 1754269165, @@ -15,6 +38,28 @@ "type": "github" } }, + "darwin": { + "inputs": { + "nixpkgs": [ + "agenix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1744478979, + "narHash": "sha256-dyN+teG9G82G+m+PX/aSAagkC+vUv0SgUw3XkPhQodQ=", + "owner": "lnl7", + "repo": "nix-darwin", + "rev": "43975d782b418ebf4969e9ccba82466728c2851b", + "type": "github" + }, + "original": { + "owner": "lnl7", + "ref": "master", + "repo": "nix-darwin", + "type": "github" + } + }, "deploy-rs": { "inputs": { "flake-compat": "flake-compat", @@ -146,7 +191,7 @@ }, "flake-utils": { "inputs": { - "systems": "systems_2" + "systems": "systems_3" }, "locked": { "lastModified": 1731533236, @@ -185,6 +230,27 @@ } }, "home-manager": { + "inputs": { + "nixpkgs": [ + "agenix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1745494811, + "narHash": "sha256-YZCh2o9Ua1n9uCvrvi5pRxtuVNml8X2a03qIFfRKpFs=", + "owner": "nix-community", + "repo": "home-manager", + "rev": "abfad3d2958c9e6300a883bd443512c55dfeb1be", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "home-manager", + "type": "github" + } + }, + "home-manager_2": { "inputs": { "nixpkgs": [ "nixpkgs" @@ -360,9 +426,10 @@ }, "root": { "inputs": { + "agenix": "agenix", "deploy-rs": "deploy-rs", "disko": "disko", - "home-manager": "home-manager", + "home-manager": "home-manager_2", "impermanence": "impermanence", "lanzaboote": "lanzaboote", "llamacpp": "llamacpp", @@ -463,6 +530,21 @@ "type": "github" } }, + "systems_3": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, "trackerlist": { "flake": false, "locked": { @@ -481,7 +563,7 @@ }, "utils": { "inputs": { - "systems": "systems" + "systems": "systems_2" }, "locked": { "lastModified": 1731533236, diff --git a/flake.nix b/flake.nix index 7d40bad..246fb1d 100644 --- a/flake.nix +++ b/flake.nix @@ -47,6 +47,11 @@ url = "github:nix-community/impermanence"; }; + agenix = { + url = "github:ryantm/agenix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + senior_project-website = { url = "github:Titaniumtown/senior-project-website"; flake = false; @@ -76,6 +81,7 @@ srvos, deploy-rs, impermanence, + agenix, ... }@inputs: let @@ -97,7 +103,6 @@ jellyfin = 8096; # no services.jellyfin option for this torrent = 6011; bitmagnet = 3333; - owntracks = 3825; gitea = 2283; immich = 2284; soulseek_web = 5030; @@ -110,7 +115,6 @@ certs = services_dir + "/http_certs"; domain = "gardling.com"; wg_ip = "192.168.15.1"; - matrix_hostname = "matrix.${service_configs.https.domain}"; }; gitea = { @@ -142,10 +146,6 @@ cacheDir = services_dir + "/jellyfin_cache"; }; - owntracks = { - data_dir = services_dir + "/owntracks"; - }; - slskd = rec { base = "/var/lib/slskd"; downloads = base + "/downloads"; @@ -221,6 +221,8 @@ lanzaboote.nixosModules.lanzaboote + agenix.nixosModules.default + home-manager.nixosModules.home-manager ( { diff --git a/secrets.nix b/secrets.nix new file mode 100644 index 0000000..816c875 --- /dev/null +++ b/secrets.nix @@ -0,0 +1,22 @@ +let + # USB secrets key - for encrypting/decrypting all secrets + usbSecretsKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN8+eSX2LH5wEHVG9sSv97ceD5zdTarV0lRvoUso4A7p USB secrets decryption key"; +in +{ + # ZFS encryption key + "zfs-key.age".publicKeys = [ usbSecretsKey ]; + + # Secureboot keys archive + "secureboot.tar.age".publicKeys = [ usbSecretsKey ]; + + # System passwords and auth + "hashedPass.age".publicKeys = [ usbSecretsKey ]; + + # Service authentication + "caddy_auth.age".publicKeys = [ usbSecretsKey ]; + "jellyfin-api-key.age".publicKeys = [ usbSecretsKey ]; + "slskd_env.age".publicKeys = [ usbSecretsKey ]; + + # Network configuration + "wg0.conf.age".publicKeys = [ usbSecretsKey ]; +} diff --git a/secrets/caddy_auth b/secrets/caddy_auth deleted file mode 100644 index 8871a69..0000000 Binary files a/secrets/caddy_auth and /dev/null differ diff --git a/secrets/caddy_auth.age b/secrets/caddy_auth.age new file mode 100644 index 0000000..53ebabc Binary files /dev/null and b/secrets/caddy_auth.age differ diff --git a/secrets/hashedPass b/secrets/hashedPass deleted file mode 100644 index fe3afff..0000000 Binary files a/secrets/hashedPass and /dev/null differ diff --git a/secrets/hashedPass.age b/secrets/hashedPass.age new file mode 100644 index 0000000..69fe4ef Binary files /dev/null and b/secrets/hashedPass.age differ diff --git a/secrets/jellyfin-api-key b/secrets/jellyfin-api-key deleted file mode 100644 index a91e5c3..0000000 Binary files a/secrets/jellyfin-api-key and /dev/null differ diff --git a/secrets/jellyfin-api-key.age b/secrets/jellyfin-api-key.age new file mode 100644 index 0000000..81facfc Binary files /dev/null and b/secrets/jellyfin-api-key.age differ diff --git a/secrets/matrix_reg_token b/secrets/matrix_reg_token deleted file mode 100644 index 206fd31..0000000 Binary files a/secrets/matrix_reg_token and /dev/null differ diff --git a/secrets/owntracks_caddy_auth b/secrets/owntracks_caddy_auth deleted file mode 100644 index 2cd6cbc..0000000 Binary files a/secrets/owntracks_caddy_auth and /dev/null differ diff --git a/secrets/secureboot.tar b/secrets/secureboot.tar deleted file mode 100644 index 7d87891..0000000 Binary files a/secrets/secureboot.tar and /dev/null differ diff --git a/secrets/secureboot.tar.age b/secrets/secureboot.tar.age new file mode 100644 index 0000000..362b256 Binary files /dev/null and b/secrets/secureboot.tar.age differ diff --git a/secrets/slskd_env.age b/secrets/slskd_env.age new file mode 100644 index 0000000..0900a57 Binary files /dev/null and b/secrets/slskd_env.age differ diff --git a/secrets/wg0.conf b/secrets/wg0.conf deleted file mode 100644 index 0707030..0000000 Binary files a/secrets/wg0.conf and /dev/null differ diff --git a/secrets/wg0.conf.age b/secrets/wg0.conf.age new file mode 100644 index 0000000..0e20308 Binary files /dev/null and b/secrets/wg0.conf.age differ diff --git a/secrets/zfs-key b/secrets/zfs-key deleted file mode 100644 index 35c226c..0000000 Binary files a/secrets/zfs-key and /dev/null differ diff --git a/secrets/zfs-key.age b/secrets/zfs-key.age new file mode 100644 index 0000000..3682980 Binary files /dev/null and b/secrets/zfs-key.age differ diff --git a/services/bitmagnet.nix b/services/bitmagnet.nix index cebecc6..9d03a74 100644 --- a/services/bitmagnet.nix +++ b/services/bitmagnet.nix @@ -25,7 +25,7 @@ }; services.caddy.virtualHosts."bitmagnet.${service_configs.https.domain}".extraConfig = '' - ${builtins.readFile ../secrets/caddy_auth} + import ${config.age.secrets.caddy_auth.path} reverse_proxy ${service_configs.https.wg_ip}:${builtins.toString service_configs.ports.bitmagnet} ''; } diff --git a/services/caddy.nix b/services/caddy.nix index 9e5869c..d0e5c9c 100644 --- a/services/caddy.nix +++ b/services/caddy.nix @@ -66,6 +66,12 @@ in }; }; + # Add agenix dependency for caddy service + systemd.services.caddy = { + after = [ "agenix.service" ]; + requires = [ "agenix.service" ]; + }; + systemd.tmpfiles.rules = [ "d ${config.services.caddy.dataDir} 700 ${config.services.caddy.user} ${config.services.caddy.group}" ]; diff --git a/services/llama-cpp.nix b/services/llama-cpp.nix index 8c8256c..9a57449 100644 --- a/services/llama-cpp.nix +++ b/services/llama-cpp.nix @@ -37,7 +37,7 @@ systemd.services.llama-cpp.serviceConfig.DynamicUser = lib.mkForce false; services.caddy.virtualHosts."llm.${service_configs.https.domain}".extraConfig = '' - ${builtins.readFile ../secrets/caddy_auth} + import ${config.age.secrets.caddy_auth.path} reverse_proxy :${builtins.toString config.services.llama-cpp.port} ''; } diff --git a/services/matrix.nix b/services/matrix.nix deleted file mode 100644 index dee5cb4..0000000 --- a/services/matrix.nix +++ /dev/null @@ -1,65 +0,0 @@ -{ - pkgs, - config, - service_configs, - lib, - ... -}: -{ - services.matrix-conduit.settings.global.registration_token = - builtins.readFile ../secrets/matrix_reg_token; - - services.caddy.virtualHosts.${service_configs.https.domain}.extraConfig = lib.mkBefore '' - header /.well-known/matrix/* Content-Type application/json - header /.well-known/matrix/* Access-Control-Allow-Origin * - respond /.well-known/matrix/server `{"m.server": "${service_configs.https.matrix_hostname}:${service_configs.ports.https}"}` - respond /.well-known/matrix/client `{"m.server":{"base_url":"https://${service_configs.https.matrix_hostname}"},"m.homeserver":{"base_url":"https://${service_configs.https.matrix_hostname}"},"org.matrix.msc3575.proxy":{"base_url":"https://${config.services.matrix-conduit.settings.global.server_name}"}}` - ''; - - services.caddy.virtualHosts."${service_configs.https.matrix_hostname}".extraConfig = '' - reverse_proxy :${builtins.toString config.services.matrix-conduit.settings.global.port} - ''; - - # Exact duplicate - services.caddy.virtualHosts."${service_configs.https.matrix_hostname}:8448".extraConfig = - config.services.caddy.virtualHosts."${config.services.matrix-conduit.settings.global.server_name - }".extraConfig; - - services.matrix-conduit = { - enable = true; - package = pkgs.conduwuit; - - settings.global = { - port = 6167; - server_name = service_configs.https.domain; - database_backend = "rocksdb"; - allow_registration = true; - - new_user_displayname_suffix = ""; - - trusted_servers = [ - "matrix.org" - "constellatory.net" - "tchncs.de" - "envs.net" - ]; - - # without this, conduit fails to start - address = "0.0.0.0"; - }; - }; - - systemd.tmpfiles.rules = [ - "Z /var/lib/private/matrix-conduit 0770 conduit conduit" - ]; - - # for federation - networking.firewall.allowedTCPPorts = [ - 8448 - ]; - - # for federation - networking.firewall.allowedUDPPorts = [ - 8448 - ]; -} diff --git a/services/owntracks.nix b/services/owntracks.nix deleted file mode 100644 index b5734ac..0000000 --- a/services/owntracks.nix +++ /dev/null @@ -1,46 +0,0 @@ -{ - pkgs, - service_configs, - username, - ... -}: -let - owntracks_pkg = pkgs.owntracks-recorder.overrideAttrs (old: { - installPhase = old.installPhase + '' - mkdir -p $out/usr/share/ot-recorder - cp -R docroot/* $out/usr/share/ot-recorder''; - }); -in -{ - users.groups.owntracks = { }; - users.users.owntracks = { - isNormalUser = true; - group = "owntracks"; - }; - - systemd.services.owntracks = { - enable = true; - description = "Store and access data published by OwnTracks apps"; - wantedBy = [ "multi-user.target" ]; - - serviceConfig = { - User = "owntracks"; - Group = "owntracks"; - WorkingDirectory = "${owntracks_pkg}"; - ExecStart = "${owntracks_pkg}/bin/ot-recorder -S ${service_configs.owntracks.data_dir} --doc-root usr/share/ot-recorder --http-port ${builtins.toString service_configs.ports.owntracks} --port 0"; - }; - }; - - systemd.tmpfiles.rules = [ - "Z ${service_configs.owntracks.data_dir} 0770 owntracks owntracks" - ]; - - services.caddy.virtualHosts."owntracks.${service_configs.https.domain}".extraConfig = '' - ${builtins.readFile ../secrets/owntracks_caddy_auth} - reverse_proxy :${builtins.toString service_configs.ports.owntracks} - ''; - - users.users.${username}.extraGroups = [ - "owntracks" - ]; -} diff --git a/services/qbittorrent.nix b/services/qbittorrent.nix index 4135629..e7d6ba3 100644 --- a/services/qbittorrent.nix +++ b/services/qbittorrent.nix @@ -102,7 +102,7 @@ ]; services.caddy.virtualHosts."torrent.${service_configs.https.domain}".extraConfig = '' - ${builtins.readFile ../secrets/caddy_auth} + import ${config.age.secrets.caddy_auth.path} reverse_proxy ${service_configs.https.wg_ip}:${builtins.toString config.services.qbittorrent.webuiPort} ''; diff --git a/services/soulseek.nix b/services/soulseek.nix index b6c42c6..8795687 100644 --- a/services/soulseek.nix +++ b/services/soulseek.nix @@ -26,7 +26,7 @@ in "skskd_env".text = '' #!/bin/sh rm -fr ${slskd_env} || true - cp ${../secrets/slskd_env} ${slskd_env} + cp ${config.age.secrets.slskd_env.path} ${slskd_env} chmod 0500 ${slskd_env} chown ${config.services.slskd.user}:${config.services.slskd.group} ${slskd_env} ''; @@ -67,6 +67,12 @@ in users.users.${config.services.jellyfin.user}.extraGroups = [ "music" ]; users.users.${username}.extraGroups = [ "music" ]; + # Add agenix dependencies for slskd service + systemd.services.slskd = { + after = [ "agenix.service" ]; + requires = [ "agenix.service" ]; + }; + systemd.tmpfiles.rules = [ "Z ${service_configs.music_dir} 0750 ${username} music" "Z ${service_configs.slskd.base} 0750 ${config.services.slskd.user} ${config.services.slskd.group}" diff --git a/services/wg.nix b/services/wg.nix index 36c363e..1e9d7f5 100644 --- a/services/wg.nix +++ b/services/wg.nix @@ -2,13 +2,14 @@ pkgs, service_configs, eth_interface, + config, ... }: { # network namespace that is proxied through mullvad vpnNamespaces.wg = { enable = true; - wireguardConfigFile = ../secrets/wg0.conf; + wireguardConfigFile = config.age.secrets.wg0-conf.path; accessibleFrom = [ # "192.168.0.0/24" ]; @@ -20,13 +21,15 @@ "network.target" "jellyfin.service" "qbittorrent.service" + "agenix.service" ]; + requires = [ "agenix.service" ]; wantedBy = [ "multi-user.target" ]; serviceConfig = { Type = "simple"; ExecStart = pkgs.writeShellScript "jellyfin-monitor-start" '' - export JELLYFIN_API_KEY=$(cat ${../secrets/jellyfin-api-key}) + export JELLYFIN_API_KEY=$(cat ${config.age.secrets.jellyfin-api-key.path}) exec ${ pkgs.python3.withPackages (ps: with ps; [ requests ]) }/bin/python ${./jellyfin-qbittorrent-monitor.py} diff --git a/usb-secrets.nix b/usb-secrets.nix new file mode 100644 index 0000000..07f8a4a --- /dev/null +++ b/usb-secrets.nix @@ -0,0 +1,58 @@ +{ + config, + lib, + pkgs, + ... +}: +{ + # Extract USB secrets key in main system before agenix + systemd.services.usb-secrets = { + description = "Extract USB secrets key"; + wantedBy = [ "sysinit.target" ]; + before = [ "agenix.service" ]; + wants = [ "local-fs.target" ]; + after = [ "local-fs.target" ]; + unitConfig.DefaultDependencies = false; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + }; + script = '' + mkdir -p /run/secrets /mnt/usb + + # Check if key already exists + if [ -f /run/secrets/usb-secrets-key ]; then + echo "USB secrets key already loaded" + exit 0 + fi + + # Wait for USB devices + for i in {1..30}; do + [ -e /dev/disk/by-label/SECRETS ] && break + sleep 1 + done + + # Mount USB and copy key + if mount /dev/disk/by-label/SECRETS /mnt/usb 2>/dev/null; then + if [ -f /mnt/usb/usb-secrets-key ]; then + install -m 600 /mnt/usb/usb-secrets-key /run/secrets/usb-secrets-key + umount /mnt/usb + echo "USB secrets key loaded" + else + umount /mnt/usb + echo "Key file not found" + exit 1 + fi + else + echo "USB not found" + exit 1 + fi + ''; + }; + + age.identityPaths = [ "/run/secrets/usb-secrets-key" ]; + + systemd.tmpfiles.rules = [ + "d /run/secrets 0700 root root -" + ]; +} \ No newline at end of file diff --git a/usb-secrets/setup-usb.sh b/usb-secrets/setup-usb.sh new file mode 100755 index 0000000..67e38ef --- /dev/null +++ b/usb-secrets/setup-usb.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env nix-shell +#! nix-shell -i bash -p parted dosfstools +set -euo pipefail + +SCRIPT_DIR="$(dirname "$(realpath "$0")")" +USB_DEVICE="$1" +if [[ -z "${USB_DEVICE:-}" ]]; then + echo "Usage: $0 " + echo "Example: $0 /dev/sdb" + exit 1 +fi + +if [[ ! -b "$USB_DEVICE" ]]; then + echo "Error: $USB_DEVICE is not a block device" + exit 1 +fi + +if [[ ! -f "$SCRIPT_DIR/usb-secrets/usb-secrets-key" ]]; then + echo "Error: usb-secrets-key not found at $SCRIPT_DIR/usb-secrets/usb-secrets-key" + exit 1 +fi + +echo "WARNING: This will completely wipe $USB_DEVICE" +echo "Press Ctrl+C to abort, or Enter to continue..." +read + +echo "Creating partition and formatting as FAT32..." +parted -s "$USB_DEVICE" mklabel msdos +parted -s "$USB_DEVICE" mkpart primary fat32 0% 100% +parted -s "$USB_DEVICE" set 1 boot on + +USB_PARTITION="${USB_DEVICE}1" +mkfs.fat -F 32 -n "SECRETS" "$USB_PARTITION" + +echo "Copying key to USB..." +MOUNT_POINT=$(mktemp -d) +trap "umount $MOUNT_POINT 2>/dev/null || true; rmdir $MOUNT_POINT" EXIT + +mount "$USB_PARTITION" "$MOUNT_POINT" +cp "$SCRIPT_DIR/usb-secrets/usb-secrets-key" "$MOUNT_POINT/" +umount "$MOUNT_POINT" + +echo "USB setup complete! Label: SECRETS" +echo "Create multiple backup USB keys for redundancy." \ No newline at end of file diff --git a/usb-secrets/usb-secrets/usb-secrets-key b/usb-secrets/usb-secrets/usb-secrets-key new file mode 100644 index 0000000..7f7eed7 Binary files /dev/null and b/usb-secrets/usb-secrets/usb-secrets-key differ diff --git a/usb-secrets/usb-secrets/usb-secrets-key.pub b/usb-secrets/usb-secrets/usb-secrets-key.pub new file mode 100644 index 0000000..f6df05a --- /dev/null +++ b/usb-secrets/usb-secrets/usb-secrets-key.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN8+eSX2LH5wEHVG9sSv97ceD5zdTarV0lRvoUso4A7p USB secrets decryption key diff --git a/zfs.nix b/zfs.nix index 8e5dbe9..abec78f 100644 --- a/zfs.nix +++ b/zfs.nix @@ -1,4 +1,5 @@ { + config, service_configs, pkgs, ... @@ -10,13 +11,14 @@ let in { system.activationScripts = { - # TODO! replace with proper secrets management + # Copy decrypted ZFS key from agenix to expected location + # /etc is on tmpfs due to impermanence, so no persistent storage risk "zfs-key".text = '' #!/bin/sh - rm -fr ${zfs-key} || true - cp ${./secrets/zfs-key} ${zfs-key} - chmod 0500 ${zfs-key} - chown root:wheel ${zfs-key} + rm -f ${zfs-key} || true + cp ${config.age.secrets.zfs-key.path} ${zfs-key} + chmod 0400 ${zfs-key} + chown root:root ${zfs-key} ''; };