Archived
fix(proxmox): embed SSH host key via NIXOS_HOST_KEYS_DIR so sops can decrypt on first boot
Check NixOS configurations / eval-hosts (pull_request) Successful in 10m30s
Check NixOS configurations / eval-hosts (pull_request) Successful in 10m30s
--pre-format-files placed the key on the QEMU builder VM's rootfs, not the target disk. nixos-install chroots into the target and runs sshd-keygen, which found no key in the chroot and generated a fresh (unregistered) one. sops then could not decrypt on first boot because the key didn't match .sops.yaml, leaving both root and nixos with '!' in /etc/shadow even after mutableUsers = false was set (hashedPasswordFile pointed to paths sops never wrote). Fix modules/platforms/proxmox.nix to embed the clan SSH host key in environment.etc via NIXOS_HOST_KEYS_DIR at eval time -- the same pattern lxc.nix uses. nixos-install's own activation places the key on the target disk, sshd-keygen finds it already present and skips generation, and sops decrypts correctly on first boot. Includes the same preserveSshHostKey/restoreSshHostKey activation scripts as lxc.nix so subsequent nixos-rebuild switch calls (without NIXOS_HOST_KEYS_DIR) don't remove the key as "obsolete" from environment.etc. Update create-proxmox-resource.sh: switch VM builds from ./result-<target> --pre-format-files ... --build-memory 2048 to NIXOS_HOST_KEYS_DIR=$(pwd)/host-keys nix build --impure ... diskoImagesScript ./result-<target> --build-memory 2048 matching the LXC build path. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011uRcikkTp3D5VbXj2DwNpQ
This commit is contained in:
@@ -784,12 +784,9 @@ REMOTE_SCRIPT
|
||||
fi
|
||||
else
|
||||
if [[ "$dry_run" -eq 1 ]]; then
|
||||
echo "[dry-run] would build on ${node}: nix build --no-use-registries --no-accept-flake-config${nix_opts_display} \\"
|
||||
echo "[dry-run] would build on ${node}: NIXOS_HOST_KEYS_DIR=\$(pwd)/host-keys nix build --impure --no-use-registries --no-accept-flake-config${nix_opts_display} \\"
|
||||
echo "[dry-run] .#nixosConfigurations.${flake_target}.config.system.build.diskoImagesScript"
|
||||
echo "[dry-run] would run: ${sudo_display}./result-${flake_target} \\"
|
||||
echo "[dry-run] --pre-format-files host-keys/${flake_target}_ssh_host_ed25519_key /etc/ssh/ssh_host_ed25519_key \\"
|
||||
echo "[dry-run] --pre-format-files host-keys/${flake_target}_ssh_host_ed25519_key.pub /etc/ssh/ssh_host_ed25519_key.pub \\"
|
||||
echo "[dry-run] --build-memory 2048"
|
||||
echo "[dry-run] would run: ${sudo_display}./result-${flake_target} --build-memory 2048"
|
||||
echo "[dry-run] image will be at ${vm_built_raw} (imported from there; no mv to /var/lib/vz/import/)"
|
||||
local_image="<built-image>.raw"
|
||||
else
|
||||
@@ -797,6 +794,14 @@ REMOTE_SCRIPT
|
||||
# See the LXC branch above for why this is one %q-quoted command
|
||||
# string rather than separate ssh argv elements.
|
||||
# $7 = image_name (hostname, the diskoImagesScript's own output filename).
|
||||
#
|
||||
# NIXOS_HOST_KEYS_DIR + --impure: modules/platforms/proxmox.nix reads
|
||||
# this env var at eval time (like lxc.nix) to embed the clan SSH host
|
||||
# key in environment.etc. nixos-install's own activation then places the
|
||||
# key on the target disk, so sshd-keygen finds it already present and
|
||||
# skips generation. --pre-format-files put the key on the QEMU builder
|
||||
# VM's rootfs (not the target disk), so sshd-keygen regenerated a fresh
|
||||
# key -- one not registered in .sops.yaml -- and sops could never decrypt.
|
||||
printf -v remote_cmd 'bash -s -- %q %q %q %q %q %q %q' \
|
||||
"$remote_repo_dir" "$flake_target" "$remote_dir" "$remote_filename" "$NIX_EXTRA_OPTS" "$sudo_prefix" "$host"
|
||||
ssh "$ssh_target" "$remote_cmd" <<'REMOTE_SCRIPT'
|
||||
@@ -813,16 +818,18 @@ if [[ ! -f "host-keys/${target}_ssh_host_ed25519_key" ]]; then
|
||||
echo "and ensure it was synced here before starting the build." >&2
|
||||
exit 1
|
||||
fi
|
||||
nix build --no-use-registries --no-accept-flake-config "${NIX_OPTS[@]}" \
|
||||
# Build diskoImagesScript with NIXOS_HOST_KEYS_DIR so proxmox.nix embeds the
|
||||
# clan SSH key in environment.etc (same as lxc.nix). This causes nixos-install
|
||||
# to place the key on the target disk, so sshd-keygen finds it and skips
|
||||
# generation -- the disk image boots with the registered key, sops decrypts.
|
||||
NIXOS_HOST_KEYS_DIR="$(pwd)/host-keys" nix build --impure \
|
||||
--no-use-registries --no-accept-flake-config "${NIX_OPTS[@]}" \
|
||||
".#nixosConfigurations.${target}.config.system.build.diskoImagesScript" \
|
||||
--out-link "result-${target}"
|
||||
# Remove any stale .raw from a previous failed build so the post-build check
|
||||
# below is unambiguous (diskoImagesScript writes to CWD as ${image_name}.raw).
|
||||
$sudo_pfx rm -f "${image_name}.raw" 2>/dev/null || true
|
||||
$sudo_pfx "./result-${target}" \
|
||||
--pre-format-files "$(pwd)/host-keys/${target}_ssh_host_ed25519_key" /etc/ssh/ssh_host_ed25519_key \
|
||||
--pre-format-files "$(pwd)/host-keys/${target}_ssh_host_ed25519_key.pub" /etc/ssh/ssh_host_ed25519_key.pub \
|
||||
--build-memory 2048
|
||||
$sudo_pfx "./result-${target}" --build-memory 2048
|
||||
if [[ ! -f "${image_name}.raw" ]]; then
|
||||
echo "ERROR: ${image_name}.raw not found in ${repo_dir} after build -- disko/QEMU may have failed." >&2
|
||||
exit 1
|
||||
|
||||
Reference in New Issue
Block a user