大家好!我是大聪明-PLUS的 DevOps 工程师。本文面向经验丰富的 Linux 用户。我将演示如何使用标准安装程序在安全启动模式下安装Debian及其类似版本。我在 AWS ARM64 和 Selectel Cloud 上测试了此安装。最终脚本也适用于服务型联想 ThinkPad T14 和个人版。
我们最终将实现的目标:
-
启用使用个人密钥进行安全启动。这样,我们将只能启动使用我们密钥签名的 EFI 文件。这将排除运行使用其他密钥签名的第三方 EFI 文件(例如 Microsoft 或硬件制造商的 EFI 文件)的可能性。
-
内核文件和 initramfs 已使用我们的密钥签名。这得益于UKI的使用。这样我们就得到了一个 EFI 文件,其内容已签名。这使我们能够从启动序列中排除 grub 或 systemd-boot。排除引导加载程序对于减少入侵笔记本电脑的潜在风险至关重要。
-
除 EFI 启动分区外,所有分区均已加密。这样可以防止笔记本电脑被盗时数据泄露,同时确保潜在黑客只能使用已签名的 EFI 文件,从而加大攻击难度。
手动安装选项
在继续安装之前,请确保“安全启动” 处于设置模式。在这种情况下,UEFI BIOS 设置必须受密码保护,以确保“安全启动”无法被禁用。
接下来我们按照以下算法进行工作:
1. 您需要从安装程序启动并选择专家模式。这不仅会在安装过程中带来更多问题,也为进一步微调新系统提供了机会。
2. 使用安装程序,我们将磁盘分区为:
-
EFI 系统分区(必须至少有 512 MB,否则所有 EFI 文件可能无法容纳);
-
加密的根分区。在这里,您可以根据需要设置分区的复杂程度。最重要的是记住,这些分区位于LUKS分区或其等效分区中。
[12:18:23][ssh][root@aws2] ~ $ cat /etc/crypttab
nvme0n1p2_crypt UUID=2de785af-2b9e-432a-bb31-a8f1fe36fa31 none luks,discard
[12:18:29][ssh][root@aws2] ~ $ cat /etc/fstab
/dev/mapper/aws-root / ext4 errors=remount-ro 0 1
# /boot/efi was on /dev/nvme0n1p1 during installation
UUID=F751-88E0 /boot/efi vfat umask=0077 0 1
/swapfile swap swap defaults 0 0
[12:18:35][ssh][root@aws2] ~ $ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
zram0 253:0 0 466M 0 disk [SWAP]
nvme0n1 259:0 0 25G 0 disk
├─nvme0n1p1 259:1 0 487M 0 part /boot/efi
└─nvme0n1p2 259:2 0 24.5G 0 part
└─nvme0n1p2_crypt 254:0 0 24.5G 0 crypt
└─aws-root 254:1 0 24.5G 0 lvm /
3. 在系统安装阶段,由于没有 systemd-ukify ,我们将选择 (stable)backports
作为软件包。bookworm
bookworm
4. 在引导加载程序选择阶段,我们将选择不带引导加载程序的选项。在这种情况下,我们需要跳过安装 grub 的步骤。
5. 完成安装。您需要在重新启动之前停止安装,因为此时系统将无法正常启动。
6、切换到Shell模式/target
,修改安装过程中挂载的新系统。
7. 将优先级更改bookworm-backports
为与 相同bookworm
。这对于安装 systemd-ukify 是必要的。
TARGET=/target
# ukify install
cat > $TARGET/etc/apt/preferences.d/bookworm-backports <<EOF
Package: *
Pin: release bookworm-backports
Pin-Priority: 500
EOF
8. 更新新系统中的软件包以安装以下版本bookworm-backports
:
in-target sh -c "export DEBIAN_FRONTEND=noninteractive && apt update && apt full-upgrade -y"
9.安装必要的软件包:
apt-install systemd-boot-efi efibootmgr sbsigntool python3-pefile
10. 让我们设置dropbear
通过 SSH 远程输入加密磁盘密码的功能。在本例中,我们dropbear
在启动时重新配置到端口 1022,并建立到 的硬链接/root/.ssh/authorized_keys
。这将允许您在启动服务器时使用相同的密钥登录,并且在更改内容时,应用 后会获取新的密钥列表update-initramfs
:
apt-install dropbear-initramfs
echo 'DROPBEAR_OPTIONS="-I 600 -j -k -p 1022 -s -c cryptroot-unlock"' >> $TARGET/etc/dropbear/initramfs/dropbear.conf
ln $TARGET/root/.ssh/authorized_keys $TARGET/etc/dropbear/initramfs/authorized_keys
11.我们来记住内核启动参数:
root_fs=$(cat $TARGET/etc/fstab | grep errors=remount-ro | grep " / " | awk '{print "root=" $1}')
echo "$root_fs ro" > $TARGET/etc/kernel/cmdline
12. 让我们对 systemd 进行额外的设置kernel-install
。这些脚本将组装好的 EFI 内核文件添加到启动菜单中。此外,还添加了将内核组装到 EFI 文件中的设置:
cat > $TARGET/etc/kernel/install.d/99-efiboot.install <<EOF
#!/bin/sh
set -e
[ "\$KERNEL_INSTALL_LAYOUT" = "uki" ] || exit 0
COMMAND="\${1:?}"
KERNEL_VERSION="\${2:?}"
boot=\$(mount | grep "\$KERNEL_INSTALL_BOOT_ROOT" | awk '{print \$1}')
case "\$COMMAND" in
remove)
if [ "\$(efibootmgr | grep \$KERNEL_VERSION | wc -l)" -eq "1" ] ; then
efibootmgr -B -b "\$(efibootmgr | grep \$KERNEL_VERSION | cut -c 5-8)"
fi
;;
add)
if [ "\$(efibootmgr | grep \$KERNEL_VERSION | wc -l)" -eq "0" ] ; then
prefix='\EFI\Linux\'
efibootmgr -d \$boot -C -L "\${KERNEL_VERSION}" -l "\$prefix\${KERNEL_INSTALL_ENTRY_TOKEN}-\${KERNEL_VERSION}.efi"
fi
if [ -f "/boot/initrd.img" ] ; then
if [ "\$(ls -la /boot/initrd.img | grep \$KERNEL_VERSION | wc -l)" -eq "1" ] ; then
efibootmgr -o "\$(efibootmgr | grep \$KERNEL_VERSION | cut -c 5-8)"
fi
else
if [ "\$(efibootmgr | grep BootOrder: | grep \$(efibootmgr | grep \$KERNEL_VERSION | cut -c 5-8) | wc -l)" -eq "0" ] ; then
list=""
if [ "\$(efibootmgr | grep BootOrder: | awk '{print \$2}' | wc -l)" -eq "1" ] ; then
list=",\$(efibootmgr | grep BootOrder: | awk '{print \$2}')"
fi
efibootmgr -o "\$(efibootmgr | grep \$KERNEL_VERSION | cut -c 5-8)\$list"
fi
fi
;;
*)
exit 0
;;
esac
EOF
chmod +x $TARGET/etc/kernel/install.d/99-efiboot.install
cat > $TARGET/etc/kernel/install.conf <<EOF
layout=uki
uki_generator=ukify
EOF
cat > $TARGET/etc/kernel/postrm.d/zz-kernel-install <<EOF
#!/bin/bash
if [[ -z \${1:-} ]]; then
echo "E: initramfs-tools: \${DPKG_MAINTSCRIPT_PACKAGE:-kernel package} did not pass a version number" >&2
exit 1
else
version="\$1"
fi
kernel-install remove "\${version}" "/boot/vmlinuz-\${version}" "/boot/initrd.img-\${version}"
EOF
chmod +x $TARGET/etc/kernel/postrm.d/zz-kernel-install
cat > $TARGET/etc/kernel/postinst.d/zz-kernel-install <<EOF
#!/bin/bash
if [[ -z \${1:-} ]]; then
echo "E: initramfs-tools: \${DPKG_MAINTSCRIPT_PACKAGE:-kernel package} did not pass a version number" >&2
exit 1
else
version="\$1"
fi
kernel-install add "\${version}" "/boot/vmlinuz-\${version}" "/boot/initrd.img-\${version}"
EOF
mkdir -p $TARGET/etc/initramfs/post-update.d/
ln $TARGET/etc/kernel/postinst.d/zz-kernel-install $TARGET/etc/initramfs/post-update.d/zz-kernel-install
chmod +x $TARGET/etc/kernel/postinst.d/zz-kernel-install
13.用于sbctl
简化安全启动证书的创建及其在UEFI中的应用。
sbctl
目前 Debian 中没有,所以你必须从 GitHub 安装。--yes-this-might-brick-my-machine
由于虚拟机使用的 EFI BIOS 版本比较老,所以只有 AWS 才需要密钥。执行此部分后,安全启动将切换到用户模式,因为sbctl
它会将创建的密钥加载到用户模式中:
ARCH=$(chroot /target/ dpkg --print-architecture)
wget --quiet https://github.com/Foxboron/sbctl/releases/download/0.14/sbctl-0.14-linux-$ARCH.tar.gz -O - | tar -xz sbctl/sbctl -O > $TARGET/usr/local/bin/sbctl
chmod +x $TARGET/usr/local/bin/sbctl
-
我们还将对其进行配置
/etc/kernel/uki.conf
,以便在创建时使用指定的密钥对 EFI 文件进行签名:
cat > $TARGET/etc/kernel/uki.conf <<EOF
[UKI]
SecureBootSigningTool=sbsign
SecureBootPrivateKey=/usr/share/secureboot/keys/db/db.key
SecureBootCertificate=/usr/share/secureboot/keys/db/db.pem
EOF
15. 让我们为 EFI 创建密钥,将它们加载到 UEFI 中并更新 initramfs 和 EFI 文件:
in-target sh -c "mount -o rw -t efivarfs efivarfs /sys/firmware/efi/efivars; \
sbctl create-keys; \
sbctl enroll-keys --yes-this-might-brick-my-machine; \
update-initramfs -u -k all; \
umount /sys/firmware/efi/efivars;"
自动安装选项
这是一个几乎自动化的安装版本。撰写本文时,需要进行磁盘分区。此选项需要 Nginx 正常运行,并且在安装过程中可以从服务器访问文件。文件中的链接需要替换为您自己的链接。
1. 让我们构建一个 EFI 安装程序文件,其中包含用于加载自动安装响应文件的参数auto=true url=https://le9i0nx.gitlab.io/autoinstall/aws-crypt.cfg interface=auto netcfg/dhcp_timeout=60 keyboard-configuration/xkb-keymap=en priority=critical
,以及通过 ttyS0 设置交互(这对于在 AWS 中工作是必需的)console=tty0 console=ttyS0
。执行后,我们将获得/boot/efi/EFI/BOOT/BOOTAA64.EFI
,并从中启动安装程序:
#!/bin/sh
set -x
wget "https://ftp.debian.org/debian/dists/stable/main/installer-amd64/current/images/netboot/debian-installer/amd64/initrd.gz"
wget "https://ftp.debian.org/debian/dists/stable/main/installer-amd64/current/images/netboot/debian-installer/amd64/linux"
apt update
apt install systemd-boot-efi binutils python3-pefile -y
wget https://raw.githubusercontent.com/systemd/systemd/v255/src/ukify/ukify.py -v -O /usr/local/bin/ukify
chmod +x /usr/local/bin/ukify
mkdir -p /boot/efi/EFI/BOOT/
ukify build \
--linux=./linux \
--initrd=./initrd.gz \
--cmdline="auto=true url=https://le9i0nx.gitlab.io/autoinstall/aws-crypt.cfg interface=auto netcfg/dhcp_timeout=60 keyboard-configuration/xkb-keymap=en priority=critical theme=dark gfxpayload=800x600x16,800x600 console=tty0 console=ttyS0" \
--uname="Debian install" \
--output "/boot/efi/EFI/BOOT/BOOTAA64.EFI"
2. 几乎自动安装的应答文件。这里最重要的部分是命令d-i preseed/late_command string
。它会在 Debian 安装后执行任意命令。在我们的例子中,向 root 用户添加 SSH 密钥并设置安全启动:
d-i preseed/late_command string \
wget --quiet -O - https://le9i0nx.gitlab.io/autoinstall/ssh.sh > /ssh.sh; \
sh /ssh.sh /target; \
wget --quiet -O - https://le9i0nx.gitlab.io/autoinstall/secure-boot/kernel-install.sh > /install.sh; \
sh /install.sh /target
由于安装应该通过网络进行,因此使用了 d -i network-console/authorized_keys_url string
。它指向一个包含可用于继续安装的密钥的文件:
d-i keyboard-configuration/xkb-keymap select us
d-i netcfg/get_hostname string unassigned-hostname
d-i netcfg/get_domain string unassigned-domain
d-i hw-detect/load_firmware boolean true
d-i anna/choose_modules string network-console
d-i preseed/early_command string anna-install network-console
d-i network-console/password password root42
d-i network-console/password-again password root42
d-i network-console/authorized_keys_url string https://le9i0nx.gitlab.io/autoinstall/authorized_keys
d-i debian-installer/language string en
d-i debian-installer/country string US
d-i debian-installer/locale string en_US.UTF-8
d-i localechooser/supported-locales multiselect en_US.UTF8, ru_RU.UTF8
d-i console-keymaps-at/keymap select us
d-i keyboard-configuration/variant select American English
d-i netcfg/choose_interface select auto
d-i mirror/http/proxy string
tzsetup-udeb time/zone select UTC
d-i clock-setup/utc boolean true
d-i clock-setup/ntp boolean true
clock-setup clock-setup/ntp-server string pool.ntp.org
d-i apt-setup/contrib boolean true
d-i apt-setup/non-free boolean true
d-i apt-setup/non-free-firmware boolean true
apt-setup-udeb apt-setup/enable-source-repositories boolean false
popularity-contest popularity-contest/participate boolean true
tasksel tasksel/first multiselect ssh-server, standard
d-i pkgsel/include string openssh-server wget ca-certificates vim
pkgsel pkgsel/update-policy select unattended-upgrades
pkgsel pkgsel/upgrade select full-upgrade
openssh-server openssh-server/password-authentication boolean false
d-i base-installer/install-recommends boolean false
bootstrap-base base-installer/initramfs-tools/driver-policy select most
d-i passwd/root-login boolean true
d-i passwd/root-password-crypted password $6$0YbiHUntJTa$k7geJE7k0.GJqG8XZKpIHrM0frlVX5ZsxFFsZ6D7SGb2IZ08La6bV8KPYkkPNEK6NJzmOggU/T3JRE0lRwE6w1
d-i passwd/make-user boolean false
d-i preseed/late_command string \
wget --quiet -O - https://le9i0nx.gitlab.io/autoinstall/ssh.sh > /ssh.sh; \
sh /ssh.sh /target; \
wget --quiet -O - https://le9i0nx.gitlab.io/autoinstall/secure-boot/kernel-install.sh > /install.sh; \
sh /install.sh /target
d-i apt-setup/services-select multiselect security, updates, backports
#bootstrap-base base-installer/kernel/image select linux-image-cloud-arm64
#d-i debian-installer/add-kernel-opts string console=tty0 console=ttyS0
3.加载SSH访问的密钥列表:
#!/bin/sh
TARGET=$1
mkdir -p $TARGET/root/.ssh
chmod 0700 $TARGET/root/.ssh
wget --quiet -O - https://le9i0nx.gitlab.io/autoinstall/authorized_keys >> $TARGET/root/.ssh/authorized_keys
chmod 0600 $TARGET/root/.ssh/authorized_keys
4.修改系统以启动到安全启动:
#!/bin/sh
set -x
TARGET=$1
# ukify install
cat > $TARGET/etc/apt/preferences.d/bookworm-backports <<EOF
Package: *
Pin: release bookworm-backports
Pin-Priority: 500
EOF
# ukify install python3-pefile -> systemd-ukify
PACKAGE="systemd-boot-efi efibootmgr sbsigntool python3-pefile dropbear-initramfs"
if [ "$TARGET" = "" ]; then
apt update
apt full-upgrade -y
apt install -y $PACKAGE
else
in-target sh -c "export DEBIAN_FRONTEND=noninteractive && apt update && apt full-upgrade -y"
apt-install $PACKAGE
fi
# dropbear
echo 'DROPBEAR_OPTIONS="-I 600 -j -k -p 1022 -s -c cryptroot-unlock"' >> $TARGET/etc/dropbear/initramfs/dropbear.conf
ln $TARGET/root/.ssh/authorized_keys $TARGET/etc/dropbear/initramfs/authorized_keys
#kernel-install fixed
root_fs=$(cat $TARGET/etc/fstab | grep errors=remount-ro | grep " / " | awk '{print "root=" $1}')
#echo "$root_fs ro console=tty0 console=ttyS0" > $TARGET/etc/kernel/cmdline
echo "$root_fs ro" > $TARGET/etc/kernel/cmdline
cat > $TARGET/etc/kernel/install.d/99-efiboot.install <<EOF
#!/bin/sh
set -e
[ "\$KERNEL_INSTALL_LAYOUT" = "uki" ] || exit 0
COMMAND="\${1:?}"
KERNEL_VERSION="\${2:?}"
boot=\$(mount | grep "\$KERNEL_INSTALL_BOOT_ROOT" | awk '{print \$1}')
case "\$COMMAND" in
remove)
if [ "\$(efibootmgr | grep \$KERNEL_VERSION | wc -l)" -eq "1" ] ; then
efibootmgr -B -b "\$(efibootmgr | grep \$KERNEL_VERSION | cut -c 5-8)"
fi
;;
add)
if [ "\$(efibootmgr | grep \$KERNEL_VERSION | wc -l)" -eq "0" ] ; then
prefix='\EFI\Linux\'
efibootmgr -d \$boot -C -L "\${KERNEL_VERSION}" -l "\$prefix\${KERNEL_INSTALL_ENTRY_TOKEN}-\${KERNEL_VERSION}.efi"
fi
if [ -f "/boot/initrd.img" ] ; then
if [ "\$(ls -la /boot/initrd.img | grep \$KERNEL_VERSION | wc -l)" -eq "1" ] ; then
efibootmgr -o "\$(efibootmgr | grep \$KERNEL_VERSION | cut -c 5-8)"
fi
else
if [ "\$(efibootmgr | grep BootOrder: | grep \$(efibootmgr | grep \$KERNEL_VERSION | cut -c 5-8) | wc -l)" -eq "0" ] ; then
list=""
if [ "\$(efibootmgr | grep BootOrder: | awk '{print \$2}' | wc -l)" -eq "1" ] ; then
list=",\$(efibootmgr | grep BootOrder: | awk '{print \$2}')"
fi
efibootmgr -o "\$(efibootmgr | grep \$KERNEL_VERSION | cut -c 5-8)\$list"
fi
fi
;;
*)
exit 0
;;
esac
EOF
chmod +x $TARGET/etc/kernel/install.d/99-efiboot.install
cat > $TARGET/etc/kernel/install.conf <<EOF
layout=uki
uki_generator=ukify
EOF
cat > $TARGET/etc/kernel/postrm.d/zz-kernel-install <<EOF
#!/bin/bash
if [[ -z \${1:-} ]]; then
echo "E: initramfs-tools: \${DPKG_MAINTSCRIPT_PACKAGE:-kernel package} did not pass a version number" >&2
exit 1
else
version="\$1"
fi
kernel-install remove "\${version}" "/boot/vmlinuz-\${version}" "/boot/initrd.img-\${version}"
EOF
chmod +x $TARGET/etc/kernel/postrm.d/zz-kernel-install
cat > $TARGET/etc/kernel/postinst.d/zz-kernel-install <<EOF
#!/bin/bash
if [[ -z \${1:-} ]]; then
echo "E: initramfs-tools: \${DPKG_MAINTSCRIPT_PACKAGE:-kernel package} did not pass a version number" >&2
exit 1
else
version="\$1"
fi
kernel-install add "\${version}" "/boot/vmlinuz-\${version}" "/boot/initrd.img-\${version}"
EOF
mkdir -p $TARGET/etc/initramfs/post-update.d/
ln $TARGET/etc/kernel/postinst.d/zz-kernel-install $TARGET/etc/initramfs/post-update.d/zz-kernel-install
chmod +x $TARGET/etc/kernel/postinst.d/zz-kernel-install
# sbctl
if [ "$TARGET" = "" ]; then
ARCH=$(dpkg --print-architecture)
else
ARCH=$(chroot /target/ dpkg --print-architecture)
fi
wget --quiet https://github.com/Foxboron/sbctl/releases/download/0.14/sbctl-0.14-linux-$ARCH.tar.gz -O - | tar -xz sbctl/sbctl -O > $TARGET/usr/local/bin/sbctl
chmod +x $TARGET/usr/local/bin/sbctl
cat > $TARGET/etc/kernel/uki.conf <<EOF
[UKI]
SecureBootSigningTool=sbsign
SecureBootPrivateKey=/usr/share/secureboot/keys/db/db.key
SecureBootCertificate=/usr/share/secureboot/keys/db/db.pem
EOF
if [ "$TARGET" = "" ]; then
sbctl create-keys
sbctl enroll-keys --yes-this-might-brick-my-machine
update-initramfs -u -k all
else
in-target sh -c "mount -o rw -t efivarfs efivarfs /sys/firmware/efi/efivars; \
sbctl create-keys; \
sbctl enroll-keys --yes-this-might-brick-my-machine; \
update-initramfs -u -k all; \
umount /sys/firmware/efi/efivars;"
fi
如何在已经运行的 UEFI grub 上切换到使用 uki 签名内核的启动选项
需要注意的是,在过渡期间,系统引导可能会中断,因为安装的功能可能无法被考虑。为了避免这种情况,您需要执行以下操作:
-
我们将 PC 启动切换到安全启动设置模式。之后,就可以从操作系统进行配置了。
-
我们将优先级改为
bookworm-backports
与 相同bookworm
。这对于安装 systemd-ukify 是必要的:
cat >/etc/apt/preferences.d/bookworm-backports <<EOF
Package: *
Pin: release bookworm-backports
Pin-Priority: 500
EOF
-
让我们更新新系统上的软件包以安装以下版本
bookworm-backports
:
apt update && apt full-upgrade -y"
-
让我们安装必要的软件包:
apt-install systemd-boot-efi efibootmgr sbsigntool python3-pefile
-
我们来记住内核启动参数:
root_fs=$(cat/etc/fstab | grep errors=remount-ro | grep " / " | awk '{print "root=" $1}')
echo "$root_fs ro" > /etc/kernel/cmdline
-
让我们对 systemd 进行额外的设置
kernel-install
。这些脚本将组装好的 EFI 内核文件添加到启动菜单中。此外,还添加了将内核组装到 EFI 文件中的设置:
cat > /etc/kernel/install.d/99-efiboot.install <<EOF
#!/bin/sh
set -e
[ "\$KERNEL_INSTALL_LAYOUT" = "uki" ] || exit 0
COMMAND="\${1:?}"
KERNEL_VERSION="\${2:?}"
boot=\$(mount | grep "\$KERNEL_INSTALL_BOOT_ROOT" | awk '{print \$1}')
case "\$COMMAND" in
remove)
if [ "\$(efibootmgr | grep \$KERNEL_VERSION | wc -l)" -eq "1" ] ; then
efibootmgr -B -b "\$(efibootmgr | grep \$KERNEL_VERSION | cut -c 5-8)"
fi
;;
add)
if [ "\$(efibootmgr | grep \$KERNEL_VERSION | wc -l)" -eq "0" ] ; then
prefix='\EFI\Linux\'
efibootmgr -d \$boot -C -L "\${KERNEL_VERSION}" -l "\$prefix\${KERNEL_INSTALL_ENTRY_TOKEN}-\${KERNEL_VERSION}.efi"
fi
if [ -f "/boot/initrd.img" ] ; then
if [ "\$(ls -la /boot/initrd.img | grep \$KERNEL_VERSION | wc -l)" -eq "1" ] ; then
efibootmgr -o "\$(efibootmgr | grep \$KERNEL_VERSION | cut -c 5-8)"
fi
else
if [ "\$(efibootmgr | grep BootOrder: | grep \$(efibootmgr | grep \$KERNEL_VERSION | cut -c 5-8) | wc -l)" -eq "0" ] ; then
list=""
if [ "\$(efibootmgr | grep BootOrder: | awk '{print \$2}' | wc -l)" -eq "1" ] ; then
list=",\$(efibootmgr | grep BootOrder: | awk '{print \$2}')"
fi
efibootmgr -o "\$(efibootmgr | grep \$KERNEL_VERSION | cut -c 5-8)\$list"
fi
fi
;;
*)
exit 0
;;
esac
EOF
chmod +x /etc/kernel/install.d/99-efiboot.install
cat > /etc/kernel/install.conf <<EOF
layout=uki
uki_generator=ukify
EOF
cat > /etc/kernel/postrm.d/zz-kernel-install <<EOF
#!/bin/bash
if [[ -z \${1:-} ]]; then
echo "E: initramfs-tools: \${DPKG_MAINTSCRIPT_PACKAGE:-kernel package} did not pass a version number" >&2
exit 1
else
version="\$1"
fi
kernel-install remove "\${version}" "/boot/vmlinuz-\${version}" "/boot/initrd.img-\${version}"
EOF
chmod +x /etc/kernel/postrm.d/zz-kernel-install
cat > /etc/kernel/postinst.d/zz-kernel-install <<EOF
#!/bin/bash
if [[ -z \${1:-} ]]; then
echo "E: initramfs-tools: \${DPKG_MAINTSCRIPT_PACKAGE:-kernel package} did not pass a version number" >&2
exit 1
else
version="\$1"
fi
kernel-install add "\${version}" "/boot/vmlinuz-\${version}" "/boot/initrd.img-\${version}"
EOF
mkdir -p /etc/initramfs/post-update.d/
ln /etc/kernel/postinst.d/zz-kernel-install /etc/initramfs/post-update.d/zz-kernel-install
chmod +x /etc/kernel/postinst.d/zz-kernel-install
-
我们使用它
sbctl
来简化安全启动证书的创建及其在 UEFI 中的应用。sbctl
目前 Debian 中没有,所以你必须从 GitHub 安装。执行此部分后,安全启动将切换到用户模式,因为sbctl
它会将创建的密钥加载到其中:
ARCH=$(dpkg --print-architecture)
wget --quiet https://github.com/Foxboron/sbctl/releases/download/0.14/sbctl-0.14-linux-$ARCH.tar.gz -O - | tar -xz sbctl/sbctl -O > /usr/local/bin/sbctl
chmod +x /usr/local/bin/sbctl
-
我们还将对其进行配置
/etc/kernel/uki.conf
,以便在创建时使用指定的密钥对 EFI 文件进行签名:
cat > /etc/kernel/uki.conf <<EOF
[UKI]
SecureBootSigningTool=sbsign
SecureBootPrivateKey=/usr/share/secureboot/keys/db/db.key
SecureBootCertificate=/usr/share/secureboot/keys/db/db.pem
EOF
-
让我们为 EFI 创建密钥,将它们加载到 UEFI 中并更新 initramfs 和 EFI 文件:
sbctl create-keys
sbctl enroll-keys
update-initramfs -u -k all
-
重新启动后,如果下载成功完成,您应该关闭使用新选项更改 BIOS 设置的权限。
结果
安装完成后,我们会将 Debian 安装在一个加密磁盘上,该磁盘包含一个有限的可从笔记本电脑启动的目录。在这样的系统中,我们信任 UEFI——它不会允许未签名的 EFI 文件启动。