From 2a0737ab7890e30439c2ad635650ab5abbe61266 Mon Sep 17 00:00:00 2001 From: "Dustin C. Hatch" Date: Mon, 4 Apr 2022 20:53:10 -0500 Subject: [PATCH] Enable local persistent storage Machine-specific data, such as SSH keys, should not be included in the immutable root filesystem image, as this would prevent multiple machines running from the same image. These few files can be stored locally, on the SD card on eMMC flash. The first time a machine boots up using this image, its local storage is initialized. This involves creating a new filesystem on the block device and generating SSH host keys. Once the storage is initialized, it is remounted read-only. All subsequent mounts are read-only as well. --- mkrootfs.sh | 4 -- overlay/etc/fstab | 2 + .../systemd/system/init-localstorage.service | 16 ++++++++ .../init-localstorage.service | 1 + .../usr/local/libexec/init-localstorage.sh | 41 +++++++++++++++++++ 5 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 overlay/etc/systemd/system/init-localstorage.service create mode 120000 overlay/etc/systemd/system/run-storage.mount.wants/init-localstorage.service create mode 100755 overlay/usr/local/libexec/init-localstorage.sh diff --git a/mkrootfs.sh b/mkrootfs.sh index 0eea2b0..8e42e46 100644 --- a/mkrootfs.sh +++ b/mkrootfs.sh @@ -45,10 +45,6 @@ cp -p \ "${srcdir}"/config.txt \ "${destdir}"/boot/efi -for x in ed25519 rsa ecdsa; do - chroot "${destdir}" /usr/libexec/openssh/sshd-keygen $x -done - tar --owner root:0 -C "${srcdir}/overlay" -c . \ | tar -C "${destdir}" -x chown -R 1000:1000 "${destdir}"/home/user diff --git a/overlay/etc/fstab b/overlay/etc/fstab index b299b09..92f7e54 100644 --- a/overlay/etc/fstab +++ b/overlay/etc/fstab @@ -2,4 +2,6 @@ tmpfs /var/lib/rsyslog tmpfs defaults 0 0 tmpfs /var/log tmpfs defaults 0 0 tmpfs /var/lib/systemd tmpfs defaults 0 0 tmpfs /var/lib/NetworkManager tmpfs defaults 0 0 +/dev/mmcblk0 /run/storage ext4 ro,noexec,nosuid,nodev,x-systemd.makefs 0 2 +overlay /etc/ssh overlay ro,lowerdir=/etc/ssh:/run/storage/ssh,noexec,nodev,nosuid,x-systemd.requires-mounts-for=/run/storage 0 0 /dev/nbd1 swap swap noauto,x-systemd.makefs 0 0 diff --git a/overlay/etc/systemd/system/init-localstorage.service b/overlay/etc/systemd/system/init-localstorage.service new file mode 100644 index 0000000..1069907 --- /dev/null +++ b/overlay/etc/systemd/system/init-localstorage.service @@ -0,0 +1,16 @@ +[Unit] +Description=Initialize Local Storage +DefaultDependencies=no +After=local-fs-pre.target +After=run-storage.mount +Before=etc-ssh.mount +Before=local-fs.target +Conflicts=shutdown.target +ConditionPathExists=!/run/storage/ssh + +[Service] +Type=oneshot +ExecStart=/usr/local/libexec/init-localstorage.sh + +[Install] +WantedBy=run-storage.mount diff --git a/overlay/etc/systemd/system/run-storage.mount.wants/init-localstorage.service b/overlay/etc/systemd/system/run-storage.mount.wants/init-localstorage.service new file mode 120000 index 0000000..a9481f4 --- /dev/null +++ b/overlay/etc/systemd/system/run-storage.mount.wants/init-localstorage.service @@ -0,0 +1 @@ +../init-localstorage.service \ No newline at end of file diff --git a/overlay/usr/local/libexec/init-localstorage.sh b/overlay/usr/local/libexec/init-localstorage.sh new file mode 100755 index 0000000..b1df419 --- /dev/null +++ b/overlay/usr/local/libexec/init-localstorage.sh @@ -0,0 +1,41 @@ +#!/bin/sh + +die() { + remount_ro + echo "ERROR: $1" >&2 + exit 1 +} + +gen_ssh_keys() { + unset kf x + mkdir -p /run/storage/ssh || die 'Could not create /run/storage/ssh' + for x in rsa ecdsa ed25519; do + kf=/run/storage/ssh/ssh_host_${x}_key + if [ ! -f ${kf} ]; then + ssh-keygen -t ${x} -f ${kf} -N '' -C '' \ + || die "Failed to generate ${x} SSH host key" + fi + done +} + +remount_ro() { + if [ -w /run/storage ]; then + mount -oremount,ro /run/storage + fi +} + +remount_rw() { + if [ ! -w /run/storage ]; then + mount -o remount,rw /run/storage \ + || die 'Could not remount /run/storage read-write' + fi +} + +mountpoint -q /run/storage || die '/run/storage is not mounted' + +if [ ! -d /run/storage/ssh ]; then + remount_rw + gen_ssh_keys +fi + +remount_ro