From cd961b33bebe56d642ab0032d86615f98c08a473 Mon Sep 17 00:00:00 2001 From: chaos Date: Wed, 13 Sep 2023 19:26:50 +0100 Subject: [PATCH] more work on raspberry's drive --- data/raspberry_ext_drive.nix | 16 +++++ extras/mk-raspberry-ext-drive.nix | 35 +++++++++++ extras/mk-raspberry-ext-drive.sh | 65 +++++++++++++++++++++ home/dev/all/extra.nix | 1 + hosts/raspberry/profiles/external-drive.nix | 44 ++++++++++++++ hosts/raspberry/raspberry.nix | 37 ++++++++---- hosts/raspberry/secrets.nix | 9 ++- outputs.nix | 5 ++ overlay/default.nix | 1 + scripts/deploy-all.sh | 3 +- 10 files changed, 201 insertions(+), 15 deletions(-) create mode 100644 data/raspberry_ext_drive.nix create mode 100644 extras/mk-raspberry-ext-drive.nix create mode 100644 extras/mk-raspberry-ext-drive.sh create mode 100644 hosts/raspberry/profiles/external-drive.nix diff --git a/data/raspberry_ext_drive.nix b/data/raspberry_ext_drive.nix new file mode 100644 index 0000000..df0d81a --- /dev/null +++ b/data/raspberry_ext_drive.nix @@ -0,0 +1,16 @@ +{}: rec { + encrypted_label = "raspberry_encrypted"; + unencrypted_label = "raspberry_drive"; + + mapper_name = "raspberry_external_drive"; + + mountpoint = "/external_drive"; + + backups_path = "${mountpoint}/backups"; + storage_path = "${mountpoint}/storage"; + extras_path = "${mountpoint}/extras"; + + encrypted_path = "/dev/disk/by-label/${encrypted_label}"; + unencrypted_path = "/dev/disk/by-label/${unencrypted_label}"; + mapper_path = "/dev/mapper/${mapper_name}"; +} diff --git a/extras/mk-raspberry-ext-drive.nix b/extras/mk-raspberry-ext-drive.nix new file mode 100644 index 0000000..e7dddc4 --- /dev/null +++ b/extras/mk-raspberry-ext-drive.nix @@ -0,0 +1,35 @@ +{ + stdenv, + bash, + util-linux, + cryptsetup, + btrfs-progs, +}: let + external_drive_data = import ../data/raspberry_ext_drive.nix {}; +in + stdenv.mkDerivation { + name = "mk-raspberry-ext-drive"; + src = ./mk-raspberry-ext-drive.sh; + unpackPhase = '' + for srcFile in $src; do + cp $srcFile $(stripHash $srcFile) + done + ''; + + patchPhase = '' + substituteAllInPlace mk-raspberry-ext-drive.sh + substituteInPlace mk-raspberry-ext-drive.sh \ + --replace "@util-linux@" "${util-linux}" \ + --replace "@btrfs-progs@" "${btrfs-progs}" \ + --replace "@cryptsetup@" "${cryptsetup}" \ + --replace "@bash@" "${bash}" \ + --replace "@ENCRYPTED_LABEL@" "${external_drive_data.encrypted_label}" \ + --replace "@UNENCRYPTED_LABEL@" "${external_drive_data.unencrypted_label}" + ''; + + installPhase = '' + mkdir -p $out/bin + cp mk-raspberry-ext-drive.sh $out/bin/mk-raspberry-ext-drive + chmod +x $out/bin/mk-raspberry-ext-drive + ''; + } diff --git a/extras/mk-raspberry-ext-drive.sh b/extras/mk-raspberry-ext-drive.sh new file mode 100644 index 0000000..e332208 --- /dev/null +++ b/extras/mk-raspberry-ext-drive.sh @@ -0,0 +1,65 @@ +#! @bash@/bin/sh + +set -e + +# e.g /dev/nvme0n1 +DRIVE_PATH=$1 +KEY_FILE=$2 +TEMP_MOUNTPOINT=$3 + +if echo "$DRIVE_PATH" | grep -q "[0-9]$"; then + PARTITION_SEPARATOR="p" +else + PARTITION_SEPARATOR="" +fi + +if [ -z "$DRIVE_PATH" ]; then + echo "Please specify a path to device as first argument" + exit 1 +fi + +if [ -z "$KEY_FILE" ]; then + echo "Please specify a key file to use" + exit 1 +fi + +if [ -z "$TEMP_MOUNTPOINT" ]; then + echo "Please specify a temp mountpoint to use" + exit 1 +fi + +if [ "$EUID" -ne 0 ]; then + echo "Please run as root" + exit +fi + +# encrypted partition label +ENCRYPTED_LABEL=@ENCRYPTED_LABEL@ +# unencrypted filesystem label +UNENCRYPTED_LABEL=@UNENCRYPTED_LABEL@ + +echo "Wiping Partitions..." +@util-linux@/bin/wipefs --all ${DRIVE_PATH} + +echo "Creating Encrypted Partition" +@cryptsetup@/bin/cryptsetup luksFormat "${DRIVE_PATH}" --key-file "${KEY_FILE}" --label "${ENCRYPTED_LABEL}" + +echo "Opening Encrypted Partition" +@cryptsetup@/bin/cryptsetup open "${DRIVE_PATH}" "mk-raspberry-ext-drive" --key-file "${KEY_FILE}" + +echo "Formatting Encrypted Filesystem" +@btrfs-progs@/bin/mkfs.btrfs -L "${UNENCRYPTED_LABEL}" /dev/mapper/mk-raspberry-ext-drive + +echo "Mounting Partition" +mount -t btrfs /dev/mapper/mk-raspberry-ext-drive "$TEMP_MOUNTPOINT" + +echo "Creating Folders" +mkdir "$TEMP_MOUNTPOINT/backups" +mkdir "$TEMP_MOUNTPOINT/storage" +mkdir "$TEMP_MOUNTPOINT/extras" + +echo "Unmounting" +umount "$TEMP_MOUNTPOINT" + +echo "Closing mapper device" +@cryptsetup@/bin/cryptsetup close "mk-raspberry-ext-drive" diff --git a/home/dev/all/extra.nix b/home/dev/all/extra.nix index 35c6090..9ea7ebc 100644 --- a/home/dev/all/extra.nix +++ b/home/dev/all/extra.nix @@ -19,5 +19,6 @@ mk-enc-usb mk-normal-enc-ssd mk-dual-enc-ssd + mk-raspberry-ext-drive ]; } diff --git a/hosts/raspberry/profiles/external-drive.nix b/hosts/raspberry/profiles/external-drive.nix new file mode 100644 index 0000000..7fef7d9 --- /dev/null +++ b/hosts/raspberry/profiles/external-drive.nix @@ -0,0 +1,44 @@ +{pkgs, ...}: let + external_drive_data = import ../../../data/raspberry_ext_drive.nix {}; + + mount_external_drive = let + jq = "${pkgs.jq}/bin/jq"; + vault = "${pkgs.vault-bin}/bin/vault"; + cryptsetup = "${pkgs.cryptsetup}/bin/cryptsetup"; + in + pkgs.writeShellScriptBin "mount_external_drive" '' + ${unmount_external_drive}/bin/unmount_external_drive + + vault-login + + ${vault} kv get -format json "/private-public-keys/cryptsetup/raspberry-ext-drive" \ + | ${jq} -r ".data.data.key" \ + | base64 -d \ + | ${cryptsetup} open ${external_drive_data.encrypted_path} ${external_drive_data.mapper_name} --key-file=/dev/stdin + mount ${external_drive_data.mapper_path} -o rw,compress=zstd ${external_drive_data.mountpoint} + ''; + + unmount_external_drive = let + cryptsetup = "${pkgs.cryptsetup}/bin/cryptsetup"; + in + pkgs.writeShellScriptBin "unmount_external_drive" '' + umount -flR ${external_drive_data.mountpoint} || true + ${cryptsetup} close ${external_drive_data.mapper_name} || true + ''; +in { + environment.systemPackages = + (with pkgs; [ + cryptsetup + ]) + ++ [ + mount_external_drive + unmount_external_drive + ]; + + systemd.tmpfiles.rules = ["d ${external_drive_data.mountpoint} - root root"]; + + # services.udev.extraRules = '' + # ACTION=="add", ENV{PARTNAME}=="${external_drive_data.encrypted_partlabel}", ENV{SYSTEMD_WANTS}="mount-external-drive.service" + # ACTION=="remove", ENV{PARTNAME}=="${external_drive_data.encrypted_partlabel}", ENV{SYSTEMD_WANTS}="unmount-external-drive.service" + # ''; +} diff --git a/hosts/raspberry/raspberry.nix b/hosts/raspberry/raspberry.nix index 501d357..ee997a1 100644 --- a/hosts/raspberry/raspberry.nix +++ b/hosts/raspberry/raspberry.nix @@ -1,25 +1,38 @@ { tree, modulesPath, + config, pkgs, lib, ... -}: { - imports = with tree; [ - users.root - users.chaos +}: let + secrets = config.services.secrets.secrets; +in { + imports = with tree; + [ + users.root + users.chaos - profiles.base - profiles.sshd + profiles.base + profiles.sshd - profiles.connectivity.network_manager - profiles.connectivity.bluetooth - profiles.connectivity.ios + profiles.connectivity.network_manager + profiles.connectivity.bluetooth + profiles.connectivity.ios - ./secrets.nix + ./secrets.nix - ./boot.nix - (modulesPath + "/installer/sd-card/sd-image.nix") + ./boot.nix + (modulesPath + "/installer/sd-card/sd-image.nix") + ] + ++ (with hosts.raspberry.profiles; [ + external-drive + ]); + + environment.systemPackages = [ + (pkgs.writeShellScriptBin "vault-login" '' + ${pkgs.vault-bin}/bin/vault login -method=userpass username=raspberry password=$(cat ${secrets.vault_login_password.path}) + '') ]; home-manager.users.root = { diff --git a/hosts/raspberry/secrets.nix b/hosts/raspberry/secrets.nix index e37c38d..83d7454 100644 --- a/hosts/raspberry/secrets.nix +++ b/hosts/raspberry/secrets.nix @@ -2,10 +2,17 @@ services.secrets = { enable = true; secrets = { + # Used for fetching the encryption drive's key at runtime + # can be revoked in case of hardware theft + # Can also run vault-login on host before secrets-init to fetch secrets using raspberry's login + vault_login_password = { + manual = true; + }; + home-wifi-password = { user = "root"; group = "root"; - permissions = "0600"; + permissions = "600"; path = "/etc/NetworkManager/system-connections/Home-WiFi.nmconnection"; fetchScript = '' diff --git a/outputs.nix b/outputs.nix index 101a609..88f3a45 100644 --- a/outputs.nix +++ b/outputs.nix @@ -69,6 +69,7 @@ in mk-enc-usb mk-normal-enc-ssd mk-dual-enc-ssd + mk-raspberry-ext-drive ]); }; @@ -87,6 +88,10 @@ in type = "app"; program = "${packages.mk-dual-enc-ssd}/bin/mk-dual-enc-ssd"; }; + mk-raspberry-ext-drive = { + type = "app"; + program = "${packages.mk-raspberry-ext-drive}/bin/mk-raspberry-ext-drive"; + }; secrets-init-lappy-t495 = secretsInitAppForSystem "lappy-t495" packages; secrets-init-vault = secretsInitAppForSystem "vault" packages; secrets-init-hetzner-vm = secretsInitAppForSystem "hetzner-vm" packages; diff --git a/overlay/default.nix b/overlay/default.nix index dbc689b..12b409d 100644 --- a/overlay/default.nix +++ b/overlay/default.nix @@ -10,6 +10,7 @@ final: prev: { mk-enc-usb = final.callPackage ../extras/mk-enc-usb.nix {}; mk-normal-enc-ssd = final.callPackage ../extras/mk-normal-enc-ssd.nix {}; mk-dual-enc-ssd = final.callPackage ../extras/mk-dual-enc-ssd.nix {}; + mk-raspberry-ext-drive = final.callPackage ../extras/mk-raspberry-ext-drive.nix {}; gotosocial = prev.gotosocial.overrideAttrs (_old: let owner = "superseriousbusiness"; diff --git a/scripts/deploy-all.sh b/scripts/deploy-all.sh index b298e84..3d29394 100755 --- a/scripts/deploy-all.sh +++ b/scripts/deploy-all.sh @@ -11,5 +11,4 @@ HOSTNAME=$(hostname) [ "${NO_REBUILD}" == "" ] && ./scripts/rebuild.sh $@ [ "${HOSTNAME}" != "hetzner-vm" ] && deploy -s ".#hetzner-vm" -- $@ [ "${HOSTNAME}" != "vault" ] && deploy -s ".#vault" -- $@ -[ "${HOSTNAME}" != "buildbox" ] && deploy -s ".#buildbox" -- $@ - +[ "${HOSTNAME}" != "raspberry" ] && nixos-rebuild --flake .#raspberry --target-host root@192.168.0.203 $@ \ No newline at end of file