Full Disk Encryption

From NixOS Wiki
Revision as of 16:04, 27 August 2017 by imported>Fadenb (Syntax highlighting)

Basic installation

Unattended Boot via USB

Sometimes it is necessary to boot a system without needing an Keyboard and Monitor. You will create a secret key, add it to a key slot and put it onto an usb stick.

dd if=/dev/urandom of=hdd.key bs=4096 count=1
cryptsetup luksAddKey /dev/sda1 ./hdd.key

Option 1: Write key onto the start of the stick

This will make the usb-stick unusable for any other operations than being used for decryption. Write they key onto the stick: dd if=hdd.key of=/dev/sdb.

Then add the following configuration to your configuration.nix:

{
  "..."

  boot.initrd.luks.devices = [
    { 
      name = "luksroot";
      device = "/dev/disk/by-id/<disk-name>-part2";
      allowDiscards = true;
      keyFileSize = 4096;
      # pinning to /dev/disk/by-id/usbkey works
      keyFile = "/dev/sdb";
    }
  ];
}

As of right now (2017-08-18) the NixOS options do not provide means to hide a key after the MBR as described in this article in the archlinux forums. More specificially you will need to be able to provide a keyOffset

Option 2: Copy Key as file onto a vfat usb stick

If you want to use your stick for other stuff or it already has other keys on it you can use the following method by Tzanko Matev. Add this to your configuration.nix:

let
  PRIMARYUSBID = "b501f1b9-7714-472c-988f-3c997f146a17";
  BACKUPUSBID = "b501f1b9-7714-472c-988f-3c997f146a18";
in {

  "..."

  # Kernel modules needed for mounting USB VFAT devices in initrd stage
  boot.initrd.kernelModules = ["uas" "usbcore" "usb_storage" "vfat" "nls_cp437" "nls_iso8859_1"];

  # Mount USB key before trying to decrypt root filesystem
  boot.initrd.postDeviceCommands = pkgs.lib.mkBefore ''
    mkdir -m 0755 -p /key
    sleep 2 # To make sure the usb key has been loaded
    mount -n -t vfat -o ro `findfs UUID=${PRIMARYUSBID}` /key || mount -n -t vfat -o ro `findfs UUID=${BACKUPUSBID}` /key
  '';

  boot.initrd.luks.devices."crypted" = {
    keyFile = "/key/keyfile";
    preLVM = false; # If this is true the decryption is attempted before the postDeviceCommands can run
  };
}

Option 3: Decryption via YubiKey

TODO, it works but needs to be described.