6.5 KiB
basic system installation
- The installations presented in this repository are always luks encrypted
- For simplicity I'm using device labels rather than uuids
- Secure Boot has to be disabled in the firmware, the installer iso isn't signed
-
create the partitions with
cfdiskorfdisk(gpt)nvme0n1p1: 2G, typeEFI System, otherwise the firmware won't find the bootloadernvme0n1p2: the rest, typeLinux filesystem
the layout should look somewhat like this after the installation
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
nvme0n1 259:0 0 476.9G 0 disk
├─nvme0n1p1 259:1 0 2G 0 part /boot
└─nvme0n1p2 259:2 0 474.9G 0 part
└─cryptroot 254:0 0 474.9G 0 crypt
├─lvmroot-swap 254:1 0 20G 0 lvm [SWAP]
├─lvmroot-home 254:2 0 250G 0 lvm /home
└─lvmroot-root 254:3 0 204.9G 0 lvm /
Note:
lsblkmay additionally show/nix/storeas a mountpoint onlvmroot-root. This is not a separate partition. NixOS mounts the root device a second time at/nix/storewithro,nosuid,nodevflags to enforce store immutability at runtime.
- prepare the installation
# format the boot partition
mkfs.fat -F 32 /dev/nvme0n1p1 -n "nixboot"
# create an encrypted partition
cryptsetup luksFormat -y --label="nixcrypt" /dev/nvme0n1p2
# open the encrypted partition and map it to /dev/mapper/cryptroot
cryptsetup luksOpen /dev/nvme0n1p2 cryptroot
# create the physical volume
pvcreate /dev/mapper/cryptroot
# create a volume group inside
vgcreate lvmroot /dev/mapper/cryptroot
# create the swap volume, half the ram (no hibernation)
lvcreate --size 16G lvmroot --name swap
# if you desire, create a home volume
lvcreate --size 150G lvmroot --name home
# create the root volume, leave some space in the vg to grow volumes later
# (lvextend -r -L +50G lvmroot/home works while mounted)
lvcreate -l 90%FREE lvmroot --name root
# format as usual for root partition
mkfs.ext4 -L "nixroot" /dev/mapper/lvmroot-root
# if you previously made the home partition, do it too
mkfs.ext4 -L "nixhome" /dev/mapper/lvmroot-home
# format the swap partition
mkswap -L "nixswap" /dev/mapper/lvmroot-swap
# mount root
mount /dev/disk/by-label/nixroot /mnt
# mount boot
mount --mkdir /dev/disk/by-label/nixboot /mnt/boot
# again, if you did the home volume
mount --mkdir /dev/disk/by-label/nixhome /mnt/home
# turn on swap
swapon /dev/disk/by-label/nixswap
- prepare nixos
# generate templates and update the hardware-configuration.nix
nixos-generate-config --root /mnt
# no extra kernelModules needed, luks and lvm load dm_crypt and dm_mod themselves
# add file systems using labels
fileSystems."/" =
{ device = "/dev/disk/by-label/nixroot";
fsType = "ext4";
};
fileSystems."/boot" =
{ device = "/dev/disk/by-label/nixboot";
fsType = "vfat";
options = [ "fmask=0077" "dmask=0077" ]; # only root may read /boot
};
fileSystems."/home" =
{ device = "/dev/disk/by-label/nixhome";
fsType = "ext4";
};
swapDevices =
[ { device = "/dev/disk/by-label/nixswap"; }
];
# point the bootloader to the luks device
boot.initrd.luks.devices."cryptroot" = {
device = "/dev/disk/by-label/nixcrypt";
# without this fstrim never reaches the ssd
allowDiscards = true;
# lower latency on nvme
bypassWorkqueues = true;
};
- install nixos
nixos-install
how to deploy the initial config
- Don't forget to install the bootloader, if you changed it since
nixos-install - The fresh install has no flakes and no git yet, a temporary shell is enough
- If the installer iso is older than the flake's nixpkgs,
--no-reexeckeepsnixos-rebuildfrom re-executing a newer version of itself, which can fail against the older systemd of the fresh install (only needed once) - Set a password for the user before rebooting,
users.nixdoesn't set one
$ export NIX_CONFIG="experimental-features = nix-command flakes"
$ nix-shell -p git
$ sudo nixos-rebuild --install-bootloader boot --flake .#host_name --no-reexec
$ sudo passwd aaron
how to enable secure boot
Secure Boot uses lanzaboote with our own keys, see modules/nixos/lanzaboote.nix.
Do this after the initial config is deployed and boots.
- create the keys, before the first rebuild with the lanzaboote module
# the keys end up in /var/lib/sbctl, they never leave the host
$ sudo nix run nixpkgs#sbctl -- create-keys
- import
modules/nixos/lanzaboote.nixin the host'sconfiguration.nix, rebuild and check the signatures
$ sudo nixos-rebuild switch --flake .#host_name
# EFI/Linux/*.efi and the bootloader must be signed, kernels in EFI/nixos
# are not, lanzaboote checks them by hash
$ sudo sbctl verify
-
reboot once with Secure Boot still disabled, to make sure the new entries boot
-
in the firmware (F2), erase all Secure Boot keys, then boot nixos again
# "Setup Mode: ✗ Enabled", the ✗ only means the state is insecure
$ sudo sbctl status
- enroll the keys
# only our own keys, no microsoft keys
$ sudo sbctl enroll-keys
- sbctl refuses if the TPM eventlog shows option ROMs (e.g. a dedicated gpu).
Don't force it, either trust exactly those with
--tpm-eventlogor microsoft's keys with--microsoft. Without either, the firmware may not start the device, in the worst case the machine doesn't boot at all.
- enable Secure Boot in the firmware and set a firmware password, then check
$ bootctl status | grep "Secure Boot" # enabled (user)
$ sudo sbctl status # Secure Boot: ✓ Enabled
- If it doesn't boot anymore, disabling Secure Boot in the firmware boots as before
- Losing the keys isn't fatal: erase the keys in the firmware and start over at step 1
how to upgrade the system
$ cd /path/to/repo
$ nix flake update
$ sudo nixos-rebuild switch --flake .#host_name
$ sudo nix-collect-garbage
how to use nix-helper
The tool nix-helper is installed by this configuration. It simplifies administrating nixos and adds more output to the rebuild command. It also features a diff after a successful build. The command uses the NH_FLAKE environment variable to be able to run from whatever directory.
Basic commands with a set NH_FLAKE variable are:
$ nh os switch
$ nh os build
$ nh os test
$ nh clean all --keep 5
There is also the option to interface with home-manager by using nh home switch but this isn't necessary since home-manager is imported as a module in this config.