initial commit

This commit is contained in:
slonkazoid 2025-01-05 20:04:46 +03:00
commit 99f7903c26
Signed by: slonk
SSH key fingerprint: SHA256:tbZfJX4IOvZ0LGWOWu5Ijo8jfMPi78TU7x1VoEeCIjM
6 changed files with 176 additions and 0 deletions

View file

@ -0,0 +1,83 @@
#!/bin/bash
check() {
require_binaries openssl &&
require_binaries tpm2_createprimary &&
require_binaries tpm2_pcrread &&
require_binaries tpm2_createpolicy &&
require_binaries tpm2_create &&
require_binaries tpm2_unseal ||
return 1
}
depends() {
echo tpm2-tss
echo sshd
}
seal() {
set -e
cd "$tpm_tempdir"
touch key ; chmod 600 key
# generate 256-bit key
openssl rand 32 > key
# create TPM primary context
tpm2_createprimary -Q -c primary.ctx
# gather PCR state
if [ -n "$tpm_pcr_bin" ]; then
dinfo "copying ${tpm_pcr_bin@Q}"
cp "$tpm_pcr_bin" pcr.bin
else
dinfo "reading current PCRs"
tpm2_pcrread -o pcr.bin "${tpm_pcrs?TPM PCR list is required}"
fi
# create policy with the PCR information
tpm2_createpolicy -Q --policy-pcr -l "$tpm_pcrs" -f pcr.bin -L pcr.policy
# seal the encryption key in the TPM
tpm2_create -Q -C primary.ctx -L pcr.policy -i key -c key.ctx
# copy sealed encryption key and relevant information to the initramfs
/usr/bin/install -Dm 644 key.ctx "${initdir}/etc/ssh/key.ctx"
echo "$tpm_pcrs" > "${initdir}/etc/ssh/pcrs"
cd "${initdir}/etc/ssh"
# encrypt keys
for key in ssh_host_*_key; do
openssl aes-256-cbc -e -in "$key" -out "${key}.enc" -kfile "${tpm_tempdir}/key" -iter 1
done
}
install() {
local conffile=${dracutsysrootdir}/etc/default/dracut-sshd-tpm
[ -f "$conffile" ] && . "$conffile"
local tpm_tempdir=$(mktemp -d)
chmod 700 "$tpm_tempdir"
( seal ) || {
dfatal "Couldn't seal keys!"
rm -rf "$tpm_tempdir"
return 1
}
rm -rf "$tpm_tempdir"
# remove unencrypted keys
rm "$initdir"/etc/ssh/ssh_host_*_key
inst_binary /usr/bin/touch
inst_binary /usr/bin/chmod
inst_binary /usr/bin/openssl
inst_binary /usr/bin/basename
inst_binary /usr/bin/tpm2_unseal
inst_simple "${moddir}/unseal.sh" /usr/sbin/unseal.sh
inst_simple "${moddir}/unseal.service" "${systemdsystemunitdir}/unseal.service"
mkdir -p "${initdir}${systemdsystemconfdir}/sshd.service.requires"
ln -s "${systemdsystemunitdir}/unseal.service" "${initdir}${systemdsystemconfdir}/sshd.service.requires"
}

13
47sshd-tpm/unseal.service Normal file
View file

@ -0,0 +1,13 @@
[Unit]
Description=Unseal OpenSSH host keys
DefaultDependencies=no
Before=sshd.service
After=tpm2.target
Requires=tpm2.target
[Service]
Type=oneshot
ExecStart=/usr/sbin/unseal.sh
[Install]
RequiredBy=sshd.service

16
47sshd-tpm/unseal.sh Executable file
View file

@ -0,0 +1,16 @@
#!/bin/sh
set -e
cd /etc/ssh
touch key
chmod 600 key
tpm2_unseal -c key.ctx -p pcr:"$(cat pcrs)" -o key
for enc in *.enc; do
base="${enc%.enc}"
touch "$base"
chmod 600 "$base"
openssl aes-256-cbc -d -in "$enc" -out "$base" -kfile key -iter 1
done

18
README.md Normal file
View file

@ -0,0 +1,18 @@
# dracut-sshd-tpm
TPM sealing of [dracut-sshd](https://github.com/gsauthof/dracut-sshd) host keys
## Configuration
The default configuration is placed into /etc/default/dracut-sshd-tpm. You will
need to configure, at minimum, which registers to use while sealing the host
keys (the `tpm_pcrs` value).
## Building
```sh
dnf install rpkg git
git clone https://git.slonk.ing/slonk/dracut-sshd-tpm
cd dracut-sshd-tpm
rpkg local
```

13
config Normal file
View file

@ -0,0 +1,13 @@
# TPM PCRs (platform control registers) to reference while sealing host keys
# See ArchWiki for a list of registers:
# https://wiki.archlinux.org/title/Trusted_Platform_Module#Accessing_PCR_registers
# Example: `sha256:0,4`
# Required, must be consistent across reboots.
#tpm_pcrs=
# Path to PCR dump to use while creating TPM policy
# The next boot's registers must match for the keys to be unsealed
# You can dump the current ones with the following command:
# root@fedora:~# tpm2_pcrread -o pcr.bin "$tpm_pcrs"
# Not required, will default to reading current register values.
#tpm_pcr_bin=

33
dracut-sshd-tpm.spec Normal file
View file

@ -0,0 +1,33 @@
# vim: syntax=spec
Name: dracut-sshd-tpm
Version: {{{ git_dir_version }}}
Release: 1%{?dist}
Summary: TPM sealing of dracut-sshd host keys
License: MIT
URL: https://git.slonk.ing/slonk/dracut-sshd-tpm
VCS: {{{ git_dir_vcs }}}
Source: {{{ git_dir_pack }}}
BuildArch: noarch
Requires: dracut-sshd tpm2-tools openssl
%description
Seals the SSH host keys used by dracut-sshd using the TPM,
and unseals them before sshd starts up.
%prep
{{{ git_dir_setup_macro }}}
%install
mkdir -p %{buildroot}/usr/lib/dracut/modules.d
cp -r 47sshd-tpm %{buildroot}/usr/lib/dracut/modules.d
install -Dt %{buildroot}/etc/default/dracut-sshd-tpm -m644 config
%files
%dir /usr/lib/dracut/modules.d/47sshd-tpm
/usr/lib/dracut/modules.d/47sshd-tpm/module-setup.sh
/usr/lib/dracut/modules.d/47sshd-tpm/unseal.service
/usr/lib/dracut/modules.d/47sshd-tpm/unseal.sh
%config /etc/default/dracut-sshd-tpm
%changelog
{{{ git_dir_changelog }}}