From 6cf6cfa8a8f131de8453be3a43dd20fb2e412533 Mon Sep 17 00:00:00 2001 From: Qubasa Date: Sat, 10 Aug 2024 12:24:36 +0200 Subject: [PATCH] docs: Add zfs disk encryption getting started guide with remote unlocking. --- docs/mkdocs.yml | 1 + docs/site/getting-started/deploy.md | 1 + docs/site/getting-started/disk-encryption.md | 301 +++++++++++++++++++ 3 files changed, 303 insertions(+) create mode 100644 docs/site/getting-started/disk-encryption.md diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index fa72fc6b0..dd1fea679 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -45,6 +45,7 @@ nav: - Configure: getting-started/configure.md - Secrets & Facts: getting-started/secrets.md - Deploy Machine: getting-started/deploy.md + - Disk Encryption: getting-started/disk-encryption.md - Mesh VPN: getting-started/mesh-vpn.md - Backup & Restore: getting-started/backups.md - Flake-parts: getting-started/flake-parts.md diff --git a/docs/site/getting-started/deploy.md b/docs/site/getting-started/deploy.md index ff09e188c..f861495a8 100644 --- a/docs/site/getting-started/deploy.md +++ b/docs/site/getting-started/deploy.md @@ -225,6 +225,7 @@ This is useful for machines that are not always online or are not part of the re ## What's next ? +- [**Disk Encryption**](./disk-encryption.md): Configure disk encryption with remote decryption - [**Mesh VPN**](./mesh-vpn.md): Configuring a secure mesh network. --- diff --git a/docs/site/getting-started/disk-encryption.md b/docs/site/getting-started/disk-encryption.md new file mode 100644 index 000000000..1af4ee47d --- /dev/null +++ b/docs/site/getting-started/disk-encryption.md @@ -0,0 +1,301 @@ +## Setting up Encryption with Remote Decryption in NixOS + +This guide provides an example setup for a single-disk ZFS system with native encryption, accessible for decryption remotely. This configuration only applies to `systemd-boot` enabled systems and requires UEFI booting. + +For a mirrored disk setup, add `mode = "mirror";` to `zroot`. Under the `disk` option, provide the additional disk identifier, e.g., `y = mirrorBoot /dev/disk/by-id/`. + +Replace the disk `nvme-eui.002538b931b59865` with your own. + +Below is the configuration for `disko.nix` +```nix +{ lib, ... }: +let + mirrorBoot = idx: { + type = "disk"; + device = "/dev/disk/by-id/${idx}"; + content = { + type = "gpt"; + partitions = { + boot = { + size = "1M"; + type = "EF02"; # for grub MBR + priority = 1; + }; + ESP = lib.mkIf (idx == "nvme-eui.002538b931b59865") { + size = "1G"; + type = "EF00"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + mountOptions = [ "nofail" ]; + }; + }; + zfs = { + size = "100%"; + content = { + type = "zfs"; + pool = "zroot"; + }; + }; + }; + }; + }; +in +{ + boot.loader.systemd-boot.enable = true; + + disko.devices = { + disk = { + x = mirrorBoot "nvme-eui.002538b931b59865"; + }; + zpool = { + zroot = { + type = "zpool"; + rootFsOptions = { + compression = "lz4"; + acltype = "posixacl"; + xattr = "sa"; + "com.sun:auto-snapshot" = "true"; + mountpoint = "none"; + }; + datasets = { + "root" = { + type = "zfs_fs"; + options = { + mountpoint = "none"; + encryption = "aes-256-gcm"; + keyformat = "passphrase"; + keylocation = "file:///tmp/secret.key"; + }; + }; + "root/nixos" = { + type = "zfs_fs"; + options.mountpoint = "/"; + mountpoint = "/"; + }; + "root/home" = { + type = "zfs_fs"; + options.mountpoint = "/home"; + mountpoint = "/home"; + }; + "root/tmp" = { + type = "zfs_fs"; + mountpoint = "/tmp"; + options = { + mountpoint = "/tmp"; + sync = "disabled"; + }; + }; + }; + }; + }; + }; +} +``` + +Add this to networking.nix and **replace** the `default` values as well as the name `gchq-local` and `networking.hostId` with your own. + +```nix +{ config, lib, ... }: +{ + options = { + networking.gchq-local.ipv4.address = lib.mkOption { + type = lib.types.str; + default = "192.168.178.177"; + }; + networking.gchq-local.ipv4.cidr = lib.mkOption { + type = lib.types.str; + default = "24"; + }; + + networking.gchq-local.ipv4.gateway = lib.mkOption { + type = lib.types.str; + default = "192.168.178.1"; + }; + + networking.gchq-local.ipv6.address = lib.mkOption { + type = lib.types.str; + default = "2003:100:6701:d500:fbbc:40fb:cff3:3b87"; + }; + + networking.gchq-local.ipv6.cidr = lib.mkOption { + type = lib.types.str; + default = "64"; + }; + networking.gchq-local.ipv6.gateway = lib.mkOption { + type = lib.types.str; + default = "fe80::3ea6:2fff:feef:3435"; + }; + }; + + config = { + networking.dhcpcd.enable = false; + networking.nameservers = [ "127.0.0.1" ]; + networking.hostId = "a76ebcca"; # Needs to be unique for each host + + # The '10' in the network name is the priority, so this will be the first network to be configured + systemd.network.networks."10-eth" = { + matchConfig.Type = "ether"; + addresses = [ + { + Address=config.networking.gchq-local.ipv4.address + "/" + config.networking.gchq-local.ipv4.cidr; + } + { + Address=config.networking.gchq-local.ipv6.address + "/" + config.networking.gchq-local.ipv6.cidr; + } + ]; + DHCP = "yes"; + }; + }; +} +``` + +Put this into initrd.nix and add your pubkey to `authorizedKeys`. +Replace `kernelModules` with the ethernet module loaded one on your system. +```nix +{config, pkgs, ...}: + +{ + + boot.initrd.systemd = { + enable = true; + network.networks."10-eth" = config.systemd.network.networks."10-eth"; + }; + boot.initrd.network = { + enable = true; + + ssh = { + enable = true; + port = 7172; + authorizedKeys = [ "" ]; + hostKeys = [ + "/var/lib/initrd-ssh-key" + ]; + }; + }; + boot.initrd.availableKernelModules = [ + "xhci_pci" + ]; + + # Check the network card by running `lspci -k` on the target machine + boot.initrd.kernelModules = [ "r8169" ]; +} +``` + + +### Step 1: Copying SSH Public Key + +Before starting the installation process, ensure that the SSH public key is copied to the NixOS installer. + +1. Copy your public SSH key to the installer, if it has not been copied already: + +```bash +ssh-copy-id -o PreferredAuthentications=password -o PubkeyAuthentication=no root@nixos-installer.local +``` + +### Step 1.5: Prepare Secret Key and Clear Disk Data + +1. Access the installer using SSH: + +```bash +ssh root@nixos-installer.local +``` + +2. Create a `secret.key` file in `/tmp` using `nano` or another text editor: + +```bash +nano /tmp/secret.key +``` + +3. Discard the old disk partition data: + +```bash +blkdiscard /dev/disk/by-id/nvme-eui.002538b931b59865 +``` + +4. Run the `clan` machine installation with the following command: + +```bash +clan machines install gchq-local root@nixos-installer --yes --no-reboot +``` + +### Step 2: ZFS Pool Import and System Installation + +1. SSH into the installer once again: + +```bash +ssh root@nixos-installer.local +``` + +2. Perform the following commands on the remote installation environment: + +```bash +zpool import zroot +zfs set keystate=prompt zroot/root +zfs load-key zroot/root +zfs set mountpoint=/mnt zroot/root/nixos +mount /dev/nvme0n1p2 /mnt/boot +``` + +3. Disconnect from the SSH session: + +```bash +CTRL+D +``` + +4. Securely copy your local `initrd_rsa_key` to the installer's `/mnt` directory: + +```bash +scp ~/.ssh/initrd_rsa_key root@nixos-installer.local:/mnt/var/lib/initrd-ssh-key +``` + +5. SSH back into the installer: + +```bash +ssh root@nixos-installer.local +``` + +6. Navigate to the `/mnt` directory, enter the `nixos-enter` environment, and then exit: + +```bash +cd /mnt +nixos-enter +realpath /run/current-system +exit +``` + +7. Run the `nixos-install` command with the appropriate system path ``: + +```bash +nixos-install --no-root-passwd --no-channel-copy --root /mnt --system +``` + +8. After the installation process, unmount `/mnt/boot`, change the ZFS mountpoint, and reboot the system: + +```bash +umount /mnt/boot +cd / +zfs set mountpoint=/ zroot/root/nixos +reboot +``` + +9. Perform a hard reboot of the machine and remove the USB stick. + +### Step 3: Accessing the Initial Ramdisk (initrd) Environment + +1. SSH into the initrd environment using the `initrd_rsa_key` and provided port: + +```bash +ssh -p 7172 root@192.168.178.141 +``` + +2. Run the `systemd-tty-ask-password-agent` utility to query a password: + +```bash +systemd-tty-ask-password-agent --query +``` + +After completing these steps, your NixOS should be successfully installed and ready for use. + +**Note:** Replace `root@nixos-installer.local` and `192.168.178.141` with the appropriate user and IP addresses for your setup. Also, adjust `` to reflect the correct system path for your environment. \ No newline at end of file