From 3bf3c5f650636ea260a334442dfa0227be739793 Mon Sep 17 00:00:00 2001 From: Vijit Singh Date: Thu, 13 Aug 2026 10:02:55 -0500 Subject: [PATCH] fix(os): run the host-key generator BEFORE Debian's sshd -t config test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drop-in ExecStartPre entries append after the main unit's, and Debian's ssh.service already runs 'sshd -t' as its own ExecStartPre. On a first boot /data/ssh is still empty, so the config test failed with 'no hostkeys available' before the generator ever ran — ssh.service could never start, and every _ssh leg of the KVM battery was dead (found by the battery on the merged tip; the wizard and stack were healthy, only SSH was down). Reset the ExecStartPre list, generate first, re-run the distro's own test; verify-image pins the three lines and their order. Co-Authored-By: Claude Fable 5 --- os/overlay/pithead-ssh-host-keys.conf | 12 ++++++++---- tests/os/verify-image.sh | 8 ++++++++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/os/overlay/pithead-ssh-host-keys.conf b/os/overlay/pithead-ssh-host-keys.conf index cb2a10ce..7ee3bef9 100644 --- a/os/overlay/pithead-ssh-host-keys.conf +++ b/os/overlay/pithead-ssh-host-keys.conf @@ -6,8 +6,12 @@ RequiresMountsFor=/data [Service] -# Runs before sshd loads any HostKey (ExecStartPre entries across merged drop-ins all run, in -# order, ahead of ExecStart — unlike ExecStart itself, which a later drop-in's own ExecStart= -# reset-then-set would otherwise clobber). Generates the key into /data/ssh if missing; a no-op -# after the first boot. +# ORDER IS THE WHOLE FIX HERE. Drop-in ExecStartPre entries APPEND after the main unit's, and +# Debian's ssh.service already carries `ExecStartPre=/usr/sbin/sshd -t` — a config test that +# fails with "no hostkeys available" while /data/ssh is still empty. Appended, our generator +# ran second and never got its turn: on a first boot ssh.service could not start at all (found +# by the KVM battery — every _ssh leg dead). Reset the list, generate first, then re-run the +# distro's own test; the image is frozen, so restating its line cannot drift. +ExecStartPre= ExecStartPre=/usr/local/sbin/pithead-ssh-host-keys +ExecStartPre=/usr/sbin/sshd -t diff --git a/tests/os/verify-image.sh b/tests/os/verify-image.sh index a18be145..43aacd76 100755 --- a/tests/os/verify-image.sh +++ b/tests/os/verify-image.sh @@ -247,6 +247,14 @@ chk "machine-id ships empty (systemd's own read-only-root first-boot semantics)" chk "SSH host-key generator baked and executable" '[ -x "$ROOT/usr/local/sbin/pithead-ssh-host-keys" ]' chk "ssh.service host-key drop-in orders after /data" \ 'grep -q "RequiresMountsFor=/data" "$ROOT/etc/systemd/system/ssh.service.d/pithead-host-keys.conf"' +# Debian's own unit runs `sshd -t` as ExecStartPre, and drop-in entries APPEND — without the +# reset, the config test runs before the generator, finds no key on a first boot, and +# ssh.service can never start (KVM-battery find). The reset line + generator-first order is +# load-bearing, so pin all three lines and their order. +chk "host-key generator runs BEFORE the distro's sshd -t (reset + reorder)" \ + '[ "$(grep "^ExecStartPre" "$ROOT/etc/systemd/system/ssh.service.d/pithead-host-keys.conf" | head -1)" = "ExecStartPre=" ] && + grep -qxF "ExecStartPre=/usr/local/sbin/pithead-ssh-host-keys" "$ROOT/etc/systemd/system/ssh.service.d/pithead-host-keys.conf" && + grep -qxF "ExecStartPre=/usr/sbin/sshd -t" "$ROOT/etc/systemd/system/ssh.service.d/pithead-host-keys.conf"' chk "sshd points at the /data host key" \ 'grep -q "^HostKey /data/ssh/ssh_host_ed25519_key" "$ROOT/etc/ssh/sshd_config.d/pithead-host-keys.conf"' chk "machine-id restore script baked and executable" '[ -x "$ROOT/usr/local/sbin/pithead-machine-id" ]'