Talk: Yubikey based Full Disk Encryption (FDE) on NixOS: Difference between revisions
→Can I update/improve this page: new section |
No edit summary |
||
| Line 4: | Line 4: | ||
If it's useful I can add it here | If it's useful I can add it here | ||
With sgillespie's repo, I created a disko config (more install instructions in my repo at https://github.com/David-Kopczynski/nix/tree/ab49a243d25caf5879eee5191d8a3424e299c752/hosts/laptop): | |||
<syntaxhighlight lang="nix"> | |||
{ | |||
pkgs ? import <nixpkgs> { }, | |||
... | |||
}: | |||
{ | |||
disko.devices.disk = | |||
# Default disk setup using EFI partition with LUKS | |||
{ | |||
"system" = { | |||
device = "/dev/nvme0n1"; | |||
type = "disk"; | |||
preCreateHook = '' | |||
mkdir -p /tmp/disko | |||
ITERATIONS=1000000 | |||
rbtohex() { ( od -An -vtx1 | tr -d ' \n' ) } | |||
hextorb() { ( tr '[:lower:]' '[:upper:]' | sed -e 's/\([0-9A-F]\{2\}\)/\\\\\\x\1/gI'| xargs printf ) } | |||
SALT="$(dd if=/dev/random bs=1 count=16 2>/dev/null | rbtohex)" | |||
CHALLENGE="$(echo -n "$SALT" | ${with pkgs; openssl}/bin/openssl dgst -binary -sha512 | rbtohex)" | |||
RESPONSE=$(${with pkgs; yubikey-personalization}/bin/ykchalresp -2 -x "$CHALLENGE" 2>/dev/null) | |||
LUKS_KEY="$(echo | ${ | |||
pkgs.callPackage "${ | |||
pkgs.fetchFromGitHub { | |||
owner = "sgillespie"; | |||
repo = "nixos-yubikey-luks"; | |||
rev = "master"; | |||
sha256 = "sha256-qmvBrvSo30kW+meehETdgjvxCmrWrc5cBBGdViJ39gU="; | |||
} | |||
}/pbkdf2-sha512" { } | |||
}/bin/pbkdf2-sha512 $((512 / 8)) $ITERATIONS "$RESPONSE" | rbtohex)" | |||
echo -n "$LUKS_KEY" | hextorb > /tmp/disko/key-file | |||
echo -ne "$SALT\n$ITERATIONS" > /tmp/disko/crypt-storage | |||
''; | |||
postCreateHook = '' | |||
rm /tmp/disko/key-file | |||
''; | |||
postMountHook = '' | |||
mkdir -p /mnt/boot/crypt-storage | |||
cp /tmp/disko/crypt-storage /mnt/boot/crypt-storage/default | |||
''; | |||
content = { | |||
type = "gpt"; | |||
partitions = { | |||
"ESP" = { | |||
priority = 1; | |||
size = "512M"; | |||
type = "EF00"; | |||
content = { | |||
type = "filesystem"; | |||
format = "vfat"; | |||
mountpoint = "/boot"; | |||
mountOptions = [ "umask=0077" ]; | |||
}; | |||
}; | |||
"crypted" = { | |||
priority = 2; | |||
size = "100%"; | |||
content = { | |||
type = "luks"; | |||
name = "crypted"; | |||
extraOpenArgs = [ | |||
"--cipher aes-xts-plain64" | |||
"--key-size 512" | |||
"--hash sha512" | |||
]; | |||
settings = { | |||
allowDiscards = true; | |||
keyFile = "/tmp/disko/key-file"; | |||
}; | |||
content = { | |||
type = "lvm_pv"; | |||
vg = "vg"; | |||
}; | |||
}; | |||
}; | |||
}; | |||
}; | |||
}; | |||
}; | |||
disko.devices.lvm_vg = | |||
# Simple LVM setup on top of LUKS | |||
{ | |||
"vg" = { | |||
type = "lvm_vg"; | |||
lvs = { | |||
"root" = { | |||
size = "100%"; | |||
content = { | |||
type = "filesystem"; | |||
format = "ext4"; | |||
mountpoint = "/"; | |||
mountOptions = [ "defaults" ]; | |||
}; | |||
}; | |||
"swap" = { | |||
size = "32G"; | |||
content = { | |||
type = "swap"; | |||
resumeDevice = true; | |||
}; | |||
}; | |||
}; | |||
}; | |||
}; | |||
} | |||
</syntaxhighlight> | |||
(This generates the LUKS key with the YubiKey plugged in and places the seed + iteration count at the correct location!) | |||
== Can I update/improve this page == | == Can I update/improve this page == | ||
Latest revision as of 09:52, 6 April 2025
I've also added a nix expression to set up a shell:
https://github.com/sgillespie/nixos-yubikey-luks
If it's useful I can add it here
With sgillespie's repo, I created a disko config (more install instructions in my repo at https://github.com/David-Kopczynski/nix/tree/ab49a243d25caf5879eee5191d8a3424e299c752/hosts/laptop):
{
pkgs ? import <nixpkgs> { },
...
}:
{
disko.devices.disk =
# Default disk setup using EFI partition with LUKS
{
"system" = {
device = "/dev/nvme0n1";
type = "disk";
preCreateHook = ''
mkdir -p /tmp/disko
ITERATIONS=1000000
rbtohex() { ( od -An -vtx1 | tr -d ' \n' ) }
hextorb() { ( tr '[:lower:]' '[:upper:]' | sed -e 's/\([0-9A-F]\{2\}\)/\\\\\\x\1/gI'| xargs printf ) }
SALT="$(dd if=/dev/random bs=1 count=16 2>/dev/null | rbtohex)"
CHALLENGE="$(echo -n "$SALT" | ${with pkgs; openssl}/bin/openssl dgst -binary -sha512 | rbtohex)"
RESPONSE=$(${with pkgs; yubikey-personalization}/bin/ykchalresp -2 -x "$CHALLENGE" 2>/dev/null)
LUKS_KEY="$(echo | ${
pkgs.callPackage "${
pkgs.fetchFromGitHub {
owner = "sgillespie";
repo = "nixos-yubikey-luks";
rev = "master";
sha256 = "sha256-qmvBrvSo30kW+meehETdgjvxCmrWrc5cBBGdViJ39gU=";
}
}/pbkdf2-sha512" { }
}/bin/pbkdf2-sha512 $((512 / 8)) $ITERATIONS "$RESPONSE" | rbtohex)"
echo -n "$LUKS_KEY" | hextorb > /tmp/disko/key-file
echo -ne "$SALT\n$ITERATIONS" > /tmp/disko/crypt-storage
'';
postCreateHook = ''
rm /tmp/disko/key-file
'';
postMountHook = ''
mkdir -p /mnt/boot/crypt-storage
cp /tmp/disko/crypt-storage /mnt/boot/crypt-storage/default
'';
content = {
type = "gpt";
partitions = {
"ESP" = {
priority = 1;
size = "512M";
type = "EF00";
content = {
type = "filesystem";
format = "vfat";
mountpoint = "/boot";
mountOptions = [ "umask=0077" ];
};
};
"crypted" = {
priority = 2;
size = "100%";
content = {
type = "luks";
name = "crypted";
extraOpenArgs = [
"--cipher aes-xts-plain64"
"--key-size 512"
"--hash sha512"
];
settings = {
allowDiscards = true;
keyFile = "/tmp/disko/key-file";
};
content = {
type = "lvm_pv";
vg = "vg";
};
};
};
};
};
};
};
disko.devices.lvm_vg =
# Simple LVM setup on top of LUKS
{
"vg" = {
type = "lvm_vg";
lvs = {
"root" = {
size = "100%";
content = {
type = "filesystem";
format = "ext4";
mountpoint = "/";
mountOptions = [ "defaults" ];
};
};
"swap" = {
size = "32G";
content = {
type = "swap";
resumeDevice = true;
};
};
};
};
};
}
(This generates the LUKS key with the YubiKey plugged in and places the seed + iteration count at the correct location!)
Can I update/improve this page
Hi! I'm fairly new to nix/NixOS and tried this guide to rebuild my Yubikey based decryption which I previously used in Arch. While following the guide, I found some issues and also see some improvements:
- while the SLOT is definded as env variable, the "2" is hardcoded in the yubikey commands
- the /dev/partition paths didn't work on my VM using NixOS 23.05, I'd use the "old" paths /dev/mapper/<name> instead
- I would add a section that tries to close and reopen the luks device with the new credentials to test if the setup was successful
- I would add a section which adds a password as a Backup decryption method (addresses https://github.com/sgillespie/nixos-yubikey-luks/issues/7)
Can I simply edit the page with those changes or is there some PR/review process for the wiki pages?