Archived
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
75 lines
2.8 KiB
Bash
Executable File
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
|