如何在没有 UEFI 引导加载程序的 Linux 上使用完全加密磁盘实现安全启动

大家好!我是大聪明-PLUS的 DevOps 工程师。本文面向经验丰富的 Linux 用户。我将演示如何使用标准安装程序在安全启动模式下安装Debian及其类似版本。我在 AWS ARM64 和 Selectel Cloud 上测试了此安装。最终脚本也适用于服务型联想 ThinkPad T14 和个人版。

我们最终将实现的目标:

  1. 启用使用个人密钥进行安全启动。这样,我们将只能启动使用我们密钥签名的 EFI 文件。这将排除运行使用其他密钥签名的第三方 EFI 文件(例如 Microsoft 或硬件制造商的 EFI 文件)的可能性。

  2. 内核文件和 initramfs 已使用我们的密钥签名。这得益于UKI的使用。这样我们就得到了一个 EFI 文件,其内容已签名。这使我们能够从启动序列中排除 grub 或 systemd-boot。排除引导​​加载程序对于减少入侵笔记本电脑的潜在风险至关重要。

  3. 除 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作为软件包。bookwormbookworm

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
  1. 我们还将对其进行配置/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 签名内核的启动选项

需要注意的是,在过渡期间,系统引导可能会中断,因为安装的功能可能无法被考虑。为了避免这种情况,您需要执行以下操作:

  1. 我们将 PC 启动切换到安全启动设置模式。之后,就可以从操作系统进行配置了。

  2. 我们将优先级改为bookworm-backports与 相同bookworm。这对于安装 systemd-ukify 是必要的:

cat >/etc/apt/preferences.d/bookworm-backports <<EOF
Package: *
Pin: release bookworm-backports
Pin-Priority: 500
EOF
  1. 让我们更新新系统上的软件包以安装以下版本bookworm-backports

apt update && apt full-upgrade -y"
  1. 让我们安装必要的软件包:

apt-install systemd-boot-efi efibootmgr sbsigntool python3-pefile
  1. 我们来记住内核启动参数:

root_fs=$(cat/etc/fstab | grep errors=remount-ro | grep " / " | awk '{print "root=" $1}')
echo "$root_fs ro" > /etc/kernel/cmdline
  1. 让我们对 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
  1. 我们使用它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
  1. 我们还将对其进行配置/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
  1. 让我们为 EFI 创建密钥,将它们加载到 UEFI 中并更新 initramfs 和 EFI 文件:

sbctl create-keys
sbctl enroll-keys
update-initramfs -u -k all
  1. 重新启动后,如果下载成功完成,您应该关闭使用新选项更改 BIOS 设置的权限。

结果

安装完成后,我们会将 Debian 安装在一个加密磁盘上,该磁盘包含一个有限的可从笔记本电脑启动的目录。在这样的系统中,我们信任 UEFI——它不会允许未签名的 EFI 文件启动。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值