commit 2e091e01691ac86f014d52504f13c6e1cc0990c3 Author: Stefan Reimer Date: Fri Feb 19 13:50:45 2021 +0100 crypt-ssh module: This modules allows for unlocking LUKS encrypted root filesystems remotely over SSH. By setting rd.luks.ssh and having a /root/.ssh/authorized_keys file dracut will wait until an authorized users logs in and enters a passphrase to open the LUKS device. diff --git a/modules.d/90crypt/cryptroot-ask.sh b/modules.d/90crypt/cryptroot-ask.sh index 1ea77ccc..e73743ef 100755 --- a/modules.d/90crypt/cryptroot-ask.sh +++ b/modules.d/90crypt/cryptroot-ask.sh @@ -173,15 +173,26 @@ fi if [ $ask_passphrase -ne 0 ]; then luks_open="$(command -v cryptsetup) $cryptsetupopts luksOpen" - _timeout=$(getargs "rd.luks.timeout") - _timeout=${_timeout:-0} - ask_for_password --ply-tries 5 \ - --ply-cmd "$luks_open -T1 $device $luksname" \ - --ply-prompt "Password ($device)" \ - --tty-tries 1 \ - --tty-cmd "$luks_open -T5 -t $_timeout $device $luksname" + + if getargbool 0 rd.luks.ssh; then + # Setup authorized_key file, inject forced cmd for each entry + while read key; do + echo "command=\"$luks_open -T5 $device $luksname && rm -f /tmp/crypt-ssh-block\" $key" >> /root/.ssh/authorized_keys + done < /root/.ssh/key.pub + rm -f /root/.ssh/key.pub + # Create flock to prevent initqueue from timing out waiting for someone to login + echo "initqueue blocked by ssh server" > /tmp/crypt-ssh-block + else + _timeout=$(getargs "rd.luks.timeout") + _timeout=${_timeout:-0} + ask_for_password --ply-tries 5 \ + --ply-cmd "$luks_open -T1 $device $luksname" \ + --ply-prompt "Password ($device)" \ + --tty-tries 1 \ + --tty-cmd "$luks_open -T5 -t $_timeout $device $luksname" + unset _timeout + fi unset luks_open - unset _timeout fi if [ "$is_keysource" -ne 0 -a ${luksname##luks-} != "$luksname" ]; then diff --git a/modules.d/92crypt-ssh/crypt-ssh-cleanup.sh b/modules.d/92crypt-ssh/crypt-ssh-cleanup.sh new file mode 100644 index 00000000..03b05d84 --- /dev/null +++ b/modules.d/92crypt-ssh/crypt-ssh-cleanup.sh @@ -0,0 +1,7 @@ +#!/bin/sh + +# Stops previously started dropbear + +if [ -f /var/run/dropbear.pid ]; then + kill $(cat /var/run/dropbear.pid) +fi diff --git a/modules.d/92crypt-ssh/module-setup.sh b/modules.d/92crypt-ssh/module-setup.sh new file mode 100644 index 00000000..4fd2aadf --- /dev/null +++ b/modules.d/92crypt-ssh/module-setup.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +check() { + require_binaries dropbear || return 1 + + # We need a SSH pub key, as passwords are not an option + # due to the initrd being unencrypted on disk + [ -r /root/.ssh/authorized_keys ] || { + echo "No /root/.ssh/authorized_keys found, needed to authenticate at boot!"; + exit 1; + } + return 255 +} + +depends() { + echo "network crypt" + return 0 +} + +install() { + #Install dropbear + mkdir -p /etc/dropbear + + # Create host keys of needed + [ -r /etc/dropbear/dropbear_dss_host_key ] || /usr/bin/dropbearkey -t dss -f /etc/dropbear/dropbear_dss_host_key > /dev/null + [ -r /etc/dropbear/dropbear_rsa_host_key ] || /usr/bin/dropbearkey -t rsa -f /etc/dropbear/dropbear_rsa_host_key > /dev/null + + inst_multiple dropbear /etc/dropbear/dropbear_dss_host_key /etc/dropbear/dropbear_rsa_host_key + inst /root/.ssh/authorized_keys /root/.ssh/key.pub + + inst_hook initqueue/online 60 "$moddir/start-ssh.sh" + inst_hook cleanup 99 "$moddir/crypt-ssh-cleanup.sh" +} diff --git a/modules.d/92crypt-ssh/start-ssh.sh b/modules.d/92crypt-ssh/start-ssh.sh new file mode 100644 index 00000000..ac1c5ec3 --- /dev/null +++ b/modules.d/92crypt-ssh/start-ssh.sh @@ -0,0 +1,27 @@ +#!/bin/sh + +# Start dropbear server once online + +type get_ip >/dev/null 2>&1 || . /lib/net-lib.sh + +port=$(getargnum 22 1 65535 rd.luks.ssh.port) +listen_ip=$(get_ip $1) +pid_file="/var/run/dropbear_$listen_ip_$port.pid" + +[ "x$listen_ip" != "x" ] && listen_ip="$listen_ip:" + +if [ -x "/usr/sbin/dropbear" ]; then + if [ -r /root/.ssh/authorized_keys ]; then + touch /var/log/lastlog + /usr/sbin/dropbear -p $listen_ip$port -m -j -k -s -P $pid_file + # flock will be removed upon successful luksopen via forced_command + while [ -e /tmp/crypt-ssh-block ]; do + sleep 1 + done + kill $(cat $pid_file) + else + warn "No authorized_keys files, not starting SSH server!" + fi +else + warn "initqueue/online/start-ssh: Could not find dropbear binary!" +fi