NixOS installation guide (with encrypted root)
Preparing Installation media
The NixOS ISO used is NixOS minimal iso.
dd bs=4M if=nixos-minimal-21.05.3216.ebf419e737b-x86_64-linux.iso of=/dev/sdb
Booting the Installer
- Disable Secure Boot Control
- Disable USB legacy boot
- Enable Launch CSM
Once logged in, login as root user as most commands will require root permissions.
sudo su
Internet connection
Wireless
First identify the name of your wireless interface
iw dev
phy#0
Interface wlp3s0
ifindex 2
wdev 0x1
addr 00:17:6c:11:6c:c6
type managed
In this example, wlp3s0 is the available wireless interface, if you are unsure, your wireless interface is likely to start with the letter "w" and unlikely to be "lo" or start with the letter "e".
Bring the interface up with:
ip link set wlp3s0 up
Scan for available networks:
iw dev wlp3s0 scan | grep SSID
Connect to a network:
wpa_supplicant -B -i wlp3s0 -c <(wpa_passphrase "ssid" "psk")
Finally, you have to your interface an IP address. This can be set manually or using the dhcp:
dhcpcd wlp3s0
If that does not work, issue the following commands:
echo 'ctrl_interface=DIR=/run/wpa_supplicant' > /etc/wpa_supplicant.conf
wpa_passphrase >> /etc/wpa_supplicant.conf
ip link set up # May not be needed as dhcpcd should bring it up but may be needed for wpa_supplicant.
wpa_supplicant -B -D nl80211 -c /foobar.conf -i
dhcpcd -A
Wiping the disk
You want to make sure that the device you’re using doesn’t contain any plaintext copies of your personal data. If the drive is new, then you can skip the rest of this section; if it’s not new, then there are two ways to handle it:
The storage device is probably /dev/sda, always double check to be sure:
lsblk
If the drive were not previously encrypted, securely wipe it with the dd command; you can either choose to fill it with zeroes or random data; I chose random data (e.g., urandom), because it’s more secure. Depending on the size of the drive, this could take a while to complete:
dd if=/dev/urandom of=/dev/sdb; sync
If the drive were previously encrypted, all you need to do is wipe the LUKS header. The size of the header depends upon the specific model of the hard drive; you can find this information by doing some research online. Refer to this article, for more information about LUKS headers. You can either fill the header with zeroes, or with random data; again, I chose random data, using urandom:
head -c 3145728 /dev/urandom > /dev/sda; sync
Partitioning
Depending on your hardware, you should follow either the DOS or (U)EFI partitioning instructions. Check if the device is UEFI or legacy BIOS:
[ -d /sys/firmware/efi ] && echo "UEFI" || echo "BIOS"
lsblk
The partitioning program used here is fdisk, however any others like cfdisk or gdisk can be used to achieve the same result.
Legacy BIOS Instructions
fdisk /dev/sdX
- o (dos disk label)
- n new
- p primary (4 primary in total)
- 1 (partition number [1/4])
- 2048 first sector (alignment for perfomance)
- +500M last sector (boot sector size)
- rm signature (Y), if ex. => warning of overwriting existing system, could use wipefs
- n new
- p
- 2
- default (fill up partition)
- default (fill up partition)
- w (write)
UEFI Instructions
fdisk /dev/sdX
- g (gpt disk label)
- n new
- 1 (partition number [1/128])
- 2048 first sector
- +500M last sector (boot sector size)
- t
- 1 (EFI System)
- n
- 2
- default (fill up partition)
- default (fill up partition)
- w (write)
Setup the encrypted LUKS partition and open it:
cryptsetup luksFormat /dev/sda2
cryptsetup config /dev/sda2 --label NIXOS_LUKS_PARTITION
cryptsetup luksOpen /dev/sda2 enc-pv
We create two logical volumes, a 8GB swap parition and the rest will be our root filesystem:
pvcreate /dev/mapper/enc-pv
pvdisplay
vgcreate vg /dev/mapper/enc-pv
vgdisplay
lvcreate -L 2G -n NixOS_SWAP vg
lvcreate -l '100%FREE' -n NixOS_ROOT vg
lvdisplay
Format the partitions:
mkfs.fat -F 32 /dev/sda1
fatlabel /dev/sda1 NixOS_BOOT
mkfs.ext4 -L NixOS_ROOT /dev/vg/NIXOS_ROOT
mkswap -L NixOS_SWAP /dev/vg/NIXOS_SWAP
Installing NixOS
We mount the partitions we just created under '/mnt' so we can install NixOS on them.
mount /dev/disk/by-label/NixOS_ROOT /mnt
mkdir /mnt/boot
mount /dev/disk/by-label/NixOS_BOOT /mnt/boot/
swapon /dev/vg/NixOS_SWAP
WPA supplicant configuration to be able to use WIFI:
cat > /etc/wpa_supplicant.conf
network = {
ssid="****"
psk="****"
}
^D
systemctl start wpa_supplicant
Generate NixOS configuration and modify it to your liking.
nixos-generate-config --root /mnt
vim /mnt/etc/nixos/configuration.nix
The following config is just a start to give an idea of how to configure.
{ config, lib, pkgs, ... }: {
imports = [ ./hardware-configuration.nix ];
boot = {
loader = {
efi = {
canTouchEfiVaribles = true;
efiSysMountPoint = "/boot/efi";
};
grub = {
device = "nodev"
efiInstallAsRemovable = true;
efiSupport = true;
enable = true;
enableCryptodisk = true;
};
};
initrd.luks.devices = {
"root" = {
allowDiscards = true;
device = "/dev/disk/by-label/NIXOS_LUKS_PARTITION";
preLVM = true;
}
};
};
networking = {
hostName = "laptop";
interfaces.wlp3s0.useDHCP = true;
useDHCP = false;
wireless = {
enable = true;
interfaces = ["wlp3s0"];
networks = {
SSID??? = {
pskRaw = "???????";
};
};
userControlled.enable = true;
};
};
time.timeZone = "Europe/London";
i18n.defaultLocale = "en_GB.UTF-8";
console = {
font = "Lat2-Terminus16";
keyMap = "uk";
};
services = {
displayManager.defaultSession = "none+awesome";
libinput = {
enable = true;
touchpad.disableWhileTyping = true;
};
pipewire = {
enable = true;
pulse.enable = true;
};
xserver = {
enable = true;
xkb.layout = "gb";
windowManager = {
awesome = {
enable = true;
luaModules = with pkgs.luaPackages; [ luarocks lgi vicious ];
};
};
};
};
users.users.eric = {
isNormalUser = true;
home = "/home/eric";
createHome = true;
extraGroups = [ "wheel" ];
packages = with pkgs; [
firefox
tree
];
};
environment.systemPackages = with pkgs; [
vim
git
brave
keepass
alacritty
ntfs3g
];
system.stateVersion = "24.05";
}
Example hardware-configuration.nix:
{ config, lib, pkgs, modulesPath, ... }: {
imports = [ (modulesPath + "/installer/scan/not-detected.nix") ];
boot = {
initrd = {
availableKernelModules = [ "uhci_hcd" "ehci_pci" "ahci" "usb_storage" "sd_mod" ];
kernelModules = [ "dm-snapshot" ];
luks.devices."root" = {
allowDiscards = true;
device = "/dev/disk/by-label/NIXOS_LUKS_PARTITION";
preLVM = true;
};
};
kernelModules = [ "kvm-intel" ];
extraModulePackages = [ ];
};
fileSystems = {
"/" = {
device = "/dev/disk/by-label/NixOS_ROOT";
fsType = "ext4";
options = [ "noatime" "nodiratime" "discard" ];
};
"/boot" = {
device = "/dev/disk/by-label/NixOS_BOOT";
fsType = "vfat";
options = [ "fmask=0022" "dmask=0022" ];
};
};
swapDevices = [ { device = "/dev/disk/by-label/NixOS_SWAP"; } ];
networking.useDHCP = lib.mkDefault true;
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
}
Once configuration is complete:
Install NixOS and rebbot.
nixos-install
reboot
Troubleshooting
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:
cryptsetup luksOpen /dev/sda2 enc-pv
lvchange -a y /dev/vg/NixOS_SWAP
lvchange -a y /dev/vg/NixOS_ROOT
mount /dev/vg/NixOS_ROOT /mnt
mount /dev/sda1 /mnt/boot
swapon /dev/vg/swap
cp /mnt/etc/wpa_supplicant.conf /etc
systemctl start wpa_supplicant