This repository contains a Nix flake for packages, NixOS modules & configurations across my various devices. This README is to be considered documentation for this flake and the managed devices.
The other sections describe what hosts are managed by this flake, the devices they are deployed to, and, where necessary, building, imaging, flashing and installation.
Caution
These configurations contain encrypted secrets managed by sops-nix and care should be taken when building and activating them.
Most of these configurations cannot be successfully activated on machines that
do not have a /var/lib/sops-nix/keys.txt
file containing the age
private
key corresponding to an age
public key in the root .sops.yaml file.
The managed hosts and their descriptions are listed in the following table:
Hostname | Device type | Description |
---|---|---|
ceres | Desktop | Secondary PC at work |
deimos | Raspberry Pi Zero 2 W | Klipper host for 3D printer |
eris | WSL | Primary PC at work |
luna | Raspberry Pi Compute Module 4 | NAS |
mars | FriendlyElec NanoPC-T6 LTS | - |
mercury | Asus ROG Flow Z13 (2022) | Personal/work laptop |
phobos | Raspberry Pi 4 Model B | Dendrite Matrix homeserver Headscale VPN |
terra | Desktop | Primary PC at home |
venus | Lenovo ThinkPad X230 Tablet | Personal laptop |
The age
private key is used for decrypting secrets encrypted with the public
key on NixOS system activation. If the key is unavailable, you will not be able
to login and certain services will not function correctly. The age
private key
has to be generated and placed in /var/lib/sops-nix/keys.txt
before secrets
can be decrypted or rotated. The age
private key can be generated using the
following command:
rage-keygen -o ~/keys.txt
In order to make key rotation easier, the following commands will re-encrypt all secret files in this repository, when executed from its root, using the new key:
SECRET_FILES_REGEX=$(REGEXES=($(rg 'path_regex: (.*)$' -Nor '$1' .sops.yaml)); IFS='|'; echo "(${REGEXES[*]})")
AGE_PUBLIC_KEY="$(rg '# public key: (.*)' -or '$1' /var/lib/sops-nix/keys.txt)"
AGE_PUBLIC_KEY_NEW="$(rg '# public key: (.*)' -or '$1' ~/keys.txt)"
fd --full-path "$SECRET_FILES_REGEX" -x sops rotate -i --add-age "$AGE_PUBLIC_KEY_NEW" --rm-age "$AGE_PUBLIC_KEY"
The public key in the .sops.yaml
configuration file and the
private key in /var/lib/sops-nix/keys.txt
have to be updated manually.
This section contains installation guides and documentation for certain devices managed by this flake, in the order of the table provided in the previous section.
Important
Some of the following hosts can be pre-installed via generated images. In
order for NixOS activation to be successful, the age
private key needs to be
inserted into the image at the expected location of
/var/lib/sops-nix/keys.txt
.
A command is available to mount a partition and open a shell at its root in order to add, remove or change files:
nix run github:Electrostasy/dots#mountImage -- -i mars-sd-image*.img
The host deimos is a Raspberry Pi Zero 2 W, used for controlling the Original Prusa MK3S+ 3D printer flashed with Klipper firmware. It serves a Mainsail web interface for remote monitoring and management of the 3D printer.
The NixOS SD image to be flashed can be built using the following command:
nix build github:Electrostasy/dots#deimosImage
The NixOS SD image may be flashed to a selected microSD card using the following command:
dd if=deimos-image*.img of=/dev/sda bs=1M status=progress oflag=direct
The host luna is a Raspberry Pi Compute Module 4 (CM4) mounted to an Axzez Interceptor carrier board, serving as Network Attached Storage.
The NixOS SD image to be flashed can be built using the following command:
nix build github:Electrostasy/dots#lunaImage
The NixOS SD image may be flashed to eMMC storage using the Raspberry Pi Compute Module 4 IO Board. The following is a set of steps in order to prepare the IO Board for flashing the CM4:
-
Bridge the first set of pins on the 'J2' jumper to disable eMMC boot.
-
Connect the IO Board with the host PC you will flash from using a micro USB cable.
-
Power on the IO Board.
-
Run
rpiboot
on the host PC to see eMMC storage as a block device:sudo rpiboot
-
Flash the image to it:
sudo dd if=luna-image*.img of=/dev/sda bs=1M status=progress oflag=direct
-
Disconnect the micro USB cable from the host PC.
-
Power off the IO Board.
-
Detach the CM4 and attach it to your carrier board.
The host mars is a FriendlyElec NanoPC-T6 LTS, currently unused.
The preferred way would be to flash both u-boot
and the NixOS image to SPI and
eMMC respectively, however, at the time of writing, due to limitations in
rkdeveloptool
, the open-source command line flashing tool developed by
Rockchip as an alternative to the closed-source upgrade_tool
, we cannot select
between SPI and eMMC flash memory when flashing. Because of this, we build an
installer image with u-boot
included, and flash on the target system instead
of externally over USB.
The NixOS installer SD image to be flashed can be built using the following command:
NIXPKGS_ALLOW_UNFREE=1 nix build --impure github:Electrostasy/dots#marsImage
The NixOS installer SD image may be flashed to a selected microSD card or USB flash drive using the following command:
dd if=mars-sd-image*.img of=/dev/sda bs=1M status=progress oflag=direct
Then, when it is booted, we can write u-boot
to SPI flash and install NixOS to
eMMC memory. The u-boot
build suitable for SPI flash, provided in
u-boot-rockchip-spi.bin
, contains the miniloader idbloader.img
and u-boot
proper u-boot.itb
files concatenated at their expected offsets.
In order to flash u-boot
to SPI on a running system, use the following
command:
flashcp -v -p u-boot-rockchip-spi.bin /dev/mtd0
In order to install NixOS to eMMC on a running system, you have to target
/dev/mmcblk0
as the target installation device.
The host mercury (and terra) has an erase-your-darlings inspired encrypted btrfs root setup, where on every boot the root subvolume is rolled back to an empty snapshot. Rollbacks are accomplished using a systemd service in the initrd.
The below commands detail the partitioning process for the host mercury:
# Create 1G ESP, LUKS root and 16G swap partitions.
sgdisk -n 1::+1G -t 1:ef00 -n 2::-16G -t 2:8309 -n 3::0 -t 3:8200 /dev/nvme0n1
# Format the ESP.
mkfs.vfat -F 32 -n BOOT /dev/nvme0n1p1
# Format the root partition.
cryptsetup luksFormat --uuid eea26205-2ae5-4d2c-9a13-32c7d9ae2421 /dev/nvme0n1p2
cryptsetup luksOpen /dev/nvme0n1p2 cryptroot
mkfs.btrfs -L nixos /dev/mapper/cryptroot
# Format the swap partition.
mkswap -L swap /dev/nvme0n1p3
# Set up the btrfs subvolumes.
mount /dev/mapper/cryptroot -o compress-force=zstd:1,noatime /mnt
btrfs subvolume create /mnt/root
btrfs subvolume create /mnt/nix
btrfs subvolume create /mnt/state
btrfs subvolume snapshot -r /mnt/root /mnt/root-blank
umount /mnt
The below commands detail the installation process for the host mercury:
mount /dev/mapper/cryptroot -o subvol=root,compress-force=zstd:1,noatime /mnt
mkdir -p /mnt/{nix,state,boot,var/log,var/lib/sops-nix,etc/nixos}
mount /dev/mapper/cryptroot -o subvol=nix,compress-force=zstd:1,noatime /mnt/nix
mount /dev/mapper/cryptroot -o subvol=state,compress-force=zstd:1,noatime /mnt/state
mount /dev/nvme0n1p1 /mnt/boot
mkdir -p /mnt/state/{var/log,var/lib/sops-nix,etc/nixos}
mount -o bind /mnt/state/var/log /mnt/var/log
# IMPORTANT: don't forget to populate /mnt/var/lib/sops-nix/keys.txt!
mount -o bind /mnt/state/var/lib/sops-nix /mnt/var/lib/sops-nix
mount -o bind /mnt/state/etc/nixos /mnt/etc/nixos
# Download the NixOS configuration to install into its directory.
git clone https://github.com/Electrostasy/dots /mnt/etc/nixos
nixos-install --flake /mnt/etc/nixos#mercury --root /mnt --no-root-passwd
Due to system.etc.overlay
, the installation currently will fail if it is
enabled. As a workaround, the following commands need to be run before
running nixos-install
again:
mkdir /mnt/tmp
mount -o bind /tmp /mnt/tmp
mount -o bind /proc /mnt/proc
mount -o bind /sys /mnt/sys
mount -o bind /dev /mnt/dev
cp /etc/os-release /mnt/etc/
The host phobos is a Raspberry Pi 4 Model B, used to host the dendrite Matrix homeserver and the headscale coordination server for Tailscale VPN to link my devices together.
The NixOS SD image to be flashed can be built using the following command:
nix build github:Electrostasy/dots#phobosImage
Flash the SD image to a selected microSD card using the following command:
dd if=phobos-image*.img of=/dev/sda bs=1M status=progress oflag=direct