This repository has been archived on 2026-07-19. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
beatzaplentyandClaude Sonnet 5 dd2d3b5914 Fix prepare-host-key.sh: backticks in a double-quoted nix-shell --run
string were parsed as command substitution by the outer shell

The whole keygen+instructions block ran inside one big double-quoted
nix-shell --run "..." string. Markdown-style `keys:` backticks in the
instructions heredoc are live to the *outer* shell in that context (it
parses the string before nix-shell ever sees it) — bash tried to run a
command literally called "keys:", failed, and silently dropped the
backtick-quoted text from the output.

Split into two minimal, single-purpose nix-shell --run invocations
(keygen, then age derivation into a captured variable) and moved the
instructions to a plain heredoc in the outer script, where normal
quoting rules apply and there's nothing left to misinterpret. Also
resolves host-keys/ to an absolute path instead of the literal
./scripts/../host-keys/... that showed up in output before.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-19 15:00:40 +10:00

65 lines
2.5 KiB
Bash
Executable File

#!/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 <hostname> [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="$(cd "$(dirname "$0")/.." && pwd)/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 ${nixos_repo}/secrets/common.yaml'
=== 4. Commit + push the nixos repo so the flake build picks up the new recipient ===
=== 5. When you boot the installer on the new machine, scp the key in ===
scp ${keyfile}{,.pub} root@<target-ip>:/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