This repository has been archived on 2026-07-30. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
nixos/scripts/prepare-host-key.sh
T
beatzaplentyandClaude Sonnet 5 a9a204eaf2 Remove packages.all bundle and the installer's own proxmox-lxc target
Both existed only so the installer could boot as an LXC container and
nixos-install some other host from within it, but lxc-* targets are
already excluded from the install menu (nixos-install can't touch its
own running root filesystem), and now have their own direct tarball
path anyway. That left the installer's own LXC form with no real use
case, and packages.all with only two members worth bundling.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01La55Nsss8jZ7ZuzUV9mfot
2026-07-20 08:04:08 +10:00

75 lines
2.8 KiB
Bash
Executable File

#!/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 <hostname>}"
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 <<EOF
Generated: ${keyfile}(.pub)
=== 1. Add this line under keys: in ${sops_yaml} ===
- &${hostname} ${age_pub}
=== 2. Add *${hostname} to whichever creation_rules key_groups this host needs ===
(e.g. secrets/common.yaml always; add a per-host secrets/${hostname}.yaml
block too if this host will get its own secrets, same pattern as
nix-cache/server.)
=== 3. Re-encrypt every secrets file you just added it to ===
nix-shell -p sops --run 'sops updatekeys ${repo_root}/secrets/common.yaml'
=== 4. Commit + push this repo so the flake build picks up the new recipient ===
=== 5. Get the key onto the installer, one of two ways ===
a) Rebuild the installer image with all host-keys/ baked in (see
docs/auto-installer.md):
NIXOS_HOST_KEYS_DIR="${keydir}" nix build .#iso --impure
(or .#pxe — --impure is required since host-keys/ is gitignored and
flakes can't see it otherwise)
b) Or, for an image already built without keys, scp it in after boot:
scp ${keyfile}{,.pub} root@<target-ip>:/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