From 6e39cc3edda00efb7df47655fbd37acb53797634 Mon Sep 17 00:00:00 2001 From: Chakib Benziane Date: Sat, 20 Apr 2019 22:48:37 +0200 Subject: [PATCH] initial --- README.md | 12 ++ etc/initramfs-tools/hooks/tinyssh | 124 ++++++++++++++++++ .../scripts/init-premount/tinyssh | 51 +++++++ etc/tinyssh-initramfs/config | 4 + 4 files changed, 191 insertions(+) create mode 100644 README.md create mode 100755 etc/initramfs-tools/hooks/tinyssh create mode 100755 etc/initramfs-tools/scripts/init-premount/tinyssh create mode 100644 etc/tinyssh-initramfs/config diff --git a/README.md b/README.md new file mode 100644 index 0000000..2fc2bbd --- /dev/null +++ b/README.md @@ -0,0 +1,12 @@ +## Requirements + +- Rebuild busybox on debian with `CONFIG_TCPSVD=y` +- Uninstall dropbear if previously installed +- Add scripts in `/etc/initramfs-tools` +- Add `authorized_keys` to `/etc/tinyssh-initramfs/authorized_keys` (only ssh-ed25519) +- Add tinysshd flags and optional custom port to `/etc/tinyssh-initramfs/config` +- Profit + +## References +- deb package `initramfs-dropbear` +- https://github.com/grazzolini/mkinitcpio-tinyssh/ diff --git a/etc/initramfs-tools/hooks/tinyssh b/etc/initramfs-tools/hooks/tinyssh new file mode 100755 index 0000000..282ceaf --- /dev/null +++ b/etc/initramfs-tools/hooks/tinyssh @@ -0,0 +1,124 @@ +#!/bin/sh + +PREREQ="" + +prereqs() { + echo "$PREREQ" +} + +case "$1" in + prereqs) + prereqs + exit 0 + ;; +esac + +. /usr/share/initramfs-tools/hook-functions + +## Needed for tinyssh +PATH=$PATH:/usr/sbin + +tinyssh_warn() { + echo "tinyssh: WARNING:" "$@" >&2 +} + +generate_keys() { + if [ ! -d /etc/tinyssh/sshkeydir ]; then + tinysshd-makekey /etc/tinyssh/sshkeydir + if [ $? -eq 0 ]; then + echo "Generated tinyssh keys..." + return 0 + fi + fi + return 1 +} + + +copy_openssh_keys() { + local osshed25519="/etc/ssh/ssh_host_ed25519_key" + + local destdir="/etc/tinyssh/sshkeydir" + + local return_code=1 + + if [ ! -x /usr/local/bin/tinyssh-convert ];then + echo "tinyssh-convert script missing" + exit 1 + fi + + if [ ! -d $destdir -a -x /usr/bin/tinyssh-convert ]; then + mkdir $destdir + fi + + if [ -s "$osshed25519" -a ! -s $destdir/.ed25519.sk -a ! -s $destdir/ed25519.pk -a -x /usr/bin/tinyssh-convert ]; then + tinyssh-convert -f $osshed25519 -d $destdir + if [ $? -eq 0 ]; then + return_code=0 + fi + fi + + if [ $return_code -eq 0 ]; then + echo "Converted keys from OpenSSH..." + fi + + return $return_code +} + +display_fingerprints() { + if [ -d /etc/tinyssh/sshkeydir ]; then + tinysshd-printkey /etc/tinyssh/sshkeydir + fi +} + +#### BEGIN REAL PROCESSING + + +## Only install tinyssh if we have an encrypted partition +[ -r /etc/crypttab ] || exit 0 + + +copy_exec /usr/sbin/tinysshd /sbin +LIBC_DIR=$(ldd /usr/sbin/tinysshd | sed -nr 's#.* => (/lib.*)/libc\.so\.[0-9.-]+ \(0x[[:xdigit:]]+\)$#\1#p') +find -L "$LIBC_DIR" -maxdepth 1 -name 'libnss_files.*' -type f | while read so; do + copy_exec "$so" +done + +# Create root dir +home=$(mktemp -d "$DESTDIR/root-XXXXXX") +chmod 0700 "$home" +for x in passwd group; do echo "$x: files"; done >"$DESTDIR/etc/nsswitch.conf" +echo "root:*:0:0::${home#$DESTDIR}:/bin/sh" >"$DESTDIR/etc/passwd" +echo "root:!:0:" >"$DESTDIR/etc/group" + +# Copy config +mkdir -p "$DESTDIR/etc/tinyssh" +if [ -e /etc/tinyssh-initramfs/config ]; then + cp -p "/etc/tinyssh-initramfs/config" "$DESTDIR/etc/tinyssh/" +fi + +umask 0022 + +# Copy host keys or generate keys +copy_openssh_keys || generate_keys +display_fingerprints + +# Copy authorized_keys from etc dir +if [ ! -r /etc/tinyssh-initramfs/authorized_keys ]; then + echo "Add authorized keys in /etc/tinyssh-initramfs/authorized_keys" + exit 1 +fi + +mkdir -m0700 "$home/.ssh" +if [ -e /etc/tinyssh-initramfs/authorized_keys ]; then + cat /etc/tinyssh-initramfs/authorized_keys +fi >"$home/.ssh/authorized_keys" + +# Check that authorized keys are in the right format +if ! grep -qE '^(ssh-ed25519) ' "$home/.ssh/authorized_keys"; then + tinyssh_warn "Invalid authorized_keys file, only ed25519 keys allowe,d remote unlocking of cryptroot via SSH won't work!" +fi + +# necessary for tinyssh private keys +cp -a /etc/tinyssh "$DESTDIR/etc/" + +# vim: set sts=4 shiftwidth=4 diff --git a/etc/initramfs-tools/scripts/init-premount/tinyssh b/etc/initramfs-tools/scripts/init-premount/tinyssh new file mode 100755 index 0000000..35b5dd1 --- /dev/null +++ b/etc/initramfs-tools/scripts/init-premount/tinyssh @@ -0,0 +1,51 @@ +#!/bin/sh + +PREREQ="udev" + +prereqs() { + echo "$PREREQ" +} + +case "$1" in + prereqs) + prereqs + exit 0 + ;; +esac + +[ "$IP" != off -a "$IP" != none -a -x /sbin/tinysshd ] || exit 0 + + +run_tinyssh() { + local flags="l" + local ssh_port=22 + [ "$debug" != y ] || flags="Lv" # log to standard error + + ssh_port=${TINYSSH_PORT:-$ssh_port} + + # always run configure_networking() before tinysshd(8); on NFS + # mounts this has been done already + [ "$BOOT" = nfs ] || configure_networking + + log_begin_msg "Starting tinysshd" + # using exec and keeping tinyssh in the foreground enables the + # init-bottom script to kill the remaining ipconfig processes if + # someone unlocks the rootfs from the console while the network is + # being configured + exec /bin/tcpsvd 0 $ssh_port /usr/sbin/tinysshd -$flags ${TINYSSH_OPTIONS-} /etc/tinyssh/sshkeydir +} + +if [ -e /etc/tinyssh/config ]; then + . /etc/tinyssh/config +fi +. /scripts/functions + +# On NFS mounts, wait until the network is configured. On local mounts, +# configure the network in the background (in run_dropbear()) so someone +# with console access can enter the passphrase immediately. (With the +# default ip=dhcp, configure_networking hangs for 5mins or so when the +# network is unavailable, for instance.) +[ "$BOOT" != nfs ] || configure_networking + +run_tinyssh & +echo $! >/run/tinyssh.pid diff --git a/etc/tinyssh-initramfs/config b/etc/tinyssh-initramfs/config new file mode 100644 index 0000000..be5029a --- /dev/null +++ b/etc/tinyssh-initramfs/config @@ -0,0 +1,4 @@ +## Extra options to pass for tinysshd + +TINYSSH_OPTIONS="-s" +TINYSSH_PORT=22