- Encrypt everthing including /boot and /root
- Enter password once
- Support UEFI
Download NixOS minimal iso and copy to USB stick. For example on Mac OSX
$ diskutil list
$ diskutil unmountDisk /dev/disk1 # Make sure you got right device
$ dd if=nixos-minimal-20.09.2405.e065200fc90-x86_64-linux.iso of=/dev/disk1
Boot from the USB stick and setup networking. (optionally setup SSH if you want to complete the install from another computer)
$ wpa_passphrase SSID 'PASSWORD' > /etc/wpa_supplicant.conf
$ systemctl start wpa_supplicant
$ systemctl start sshd
$ passwd # So we can login via SSH
I have 2 drives on my system: NVME SSD and a regular SATA drive. This is what the drives should look like after install. I use NVME SSD for booting
and SATA drive as a /data
mount.
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 931.5G 0 disk
└─sda1 8:1 0 931.5G 0 part
└─crypted-data 254:3 0 931.5G 0 crypt /data
nvme0n1 259:0 0 465.8G 0 disk
├─nvme0n1p1 259:1 0 549M 0 part /boot/efi
└─nvme0n1p2 259:2 0 465.2G 0 part
└─root 254:0 0 465.2G 0 crypt
├─vg-swap 254:1 0 4G 0 lvm [SWAP]
└─vg-root 254:2 0 461.2G 0 lvm /
The only unecrypted partition is nvme0n1p1
, which is mounted on /boot/efi
. But rest of /boot
is encrypted along with swap and root. /dev/sda1
is also encrypted and mounted as /data
(Note: If you plan on extending /data
with more drives, you should do LUKS-on-LVM )
Use Use gdisk
to partition the drives
$ gdisk /dev/nvme0n1
o
Create partition tablen
Create new partition of size 550M and of typeef00
n
Create another partition of type8300
and use remainig spacep
Show what gdisk will writew
Write to disk an exit
$ gdisk /dev/sda
o
Create partition tablen
Create another partition of type8300
and use all spacep
Show what gdisk will writew
Write to disk an exit
$ dd if=/dev/urandom of=./keyfile0.bin bs=1024 count=4
$ dd if=/dev/urandom of=./keyfile1.bin bs=1024 count=4
# Enter the passphrase which is used to unlock disk. You will enter this in grub on every boot
$ cryptsetup luksFormat --type luks1 -c aes-xts-plain64 -s 256 -h sha512 /dev/nvme0n1p2
# Add a second key which will be used by nixos. You will need to enter the pasphrase from previous step
$ cryptsetup luksAddKey /dev/nvme0n1p2 keyfile0.bin
$ cryptsetup luksOpen /dev/nvme0n1p2 crypted-nixos -d keyfile0.bin
# For /data just the second random generated key
$ cryptsetup luksFormat -c aes-xts-plain64 -s 256 -h sha512 /dev/sda1 -d keyfile1.bin
$ cryptsetup luksOpen /dev/sda1 crypted-data -d keyfile1.bin
$ pvcreate /dev/mapper/crypted-nixos
$ vgcreate vg /dev/mapper/crypted-nixos
$ lvcreate -L 4G -n swap vg
$ lvcreate -l '100%FREE' -n root vg
$ mkfs.fat -F 32 /dev/nvme0n1p1
$ mkswap -L swap /dev/vg/swap
$ mkfs.ext4 -L root /dev/vg/root
$ mkfs.ext4 -L data /dev/mapper/crypted-data
$ mount /dev/vg/root /mnt
$ mkdir -p /mnt/boot/efi
$ mount /dev/nvme0n1p1 /mnt/boot/efi
$ swapon /dev/vg/swap
$ mkdir -p /mnt/etc/secrets/initrd/
$ cp keyfile0.bin keyfile1.bin /mnt/etc/secrets/initrd
$ chmod 000 /mnt/etc/secrets/initrd/keyfile*.bin
$ nixos-generate-config --root /mnt
Add the following to /mnt/etc/nixos/configuration.nix
boot.loader.efi.canTouchEfiVariables = true;
boot.loader.efi.efiSysMountPoint = "/boot/efi";
boot.loader.grub = {
enable = true;
device = "nodev";
version = 2;
efiSupport = true;
enableCryptodisk = true;
};
boot.initrd = {
luks.devices."root" = {
device = "/dev/disk/by-uuid/a8b302cf-5296-4a2e-a7ba-707e6fa75123"; # UUID for /dev/nvme01np2
preLVM = true;
keyFile = "/keyfile0.bin";
allowDiscards = true;
};
secrets = {
# Create /mnt/etc/secrets/initrd directory and copy keys to it
"keyfile0.bin" = "/etc/secrets/initrd/keyfile0.bin";
"keyfile1.bin" = "/etc/secrets/initrd/keyfile1.bin";
};
};
# Data mount
fileSystems."/data" = {
device = "/dev/disk/by-uuid/79630267-5766-4c7d-85a5-1d5f1dcd58ad"; # UUID for /dev/mapper/crypted-data
encrypted = {
enable = true;
label = "crypted-data";
blkDev = "/dev/disk/by-uuid/3476cb09-b3c4-4301-9ec9-84f60f32828a"; # UUID for /dev/sda1
keyFile = "/keyfile1.bin";
};
};
You can get the UUIDs by running
$ blkid
Install NixOS and reboot
$ nixos-install
$ reboot
Thats it! Once you reboot, GRUB will ask for the password. If password is correct, GRUB will show you the NixOS system profiles menu. After that, your system will boot without asking for the disk password.
If I enter an incorrect disk password, GRUB does not handle it gracefully. It will drop me into a shell without re-prompting for a password. I have to run the following commands for it to prompt again. Need to figure out if GRUB has an option for it to re-prompt.
cryptomount hdX,gptY # Device to mount: drive X, GPT partition Y, this forces the re-prompt.
insmod normal # Load the normal mode boot module.
normal # Enter normal mode and display the GRUB menu.
- Installation of NixOS with encrypted root by martijnvermaat
- Full disk encryption with LUKS (including /boot) by Pavel Kogan
- dm-crypt/Encrypting an entire system by ArchLinux wiki
- EmilGedda
- ElvishJerricco
- whoizit
- starfys
- WolfangAukang
- Dom-R
I believe the use of path literal syntax will cause
initrd.keys.gz
to be placed in your nix store, allowing all users to read the file. Just putting the path in a string literal will have the same functionality but won't put it in the nix store.Anyway thanks for this. Very useful!