#!/usr/bin/env bash # Generates a new machine's SSH host key ahead of installing it, so # sops-nix (in the `nixos` flake) has something to derive an age key # from before the target ever boots. # # Why this is needed: sops-nix derives each host's decryption key from # its own /etc/ssh/ssh_host_ed25519_key at *activation* time, but that # activation runs before systemd would otherwise generate this key on # first boot (sshd-keygen is a normal systemd service gated behind # multi-user.target; activation scripts run earlier than that). Without # pre-seeding, secrets — including the root/nixos login password — fail # to decrypt on the machine's very first boot. # # This script only touches your admin workstation and the `nixos` repo's # .sops.yaml (it never contacts the target machine). Run it, follow the # printed next steps, then use the resulting key with the auto-install.sh # prompt (see common.nix) when you actually install the new machine. set -euo pipefail hostname="${1:?usage: scripts/prepare-host-key.sh [path-to-nixos-repo]}" nixos_repo="${2:-../nixos}" sops_yaml="${nixos_repo}/.sops.yaml" if [[ ! -f "$sops_yaml" ]]; then echo "ERROR: $sops_yaml not found. Pass the nixos repo path as the 2nd argument." >&2 exit 1 fi keydir="$(dirname "$0")/../host-keys" mkdir -p "$keydir" keyfile="${keydir}/${hostname}_ssh_host_ed25519_key" if [[ -f "$keyfile" ]]; then echo "ERROR: $keyfile already exists. Remove it first if you want to regenerate." >&2 exit 1 fi nix-shell -p openssh ssh-to-age --run " set -euo pipefail ssh-keygen -t ed25519 -N '' -C '${hostname}' -f '${keyfile}' >/dev/null age_pub=\$(ssh-to-age -i '${keyfile}.pub') cat <:/root/host-keys/ Then continue with /etc/auto-install.sh as normal — it will find the pre-seeded key and install it before running nixos-install. EOF "