Skip to content

britter/nix-configuration

Repository files navigation

nix-configuration

Flake based Nix configuration for my machines.

Useful commands

General

Show store location of a module

nix build <package> --print-out-paths --no-link

Where <package> would be something like nixpkgs#cowsay

Run command without installing or nix-shell

nix run <package> -- <args>

Where

  • <package> would be something like nixpkgs#exa
  • <args> would be something like --tree --level 4 (in the case of exa).

Note that the <package> and <args> need to be separated by --

Getting a package hash

From URL:

nix run nixpkgs#nix-prefetch fetchurl --url <url>

From git/GitHub:

nix run nixpkgs#nix-prefetch-git <url>
nix run nixpkgs#nix-prefetch-github <owner> <repo>

This will download the URL/git repository to the store and print the resulting hash.

Flakes

Switch to a machine configuration by host name

sudo nixos switch --flake ".#<host>"

Retrieve flake meta data

nix flake metadata <flake url>

Flake url can be something like

  • . (flake in CWD)
  • github:nixos/nixpkgs/nixos-unstable

Initialize a new flake

nix flake init --template <template name>

Update specific flake input

nix flake lock --update-input <input name>

Update flake with commit

nix flake update --commit-lock-file

Explore a flake

nix flake show <flake url>

Secrets management with sops

** Adding a new host

  • Generate SSH key for the host using ssh-key-gen
  • Convert the public key to age
nix run nixpkgs#ssh-to-age -- -i ~/.ssh/key.pub
  • Add an entry to .sops.yaml for that host
  • Create the secrets file
nix run nixpkgs#sops -- path/to/secrets.yaml

Rotating a key in a sops file

Modify .sops.yaml and update the key.

nix run nixpkgs#sops -- updatekeys path/to/secrets.yaml

Initializing a new machine

NixOS

  1. Install the latest NixOS release
  2. Clone this repository using a nix shell that has git nix shell nixpkgs#git
  3. Create a new folder under hosts that's named after the host.
  4. Copy the configuration.nix and hardware-configuration.nix files from etc/nixos/ into the new directory.
  5. Add the new machine to flake.nix. Make sure the machine's host name and nixosConfiguration name match.
  6. Repace /etc/nixos with a symbolic link to cloned repository.
  7. Run sudo nixos-rebuild switch --flake to enable the flake based configuration for the new machine.

VMs

Optional: Build a new VM image if changes are required

nix build .#nixosConfigurations.minimal-server-iso.config.system.build.isoImage
  1. Define a new VM using the home-lab terraform configuration. Make sure to reference the right ISO.
  2. Wait for the VM to boot into the installer.
  3. Create a new host by copying one of the existing hosts.
  4. Install the VM using nix-anywhere by running
nix run github:nix-community/nixos-anywhere -- --flake '.#<host-config>' [email protected]

In case, the machine uses sops secrets, the key needs to be sent to the host during setup. Either use an existing setup script in scripts/ or create a new one based on the others. Then run the script from a shell that has nixos-anywhere:

nix shell github:nix-community/nixos-anywhere
./scripts/setup-<host>.sh

Redeploy the machine remotely via

nixos-rebuild switch --fast --flake .#<host-config> \
    --target-host root@<host-ip> \
    --build-host root@<host-ip>

See https://www.haskellforall.com/2023/01/announcing-nixos-rebuild-new-deployment.html

macOS

  1. Install nix using the Determinate Systems nix installer.
  2. Clone this repository using a nix shell that has git nix shell nixpkgs#git
  3. Create a new folder under hosts that's names after the host.
  4. Initialize a new configuration from the examples in the nix-darwin repository.
  5. Add the new machine to flake.nix. Make sure the machine's host name and darwinConfiguration name match.
  6. Inside the repository clone, run nix run nix-darwin --extra-experimental-features 'nix-command flake' darwin-rebuild -- switch --flake . (See for resolution of LnL7/nix-darwin#721 in order to run darwin-rebuild from anywhere after that).
  7. Apply the workaround documented in LnL7/nix-darwin#122 (comment) is the issue is still unresolved.

Raspberry Pi

This is the description for a network install that does not require the Raspberry Pi to be connected to a display. Instead it's sufficient to connet it to the network via ethernet cable and ssh into the machine. The SD card image will setup the root account and a user called nixos without password. However the SSH service is configred to not accept empty passwords. So in order to login via SSH, you need to pre-load your SSH key into the authorized_keys file of either the root user or the nixos user. The first step is to download the bootable SD card image from the Hydra build system, see this nixos.wiki entry.

Pre-load an SSH key into the image

  1. Use nix run nixpkgs#parted <img> to find out what exactly to mount. See this stackoverflow answer for details.
  2. Mount the image file into a local directory by running
mkdir img
sudo mount -o loop,offset=<result from parted> <image file name> img
  1. Generate an SSH key if you haven't already using the ssh-keygen tool.
  2. The SD card image will setup a user called nixos on first boot. For that reason /home/nixos does not exist in the image you just mounted. Create the user home, and pre-load your SSH key as an authorized key:
sudo mkdir -p img/home/nixos/.ssh
sudo cp ~/.ssh/id_rsa.pub img/home/nixos/.ssh/authorized_keys
sudo chown -R 1000:100 img/home/nixos
sudo chmod -R 700 img/home/nixos
sudo chmod 600 img/home/nixos/authorized_keys
  1. Unmount the image via sudo umount img
  2. Use nix run nixpkgs#rpi-imager to run the Raspberry Pi imager and write the image to the SD card.

After first boot

  1. Once the key is on the device, ssh into it as the nixos user.
  2. Run sudo nixos-generate-config to generate the initial configuration.
  3. IMPORTANT: You need to make two modifications to /etc/nixos/configuration.nix. If you forget to add this to the config, when you nixos-rebuild switch you won't be able to login anymore!
  • Configure the nixos user:
users.users.nixos = {
  isNormalUser = true;
  extraGroups = ["wheel"];
}
  • Enable the SSH services:
services.openssh = {
  enable = true;
  # require public key authentication for better security
  settings.PasswordAuthentication = false;
  settings.KbdInteractiveAuthentication = false;
  #settings.PermitRootLogin = "yes";
};
  1. Start from 2. in the NixOs section.

Useful links

Packages

Flakes

Configuration examples

Tools

General

Nix related

Nix on Raspberry Pi