我正在尝试创建一个基于 tpm2 的自动解锁 sh 脚本,但脚本失败,找不到文件



我正在尝试使用tpm2工具创建基于TPM的解锁脚本,其中包含Tevora安全启动tpm2的说明。我已经设置了密钥,用cryptsetup luksAddKey secret.bin加载了它,然后使用tpm2_unlock -c 0x81000000 --auth pci:sha1:0,2,3,7对其进行了测试并返回 secret.bin 的值。对于额外的措施,为了确保它有效,我将 secret.bin 加载到"/etc/crypttab"中,运行# update-initramfs -u -k all,然后重新启动。重新启动后,系统解锁。

我将以下代码复制到"/etc/initramfs-tools/hooks/tpm2"中

#!/bin/sh -e
if [ "$1" = "prereqs" ]; then exit 0; fi
. /usr/share/initramfs-tools/hook-functions
copy_exec /usr/local/bin/tpm2_unseal
copy_exec /usr/local/lib/libtss2-tcti-device.so

我将我的 etc/crypttab 从cryptname UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx none luks附加到cryptname UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx none luks,keyscript=/usr/local/bin/passphrase-from-tpm

我重写了以下脚本,因为 tpm2-tools 命令已经过时,在新命令中进行了编辑,并将其存储在/usr/local/bin/passphrase-from-tpm 中:

#!/bin/sh
set -e
echo "Unlocking via TPM" >&2
export TPM2TOOLS_TCTI="device:/dev/tpm0"
/usr/local/bin/tpm2_unseal -c 0x81000000 --auth pcr:sha1:0,2,3,7
if [ $? -eq 0 ]; then
exit
fi
/lib/cryptsetup/askpass "Unlocking the disk fallback $CRYPTTAB_SOURCE ($CRYPTTAB_NAME)nEnter passphrase: "

我跑# update-initramfs -u -k all然后重新启动。重新启动时,我收到以下错误:/lib/cryptsetup/scripts/passphrase-from-tpm: line 5: /usr/local/bin/tpm2_unseal: not found

我曾多次尝试从tpm编辑密码短语,但没有成功,包括:

  • 将密码短语从 tpm 移动到"/boot/efi/EFI/BOOT/"并将 crypttab 引用到该文件
  • 修改来自 tpm 的密码短语以使用相对文件路径来tpm_unseal

在我想出如何使用以下命令创建备份 linux 启动之前:

objcopy 
--add-section .osrel=/etc/os-release --change-section-vma .osrel=0x20000 
--add-section .cmdline=cmdline.txt --change-section-vma .cmdline=0x30000 
--add-section .linux="/boot/vmlinuz" --change-section-vma .linux=0x40000 
--add-section .initrd="/boot/initrd.img" --change-section-vma .initrd=0x3000000 
/usr/lib/systemd/boot/efi/linuxx64.efi.stub /boot/EFI/BOOT/BOOT_RECX64.EFI

由于错误,我将完全被锁定在系统之外,并且不得不重新安装Ubuntu大约40次。我吃了很多苦,想退出,但我太固执了,不敢扔旗帜。

只需将tpm2_unseal复制到/usr/local/bin/

我正在尝试按照基本上这些说明以及我发现的其他一些说明进行工作设置。虽然尚未 100% 工作,但请检查/etc/initramfs-tools/hooks/tpm2/usr/local/bin/passphrase-from-tpm是否都标记为可执行文件 (sudo chmod ug+x $filename(。

进行initramfs后,可以运行以下命令以确保与TPM相关的文件确实在映像中。将文件名中的路径替换为update-initramfs所说的它正在生成的任何内容:

$ lsinitramfs /boot/initrd.img-5.0.0-37-generic | egrep "(tpm|libtss)"
lib/cryptsetup/scripts/passphrase-from-tpm
lib/modules/5.0.0-37-generic/kernel/crypto/asymmetric_keys/tpm_key_parser.ko
lib/modules/5.0.0-37-generic/kernel/crypto/asymmetric_keys/asym_tpm.ko
lib/udev/rules.d/tpm-udev.rules
usr/local/lib/libtss2-sys.so.0
usr/local/lib/libtss2-mu.so.0
usr/local/lib/libtss2-sys.so.0.0.0
usr/local/lib/libtss2-tcti-device.so
usr/local/lib/libtss2-tcti-device.so.0
usr/local/lib/libtss2-tcti-device.so.0.0.0
usr/local/lib/libtss2-mu.so.0.0.0
usr/local/bin/tpm2_unseal

此外,我还修改了以下内容/usr/local/bin/passphrase-from-tpm

#!/bin/sh
TPM_DEVICE=/dev/tpm0
TPM_REGISTER=0x81000001
TPM_SEAL_POLICY=sha256:0,2,4,7
export TPM2TOOLS_TCTI="device:$TPM_DEVICE"
if [ "$CRYPTTAB_TRIED" -eq 0 ]; then
echo "Unlocking via TPM" >&2
/usr/local/bin/tpm2_unseal -H $TPM_REGISTER -L $TPM_SEAL_POLICY 
UNSEAL_STATUS=$?
echo "Unseal status $UNSEAL_STATUS" >&2
if [ $UNSEAL_STATUS -eq 0 ]; then
exit
fi
else
echo "TPM unlocking previously failed for $CRYPTTAB_SOURCE ($CRYPTTAB_NAME)" >&2
/lib/cryptsetup/askpass "Enter passphrase for $CRYPTTAB_SOURCE ($CRYPTTAB_NAME): "
fi

请注意,要tpm2_unseal的命令行选项适用于 tpm2-tools 的 3.x 版本。如果您使用的是其他版本,则可能需要更新选项。

我将各种位拉出到文件顶部的变量中。修改TPM_REGISTERTPM_SEAL_POLICY以匹配创建 TPM 对象的方式。set -e已被删除,因为如果任何命令失败,整个脚本将退出,从而防止askpass回退在失败时运行tpm2_unseal。

此外,我注意到如果脚本由于某种原因失败,systemd 将尝试再次运行它。如果 TPM 中的密钥与 LUKS 密钥不匹配,这将导致系统无法启动,因为解封成功,但解锁失败,systemd 将再次运行脚本。

查看crypttab的手册页,我发现提供给键脚本的环境变量之一是CRYPTTAB_TRIED这是它尝试解锁卷的尝试次数。如果CRYPTTAB_TRIED为 0,它将尝试使用 TPM,如以下测试所示(以非 root 身份运行,因此访问 TPM 设备失败(:

$ export CRYPTTAB_SOURCE=some_device
$ export CRYPTTAB_NAME=some_device_name
$ export CRYPTTAB_TRIED=0
$ ./passphrase-from-tpm
Unlocking via TPM
ERROR:tcti:src/tss2-tcti/tcti-device.c:440:Tss2_Tcti_Device_Init() Failed to open device file /dev/tpm0: Permission denied
ERROR: tcti init allocation routine failed for library: "device" options: "/dev/tpm0"
ERROR: Could not load tcti, got: "device"
Unseal status 1

当它尝试再次运行脚本时,CRYPTTAB_TRIED将大于 0,使其改为显示密码提示:

$ export CRYPTTAB_TRIED=1
$ ./passphrase-from-tpm
TPM unlocking previously failed for some_device (some_device_name)
Enter passphrase for some_device (some_device_name):

希望这对您仍然有用,并且对任何试图在 Linux 上使用 TPM 进行磁盘加密的纸牌屋的人都有帮助。

最新更新