Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions bin/prod/ssh-keygen-boot
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#!/bin/bash

set -euo pipefail

LOG_FILE="${LOG_FILE:-/var/log/reflash.log}"
KEY_DIR="${REFLASH_SSH_KEY_DIR:-/mnt/usb/ssh_host_keys}"

info() {
echo "[info] $1" >> "$LOG_FILE"
echo "$1"
}

# Build-time SSH host key generation (a side effect of installing
# openssh-server) would bake identical keys into every image and every board
# flashed from it. Keys are deleted at build time instead, and restored (or
# generated once and saved) here from the USB drive - the one thing on this
# board that actually persists across reboots, unlike the initrd root fs.

# On a freshly-flashed drive, /mnt/usb's partition doesn't exist yet - it's
# normally created by expand-usb, which the Go server calls on its own
# startup. This unit runs before reflash.service specifically so it has
# /mnt/usb to itself first, which means that hasn't happened yet here.
# expand-usb is idempotent (a no-op once the partition already exists), so
# calling it again from reflash.service afterward is harmless.
expand-usb

mount-unmount-usb mounted rw

if [ -f "$KEY_DIR/ssh_host_rsa_key" ]; then
info "Restoring SSH host keys from USB storage"
cp "$KEY_DIR"/ssh_host_* /etc/ssh/
else
info "No saved SSH host keys on USB storage - generating and saving new ones"
ssh-keygen -A
mkdir -p "$KEY_DIR"
cp /etc/ssh/ssh_host_* "$KEY_DIR/"
fi

mount-unmount-usb unmounted
info "SSH host keys ready"
31 changes: 31 additions & 0 deletions mkimage.sh
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,13 @@ RemainAfterExit=yes
[Install]
EOF

# Installing openssh-server generated SSH host keys as a side effect - baked
# into this one build, they'd be identical across every image and every
# board flashed from it (#80). Delete them; ssh-keygen-boot.service (set up
# below, outside the chroot) restores or generates them from USB storage
# on boot instead.
rm -f /etc/ssh/ssh_host_*

# Clean up
rm -rf /usr/sbin/policy-rc.d
rm ./*.deb
Expand Down Expand Up @@ -253,6 +260,30 @@ cat <<EOF > "${ROOTFSDIR}"/initrd/etc/systemd/resolved.conf.d/mdns.conf
MulticastDNS=yes
EOF

# This board's root fs runs from initrd and doesn't persist writes across
# reboots, so keys generated straight into /etc/ssh would be regenerated
# (and thus change) every boot. ssh-keygen-boot restores/saves them against
# /mnt/usb instead - the one thing that actually persists - so a given board
# keeps a stable identity while still not sharing a key with every other
# image/board (#80). Ordered before both ssh.service and reflash.service so
# it has /mnt/usb to itself - mount-unmount-usb has no locking of its own.
cat <<EOF >"${ROOTFSDIR}"/initrd/etc/systemd/system/ssh-keygen-boot.service
[Unit]
Description=Restore or generate persistent SSH host keys from USB storage (see #80)
Before=ssh.service reflash.service
ConditionPathExists=!/etc/ssh/ssh_host_rsa_key

[Service]
Type=oneshot
ExecStart=/usr/local/bin/ssh-keygen-boot
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
EOF

systemctl enable ssh-keygen-boot --root="${ROOTFSDIR}"/initrd

cat <<EOF >"${ROOTFSDIR}"/initrd/etc/systemd/system/reflash.service
[Unit]
Description=Refactor flashing server
Expand Down
Loading