Typing passwords is a chore

It’s tedious and unlocking your drive in public is also less secure.

Fortunately, you can handle the unlocking process using a simple 1$ USB stick.

boot = {
  tmp.cleanOnBoot = true;
  loader.efi.canTouchEfiVariables = false;
  supportedFilesystems = [ "zfs" ];
  loader.timeout = 1;

  loader.grub = {
    enable = true;
    device = "nodev";
    enableCryptodisk = true;
    zfsSupport = true;
    efiSupport = true;
    efiInstallAsRemovable = true;
    mirroredBoots = [
      {
        devices = [ "nodev" ];
        path = "/boot";
      }
    ];
  };

  initrd.kernelModules = [
    "usb_storage"
    "vfat"
    "nls_cp437"
  ];

  initrd.systemd = {
    enable = true;
    contents."/etc/fstab".text = ''
      LABEL=Usbkey   /key   vfat   defaults,nofail,x-systemd.device-timeout=5   0   2
    '';
  };

  initrd.luks.devices = {
    root = {
      device = "/dev/disk/by-uuid/dddddddd-dddd-dddd-dddd-dddddddddddd";
      keyFile = "/key/KEYFILE";
      fallbackToPassword = true;
    };
  };
};

I use ZFS, but you can simply omit the options related to it.

The general idea is to add systemd to the initrd and use standard fstab syntax to mount our USB drive with LUKS key.

In my case, the USB has the label “Usbkey”, replace it with your label or use UUID. It is also best to use a simple filesystem like FAT and, of course, add the appropriate kernel modules.

Run ls -l /dev/disk/by-uuid to find your UUID.

KEYFILE is just a file serving as the key in the root directory of the USB, you can generate it with: dd if=/dev/urandom of=/mnt/myusb/KEYFILE bs=4096 count=1

Then, add this key to your LUKS drive:

cryptsetup luksAddKey /dev/sdx /mnt/myusb/KEYFILE

Remember to back it up.