For my desktop, I set up NixOS with an encrypted root partition. The steps taken
were not obvious to me from the official documentation, so I'll be documenting them
here for future reference. The setup described uses LVM inside a luks-encrypted root
partition and a unencrypted /boot
partition for EFI.
Installation media
NixOS provides two .iso
images you can boot for the installation: A
full-fledged graphical installer
and a minimal image
without a desktop environment, you can use either of them for the following. I
went with the graphical image and did the following steps in the provided
terminal emulator, but the procedure in a TTY should be identical.
To create a bootable usb-stick, do as you would for any other Linux distribution. Lazy people seem to like balena etcher, I went with the traditional command-line approach.
Fun fact: Did you know that you don't need the "standard" dd bs=4M if=path/to/nixos.iso of=/dev/sdX status=progress oflag=sync
that all wikis seem
to love? Using cat
is more than enough:
In either case, triple-check that your device (here: /dev/sdX
) is correct!
I like to use lsblk
to list devices.
Smashing keys get into BIOS
In case your stick boots right up, you can skip this paragraph. While it
should boot, I've yet to encounter a single time this works on the first try.
Once you have found the key to get into the BIOS of your motherboard (by
smashing f1
, f2
, f10
, f12
, Delete
, Enter
until you get it right),
here are a few common settings to check that have caused me trouble in the past.
In particular, I usually disable legacy boot completely in favor of EFI, so I can
be sure it won't randomly switch to legacy mode.
- Check boot order
- Disable Secure Boot
- Disable USB legacy boot
- Enable Launch CSM
Partitioning
Partitioning in NixOS is manual and mostly the same as you would do in Arch or
any other "minimal" distribution. You can use gparted
if you decided to boot
the graphical installer, but I find the process simpler with good-old gdisk
.
We will be creating two partitions:
- EFI partition (500M)
- Encrypted physical volume for LVM (remaining space)
Furthermore, LVM will be used inside the encrypted physical volume and I will be adding 8G of swap. For the thoroughly-paranoid this has the added benefit, that the swap partition will also be encrypted.
Assuming the drive you want to install to is /dev/sda
, run gdisk /dev/sda
and create the partitions:
o
: Create empty gpt partition table)n
: Add partition, first sector: default, last sector: +500M, typeef00 EFI
n
: Add partition, remaining space, type8e00 Linux LVM
w
: Write partition table and exit
We can now set up the encrypted LUKS partition and open it using cryptsetup
We create two logical volumes, a 8 GB swap partition and the rest will be our root file system
Format the partitions:
Installing NixOS
The partitions just created have to be mounted, e.g. to /mnt
so we can install
NixOS on them. At this point activating the swap (if you created one) is a good
idea. The /boot
partion is mounted in a new folder /mnt/boot
inside the
root partition.
If you already have a configuration file for your system, you can place it now
in /etc/nixos/configuration.nix
. You can also let NixOS generate a working
template for you and modify it to your liking.
The command above will set everything up for you in /etc/nixos/
crating a
configuration.nix
and a hardware.nix
file for you. In most cases you will
want to make changes, just use any text-editor and open configuration.nix
.
There are a few options you will have to change to make your drive bootable,
since it has to be decrypted.
This setup is tested with GRUB2. You can use any boot-loader that supports luks,
but the following options should give you a working system. Notice that we use
version 2
of grub and set the device
to nodev
. Cleaning up the /tmp
dir
is not really necessary, but I like to have it deleted on boot so nothing gets
left behind.
# Use the Grub2 as bootloader.
boot.loader.grub.enable = true;
boot.loader.grub.version = 2;
boot.loader.grub.device = "nodev";
boot.loader.grub.efiSupport = true;
boot.loader.efi.canTouchEfiVariables = true;
boot.cleanTmpDir = true;
Next up: Decryption and LVM. You need to tell nix how to handle your drive
setup. To get the UUID
of your drive, run blkid
on it
Add the correct UUID
and your config should look something like this:
boot.initrd.luks.devices = {
root = {
# Get UUID from blkid /dev/sda2
device = "/dev/disk/by-uuid/f4aaaf6d-4eb3-4a2d-a35e-f8e780ac0110";
preLVM = true;
allowDiscards = true;
};
};
Unstable channel (optional)
I use the unstable
branch on some of my machines. These include configuration
options not present in the current stable branch (currently 20.09
). To be able
to install such config, you can just switch the installer to unstable:
That's all! From here, you can modify your config like normally and include any services, accounts, pkgs, configs that you want. The procedure from here on is the same as with a non-encrypted drive. When you're happy with the configuration, install NixOS and reboot into your new system.
Troubleshooting
Still here? Well, I guess something went wrong. If for whatever reason the system doesn't boot, we can go back to the installation environment by booting from the installation media and remounting all partitions:
Fix it and try again until it works ;)