USB_Keyfile
USB Stick Keyfile
This allows you to use a USB stick for your keyfile, with a backup in case you
want or need it. There is a setting fallbackToPassword
that protects you in
case something fails with the USB key.
First, I’ll show how to set up a dedicated USB stick for a keyfile. (i.e., one that is only used for this). After that I will show the process of adding the keyfile to a USB stick with existing data on it that you don’t want to lose.
Generate the keyfile
sudo dd if=/dev/urandom of=/root/usb-luks.key bs=4096 count=1
This is for a dedicated USB stick that we will wipe first then add the key.
sudo cryptsetup luksAddKey /dev/disk/by-partlabel/luks /root/usb-luks.key
/dev/disk/by-partlabel/luks
refers to your encrypted partition by its partition label, which is stable and less likely to change than/dev/nvme0n1p2
/root/usb-luks.key
is the keyfile we generated.You’ll be prompted to enter your existing LUKS passphrase to authorize adding the new key.
Now our LUKS volume will accept both our existing passphrase and the new keyfile (from the USB stick) for unlocking.
- Clear Data on USB stick and replace with 0’s
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sda 8:0 1 239M 0 disk
sdb 8:16 1 1.4M 0 disk /run/media/jr/7CD1-149A # Example USB mount
zram0 253:0 0 7.5G 0 disk [SWAP]
nvme0n1 259:0 0 476.9G 0 disk
├─nvme0n1p1 259:1 0 512M 0 part /boot
└─nvme0n1p2 259:2 0 476.4G 0 part
└─cryptroot 254:0 0 476.4G 0 crypt /persist # Main Btrfs mount
# (other subvolumes are within /persist and bind-mounted by impermanence)
# unplug the device and run lsblk again so your sure
- Before wiping you must unmount any mounted partitions:
sudo umount /dev/sda1
# Overwrite with Zeros (fast, sufficient for most uses)
sudo dd if=/dev/zero of=/dev/sda bs=4M status=progress
# Or overwrite with Random Data (More Secure, Slower)
sudo dd if=/dev/urandom of=/dev/sda bs=4M status=progress
# Or for the most secure way run multiple passes of
sudo shred -v -n 3 /dev/sda
- Create a New Partition and Format (Optional)
sudo fdisk /dev/sda
Press
o
to create a new empty DOS partition table.Press
n
to create the new partitionPress
w
to write the changes.
Formats as FAT32:
sudo mkfs.vfat /dev/sda1
# or as ext4
sudo mkfs.ext4 /dev/sda1
I chose vfat
so I ran sudo mkfs.vfat /dev/sda1
. In my case this changed the
device path to /run/media/jr/7CD1-149A
so it’s important to find your own UUID
with the following command:
sudo blkid /dev/sda1
/dev/sda1: SEC_TYPE="msdos" UUID="B7B4-863B" BLOCK_SIZE="512" TYPE="vfat" PARTUUID="7d1f9d7f-01"
As you can see the above UUID is
"B7B4-863B"
Remove and re-insert the USB stick, this ensures the system recognizes the new partition and filesystem.
- Copy the keyfile to your USB Stick
sudo cp /root/usb-luks.key /run/media/jr/B7B4-863B/
sync
- Securely Remove the Keyfile from Your System
sudo shred --remove --zero /root/usb-luks.key
- Update your NixOS Configuration
Note the output of blkid /dev/sda1
and if you have a backup device list that
also:
The following is from the wiki edited for my setup, it was created by Tzanko Matev:
let
PRIMARYUSBID = "B7B4-863B";
BACKUPUSBID = "Ventoy";
in {
boot.initrd.kernelModules = [
"uas"
"usbcore"
"usb_storage"
"vfat"
"nls_cp437"
"nls_iso8859_1"
];
boot.initrd.postDeviceCommands = lib.mkBefore ''
mkdir -p /key
sleep 2
mount -n -t vfat -o ro $(findfs UUID=${PRIMARYUSBID}) /key || \
mount -n -t vfat -o ro $(findfs UUID=${BACKUPUSBID}) /key || echo "No USB key found"
'';
boot.initrd.luks.devices.cryptroot = {
device = "/dev/disk/by-partlabel/luks";
keyFile = "/key/usb-luks.key";
fallbackToPassword = true;
allowDiscards = true;
preLVM = false; # Crucial!
};
}
If you have issues or just want to remove the key take note of the path used to add it so you don’t have to enter the whole key:
sudo cryptsetup luksRemoveKey /dev/disk/by-partlabel/luks --key-file /root/usb-luks.key
Instructions for Using a USB Stick with Existing Data
- Generate the Keyfile
sudo dd if=/dev/urandom of=/root/usb-luks.key bs=4096 count=1
- Add the Keyfile to your LUKS Volume
sudo cryptsetup luksAddKey /dev/disk/by-partlabel/luks /root/usb-luks.key
(enter your existing passphrase when prompted)
- Copy the Keyfile to the USB Stick
Plug in the USB Stick and note its mount point (e.g.,
/run/media/$USER/YourLabel
)Copy the keyfile:
sudo cp /root/usb-luks.key /run/media/$USER/YourLabel/
sync
You run the above as 2 commands, the second being
sync
.You can rename it if you wish (e.g.,
luks.key
)
- Securely Delete the Local Keyfile
sudo shred --remove --zero /root/usb-luks.key
- You need to ensure the keyfile is accessible in the initrd. Since automounting
(like
/run/media/...
) does not happen ininitrd
, you must manually mount the USB in theinitrd
using itsUUID
or label.
Find the USB Partition UUID:
lsblk -o NAME,UUID
# or
blkid /dev/sda1
Suppose the UUID is B7B4-863B
Add to your configuration.nix
:
boot.initrd.kernelModules = [ "usb_storage" "vfat" "nls_cp437" "nls_iso8859_1" ];
boot.initrd.postDeviceCommands = lib.mkBefore ''
mkdir -p /key
sleep 1
mount -n -t vfat -o ro $(findfs UUID=B7B4-863B) /key || echo "USB not found"
'';
boot.initrd.luks.devices.cryptroot = {
device = "/dev/disk/by-partlabel/luks";
keyFile = "/key/usb-luks.key"; # or whatever you named it
fallbackToPassword = true;
allowDiscards = true;
};