Как сделать безопасную загрузку с полностью зашифрованным диском на Linux без загрузчика на UEFI
- воскресенье, 25 августа 2024 г. в 00:00:08
Всем привет! На связи Алексей Гаврилов, DevOps-инженер компании «Флант». Эта статья предназначена для довольно искушённых пользователей Linux. Я покажу, как устанавливать Debian или его аналоги стандартным установщиком в Secure boot. Эту установку я проверил на AWS ARM64 и в Selectel Cloud. Также конечные скрипты работают на служебном Lenovo ThinkPad T14 и личном L380 Yoga.
Чего в итоге мы добьёмся:
Включённый Secure boot с личными ключами для него. Так мы получим возможность загружать только EFI-файлы, подписанные нашим ключом. Это исключит возможность запуска сторонних EFI-файлов, подписанных другими ключами, например, Microsoft или производителем железа.
Файл ядра и initramfs, которые подписаны нашим ключом. Это возможно благодаря использованию UKI. Так мы получаем EFI-файл, содержимое которого подписано. Это позволяет нам исключить из последовательности загрузки grub или systemd-boot. Исключение загрузчиков нужно для уменьшения возможного вектора взлома ноутбука.
Зашифрованные разделы, кроме EFI boot. Так мы получим возможность исключить утечку данных в случае кражи ноутбука, а также усложним жизнь потенциальному взломщику тем, что в его распоряжении будут только подписанные EFI-файлы.
Прежде чем перейти к установке, убедимся, что Secure Boot находится в режиме настройки. При этом настройки UEFI BIOS должны быть защищены паролем, чтобы Secure boot нельзя было отключить.
Дальше работаем по следующему алгоритму:
1. Нужно загрузиться с установщика и выбрать экспертный режим. Это даёт дополнительные вопросы при установке, но также и возможности в более тонкой настройке новой системы.
2. С помощью программы установки разобьём диск на:
системный раздел EFI (он должен быть как минимум 512 МБ, иначе все 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. На этапе установки системы выберем backports
в качестве пакета для bookworm
(stable), так как в bookworm
нет systemd-ukify.
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. Сделаем дополнительную настройку для kernel-install
из состава systemd. Данные скрипты добавляют собранные 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
, чтобы упростить создание сертификатов для Secure boot и их применение к UEFI.
sbctl
на данный момент нет в Debian, поэтому приходится ставить с GitHub. Ключ --yes-this-might-brick-my-machine
нужен только для AWS, так как в VM используется довольно старая версия EFI BIOS. После исполнения данной части Secure boot перейдёт в режим пользователя, так как 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. В нашем случае — добавление SSH-ключей пользователю root и настройка 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
Так как установка предполагается по сети, используется 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. Модификация системы для загрузки в 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
Стоит учитывать, что при переходе можно сломать загрузку системы, так как можно не учесть особенности именно вашей инсталляции. Чтобы избежать этого, нужно сделать следующее:
Переведём загрузку ПК в режим настройки Secure boot. После этого он может быть настроен из операционной сиситемы.
Поменяем приоритет 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
Сделаем дополнительную настройку для kernel-install
из состава systemd. Данные скрипты добавляют собранные 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
, чтобы упростить создание сертификатов для Secure boot и их применение к UEFI.
sbctl
на данный момент нет в Debian, поэтому приходится ставить с GitHub. После исполнения данной части Secure boot перейдёт в режим пользователя, так как 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-файлы.
Используемые ссылки: