This has been a "need" for a long time for home users with FDE. The go-to software solution for Linux has been:
I use OpenSuse so I had to use the guide for Fedora, but there were some differences as far as I remember.
Fedora, RHEL, CentOS, Rocky, Alma, Arch, and Gentoo
Dracut is available on:
Debian and Ubuntu
That covers most common Linux distros.
-
Personally, I'm using this on Fedora.
/usr/lib/dracut/modules.d/46cryptssh:
#!/bin/bash
check() {
require_binaries sshd || return 1
return 0
}
depends() {
return 0
}
install() {
if [ ! -e /etc/ssh/dracut ]; then
mkdir /etc/ssh/dracut &&
tmp=$(mktemp -d) &&
head -c128 /dev/random > $tmp/passphrase &&
ssh-keygen -t ed25519 -f /etc/ssh/dracut/ssh_host_ed25519_key -N"$(base64 < $tmp/passphrase)" &&
tpm2_createprimary -C o -c $tmp/primary.ctx &&
tpm2_pcrread -o $tmp/pcr.bin sha256:0,7
tpm2_createpolicy --policy-pcr -l sha256:0,7 -f $tmp/pcr.bin -L $tmp/pcr.policy
tpm2_create -C $tmp/primary.ctx -L $tmp/pcr.policy -i $tmp/passphrase -c $tmp/seal.ctx &&
tpm2_evictcontrol -C o -c $tmp/seal.ctx -o /etc/ssh/dracut/seal || {
rm -r $tmp /etc/ssh/dracut
exit 1
}
rm -r $tmp
fi
for file in /etc/ssh/dracut/*; do
inst_simple "$file" "/etc/ssh/${file#/etc/ssh/dracut/}"
done
mkdir -p -m 0700 "$initdir"/root/.ssh
/usr/bin/install -m 600 /etc/ssh/dracut_authorized_keys "$initdir"/root/.ssh/authorized_keys
inst_binary /usr/sbin/sshd
inst_binary /usr/sbin/ssh-keygen
inst_binary /usr/bin/tpm2_unseal
inst_binary /usr/bin/base64
inst_simple /usr/lib/libtss2-tcti-device.so
inst_simple "$moddir"/cryptsshd.service "$systemdsystemunitdir"/cryptsshd.service
inst_simple "$moddir"/sshd_config /etc/ssh/sshd_config
inst_binary /usr/lib/ssh/sshd-session
inst_binary /usr/lib/ssh/sshd-auth
mkdir -p -m 0755 "$initdir"/var/empty/sshd
mkdir -p -m 0755 "$initdir"/usr/share/empty.sshd
mkdir -p -m 0755 "$initdir"/var/log
touch "$initdir"/var/log/lastlog
systemctl -q --root "$initdir" enable cryptsshd
}
cryptsshd.service: [Unit]
Description=OpenSSH Daemon for Disk Encryption Passphrase
DefaultDependencies=no
Before=cryptsetup.target
After=network-online.target
[Service]
Type=notify-reload
ExecStartPre=/bin/sh -c '/usr/bin/ssh-keygen -p -f /etc/ssh/ssh_host_ed25519_key \
-N "" -P "$(/usr/bin/tpm2_unseal -c /etc/ssh/seal -p pcr:sha256:0,7 | base64)"'
ExecStart=/usr/bin/sshd -D
KillMode=process
Restart=always
[Install]
WantedBy=sysinit.target
That encrypts the SSH host key using a password sealed with PCR7, which is invalidated if an attacker disables Secure Boot or tampers with the enrolled keys. Thus, an attacker can't extract the key from the drive or by modifying the kernel command line to boot to a shell (since that's not allowed without disabling secure boot).It's still probably vulnerable to a cold boot attack, since the key is decrypted CPU-side. It would be interesting to perform the actual key operations on the TPM itself to prevent this.