#!/usr/bin/env bash # Generates a new machine's SSH host key ahead of installing it, so # sops-nix 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 this 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 modules/installer/common.nix) when you actually install the # new machine. set -euo pipefail repo_root="$(cd "$(dirname "$0")/.." && pwd)" hostname="${1:?usage: scripts/prepare-host-key.sh }" sops_yaml="${repo_root}/.sops.yaml" if [[ ! -f "$sops_yaml" ]]; then echo "ERROR: $sops_yaml not found — is this script still under nixos/scripts/?" >&2 exit 1 fi keydir="${repo_root}/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 --run "ssh-keygen -t ed25519 -N '' -C '${hostname}' -f '${keyfile}'" >/dev/null age_pub="$(nix-shell -p ssh-to-age --run "ssh-to-age -i '${keyfile}.pub'")" cat <:/root/host-keys/ Then continue with /etc/auto-install.sh as normal — it checks /etc/host-keys (baked in) before /root/host-keys (scp'd) and installs whichever it finds before running nixos-install. EOF