Skip to content

Give each Reflash board its own persistent SSH host key - #102

Merged
eliasbakken merged 1 commit into
mainfrom
fix/unique-ssh-host-keys
Aug 10, 2026
Merged

Give each Reflash board its own persistent SSH host key#102
eliasbakken merged 1 commit into
mainfrom
fix/unique-ssh-host-keys

Conversation

@eliasbakken

Copy link
Copy Markdown
Contributor

Summary

mkimage.sh installed openssh-server during the image build, which generates SSH host keys as a side effect - baked into that one build, they'd be identical across every image and every board flashed from it (#80). That's a real MITM/impersonation risk: the private key extracted from any single image works against every other board running the same build.

Deleted the build-time keys and added ssh-keygen-boot.service, which restores (or generates once and saves) them against /mnt/usb instead - the one thing that actually persists across reboots on this board, since the root fs runs from initrd and doesn't. Ordered before both ssh.service and reflash.service so it has /mnt/usb to itself first - mount-unmount-usb has no locking of its own, so overlapping access from two processes isn't safe.

On a freshly-flashed drive, /mnt/usb's second partition doesn't exist yet - it's normally created by expand-usb, called from the Go server's own startup, which runs after this unit specifically so it doesn't race the server for the drive. ssh-keygen-boot calls expand-usb itself first; it's idempotent, so the Go server calling it again moments later is harmless.

Testing

  • make test-bats / go test ./... - no regressions (this script's logic depends on real block-device/mount behavior that isn't meaningfully unit-testable the way the other bats-covered scripts are, so validation is live-hardware only, below).
  • Live-tested on real hardware through the actual boot sequence, not just invoked directly:
    • Flashed a fresh image, confirmed on first boot that ssh-keygen-boot.service correctly detects no /mnt/usb partition yet, creates it via expand-usb, generates keys, and saves them to /mnt/usb/ssh_host_keys/.
    • Rebooted, confirmed the exact same key (verified by SHA256 fingerprint) is restored from USB rather than regenerated.

Closes #80

mkimage.sh installed openssh-server during the image build, which
generates SSH host keys as a side effect - baked into that one build,
they'd be identical across every image and every board flashed from
it (#80). That's a real MITM/impersonation risk: the private key
extracted from any single image works against every other board
running the same build.

Deleted the build-time keys and added ssh-keygen-boot.service, which
restores (or generates once and saves) them against /mnt/usb instead -
the one thing on this board that actually persists across reboots,
since the root fs runs from initrd and doesn't. Ordered before both
ssh.service and reflash.service so it has /mnt/usb to itself first;
mount-unmount-usb has no locking of its own, so overlapping access
from two processes at once isn't safe.

On a freshly-flashed drive /mnt/usb's second partition doesn't exist
yet - it's normally created by expand-usb, called from the Go server's
own startup, which runs after this unit specifically so it doesn't
race the server for the drive. ssh-keygen-boot calls expand-usb itself
first; it's idempotent, so the Go server calling it again moments
later is harmless.

Live-tested on real hardware through the actual boot sequence (not
just invoked directly): flashed a fresh image, confirmed keys are
generated and saved to /mnt/usb/ssh_host_keys/ on first boot, then
rebooted and confirmed the exact same key (verified by fingerprint) is
restored rather than regenerated.

Closes #80
@eliasbakken
eliasbakken merged commit 23d3587 into main Aug 10, 2026
2 checks passed
@eliasbakken
eliasbakken deleted the fix/unique-ssh-host-keys branch August 10, 2026 21:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Do not generate ssh keys during build

1 participant