How to make secure boot with fully encrypted disk without bootloader on UEFI
Hello everyone! This is Alexey Gavrilov, DevOps engineer at Flant. This article is intended for fairly sophisticated Linux users. I will show you how to install Debian or its analogues using the standard installer in Secure boot. I tested this setup on AWS ARM64 and Selectel Cloud. The final scripts also work on a company Lenovo ThinkPad T14 and a personal L380 Yoga.
What we will ultimately achieve:
Enabled Secure boot with personal keys for it. This way we will be able to boot only EFI files signed with our key. This will exclude the possibility of running third-party EFI files signed with other keys, for example, Microsoft or the hardware manufacturer.
The kernel file and initramfs, which are signed with our key. This is possible by using UKI. This way we get an EFI file whose contents are signed. This allows us to exclude grub or systemd-boot from the boot sequence. Excluding bootloaders is necessary to reduce the possible vector of hacking the laptop.
Encrypted partitions, except EFI boot. This will allow us to prevent data leakage in case of laptop theft, and also make life more difficult for a potential hacker by ensuring that he will only have signed EFI files at his disposal.
Manual installation option
Before we proceed with the installation, let's make sure that Secure Boot is enabled is in setup mode. In this case, the UEFI BIOS settings must be password protected so that Secure boot cannot be disabled.
Next we work according to the following algorithm:
1. You need to boot up from the installer and select the expert mode. This gives additional questions during installation, but also opportunities for more fine-tuning of the new system.
2. Using the installation program, we will partition the disk into:
EFI system partition (it must be at least 512 MB, otherwise all EFI files may not fit);
encrypted root partition. Here you can make the partition as complex as you want. The main thing is to remember that the partitions are in LUKS-section or its analogue.
[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. At the system installation stage, select backports
as a package for bookworm
(stable), because in bookworm
no systemd-ukify.
4. At the bootloader selection stage, we will select the option without a bootloader. In this case, we need to skip the point with installing grub.
5. Finish the installation. However, you need to stop before rebooting, as the system will not be able to start correctly at this point.
6. Let's switch in Shell mode to modify a new system that is mounted in /target
during installation.
7. Let's change the priority bookworm-backports
on priority as for bookworm
. This is needed to install 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. Update the packages in the new system to install the versions from bookworm-backports
:
in-target sh -c "export DEBIAN_FRONTEND=noninteractive && apt update && apt full-upgrade -y"
9. Install the necessary packages:
apt-install systemd-boot-efi efibootmgr sbsigntool python3-pefile
10. Let's set it up dropbear
to be able to remotely enter the password for the encrypted disk via SSH. In this case, we reconfigure dropbear
on port 1022 at startup and do hard link on /root/.ssh/authorized_keys
. This will allow you to log in with the same key when starting the server, and also when changing the contents to get a new list of keys after application 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. Let's remember the kernel startup parameters:
root_fs=$(cat $TARGET/etc/fstab | grep errors=remount-ro | grep " / " | awk '{print "root=" $1}')
echo "$root_fs ro" > $TARGET/etc/kernel/cmdline
12. Let's make an additional setting for kernel-install
from systemd. These scripts add the compiled EFI kernel files to the boot menu. Also, a setting is added for compiling kernels into EFI files:
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. Use sbctl
to simplify the creation of certificates for Secure boot and their application to UEFI.
sbctl
currently not in Debian, so you have to install it from GitHub. Key --yes-this-might-brick-my-machine
is only needed for AWS, as the VM uses a fairly old version of the EFI BIOS. After executing this part, Secure boot will switch to user mode, as sbctl
load the generated keys into it:
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
We will also configure
/etc/kernel/uki.conf
so that when created, EFI files are signed with the specified keys:
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. Let's create keys for EFI, load them into UEFI and update initramfs and EFI files:
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;"
Automated installation option
This is a virtually automated version of the installation. At the time of writing, disk partitioning is required. This option requires a working nginx with files accessible from the server during the installation process. The links in the files need to be replaced with your own.
1. Let's build an EFI installer file with parameters for loading the answer file for unattended installation auto=true url=https://le9i0nx.gitlab.io/autoinstall/aws-crypt.cfg interface=auto netcfg/dhcp_timeout=60 keyboard-configuration/xkb-keymap=en priority=critical
as well as settings for interaction via ttyS0 (this is necessary for working in AWS) console=tty0 console=ttyS0
. After execution we get /boot/efi/EFI/BOOT/BOOTAA64.EFI
from which we will launch the installer:
#!/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. Answer file for almost automatic installation. Here the important part is in the command d-i preseed/late_command string
. It executes arbitrary commands after installing Debian. In our case, adding SSH keys to the root user and setting up Secure boot:
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
Since the installation is supposed to be over the network, d is used-i network-console/authorized_keys_url string
. It points to a file with keys that can be used to continue the installation:
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. Load the list of keys for SSH access:
#!/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. Modifying the system to boot into Secure boot:
#!/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
How to switch to boot option with uki signed kernel on already working grub for UEFI
It is worth considering that during the transition, you can break the system boot, since you may not take into account the features of your installation. To avoid this, you need to do the following:
Let's switch the PC boot to Secure boot setup mode. After that, it can be configured from the operating system.
Let's change the priority
bookworm-backports
on priority as forbookworm
. This is needed to install systemd-ukify:
cat >/etc/apt/preferences.d/bookworm-backports <<EOF
Package: *
Pin: release bookworm-backports
Pin-Priority: 500
EOF
Let's update the packages in the new system to install the versions from
bookworm-backports
:
apt update && apt full-upgrade -y"
Let's install the necessary packages:
apt-install systemd-boot-efi efibootmgr sbsigntool python3-pefile
Let's remember the kernel startup parameters:
root_fs=$(cat/etc/fstab | grep errors=remount-ro | grep " / " | awk '{print "root=" $1}')
echo "$root_fs ro" > /etc/kernel/cmdline
Let's make an additional setting for
kernel-install
from systemd. These scripts add the compiled EFI kernel files to the boot menu. Also, a setting is added for compiling kernels into EFI files:
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
We use
sbctl
to simplify the creation of certificates for Secure boot and their application to UEFI.sbctl
is currently not in Debian, so you have to install it from GitHub. After executing this part, Secure boot will switch to user mode, becausesbctl
load the generated keys into it:
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
We will also configure
/etc/kernel/uki.conf
so that when created, EFI files are signed with the specified keys:
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
Let's create keys for EFI, load them into UEFI and update initramfs and EFI files:
sbctl create-keys
sbctl enroll-keys
update-initramfs -u -k all
After restarting, if the download was completed successfully, you should close access to changing BIOS settings using the new option.
Results
Once the installation is complete, we will have Debian installed on an encrypted disk with a limited list of what can be booted from the laptop. In such a system, we trust UEFI – that it will not allow unsigned EFI files to be booted.
Links used:
P.S.
Read also in our blog: