# Nixos on encrypted btrfs

Nixos is heroin for tinkerers. Paradise can be tinkered together and be freely shared among peers because it’s fully reproducible! Jappie wanted more, he wanted a secure disk and a BTRFS. There used to be no guides for this, now there is.

The bullet was bitten, BTRFS was made to work on a LUKS encrypted disk. This isn’t hard, with care and precision. To help a reader we document the journey towards BTRFS. Commands compiled and included.

To prevent data loss a move plan was made. This plan also includes all resources used. Here we describe that plan in detail and compile the commands into an understandable whole.

# Getting started

Get yourself a NIXOS live usb. Boot into it. First step is to setup WIFI:

wpa_passphrase SSID PASS > /etc/wpa_supplicant.conf
systemctl restart wpa_supplicant


The first command creates a config for wpa_supplicant. The reader must fill in SSID and PASS of his target wifi network. The second command tells systemd to go restart wpa_supplicant and use the new config.

# Partitioning

Now to setup the partitioning on the RIGHT device. Choose carefully. Use lsblk to figure out which device is RIGHT. You’ll know it’s the WRONG device if you lose data after partitioning. The RIGHT device will be called $dev hence forward. There are no other partitioning tools than gdisk. Only heretics believe there are. Therefore we use gdisk: gdisk$dev


## Gdisk cheat sheet

CommandEffect
pFor printing, to see what’s going on.
dFor deletion, you should start out with deleting everything on $dev. nIs used for creating new partitions. wis used for writing once finished. This table just describes the commands needed for the intended partitioning. ## Intended partitioning Numbertypesize 1ef00+500M 28200+$(SIZE_RAM+ a little)G
38300(rest of disk)

The first partition will be boot, the second swap1, the third will be everything else. We will encrypt everything else. With type ef00 we will use UEFI for booting. Don’t worry. nix will handle that, mostly. Done. Onwards!

# Encryption

We use cryptsetup for encryption. Make sure to select the right partition. We do not want to encrypt the boot partition because then we can’t boot. So if you followed above instructions it will be either 3 or p3 (depending on device type). We’ll call it 3.

cryptsetup luksFormat "$dev"3 cryptsetup open "$dev"3 nixenc


The first command does the actual formatting, the second one opens up the formatted disk. You’ll need to provide the right password in both cases. Choose one you can remember but is strong. Once decrypted the disk will be mapped to /dev/mapper/nixenc, note that we supplied that final part in the last command.

# Formatting filesystems

Partitioning is a distinct step from setting up filesystems.

mkfs.vfat -n boot "$dev"1 mkswap "$dev"3
swapon "$dev"3 mkfs.btrfs -L root /dev/mapper/nixenc  The boot partition will be vfat because UEFI tells us to. The everything else partition will be btrfs, because why are you following this guide if not? Note that we point it at the mapped file, if the "$dev"3device were to be used directly we’d remove the encryption.

# Moutning and subvolumes

Wouldn’t it be nice to have subvolumes on your BTRFS? This is not cargo culted at all.

mount -t btrfs /dev/mapper/nixenc /mnt/
btrfs subvol create /mnt/nixos
umount /mnt
mount -t btrfs -o subvol=nixos /dev/mapper/nixenc /mnt


First we create a nixos subvolume below the root subvolume, eg the nixos operating system will not be installed in the root, but one node below the root, allowing potentially more operating systems to be installed on the same partition. Reverse explaining cargo culting behavior, this maybe a good idea.

btrfs subvol create /mnt/home


Setting up a subvolume for home allows btrfs based backups. I used too also make subvolumes for tmp2 and var, but I don’t see the merit in that.

mkdir /mnt/boot
mount "\$dev"1 /mnt/boot


Here we mount the boot partition. Just to make it detectable by the nix config generation script.

## Did I do everything right?

Doing this a second time my speed made me skeptical, to verify everything was sane I used the following commands.

mount | grep /mnt
ls /mnt


The first command is to check if the encrypted volume and boot is mounted at the right paths. The second one to verify the folders are created, which are subvolumes. The subvolume command creates a folder so if it exists we presume it worked. But if you’re really unsure you can use btrfs subvol list /mnt/.

# Configure nix

We can use hardware detection to figure out how to setup nix on this setup:

nixos-generate-config --root /mnt


Done.

Now the user needs to write his own nix config, or copy mine or cherry pick whatever they need (recommend).

Once configuration is done we can install nix:

nixos-install


Don’t worry, we can use nixos-rebuild switch to reconfigure nix whenever once we’re booted into it. Hopefully we boot successfully:

reboot


Booting is hard, don’t worry if this goes wrong the first 10 30 times.

You may need to enable UEFI in your BIOS. It’s up to the reader to figure that part out. (press some f keys on boot, f11 maybe?). Alternatively one could setup grub. Good luck with that.

You can’t read the rest of this post until you’ve booted, go back if you haven’t, you messed up.

# Final steps

Once rebooted you may be stuck at the display manager. Use Alt+f1 to switch to another TTY and login as root, then use passwd your-user-name to set an initial password. Use Alt+f7 to go back to the display manager.

I personally haven’t moved all my configuration into nix yet (it’s a big project), but I wrote a script that symlinks all dotfiles, and hardlinks the configuration.nix to my linux-config project.

# Conclusion

The manual step of setting up BTRFS on an encrypted volume were described. Nix is of course fully self installing so once the partitions were setup and mounted right for hardware detection, we were done.

1. This one is optional but allows hibernation. Which is very convenient for laptops. It can also make your system more stable. Note that Swap files are bad on BTRFS

2. If you want a subvolume for /tmp, make sure to chmod it to 777 Otherwise various applications get upset. Pulse audio for example doesn’t work well if it can’t write into /tmp

nixos linux