Как сделать безопасную загрузку с полностью зашифрованным диском на Linux без загрузчика на UEFI

от автора

Всем привет! На связи Алексей Гаврилов, DevOps-инженер компании «Флант». Эта статья предназначена для довольно искушённых пользователей Linux. Я покажу, как устанавливать Debian или его аналоги стандартным установщиком в Secure boot. Эту установку я проверил на AWS ARM64 и в Selectel Cloud. Также конечные скрипты работают на служебном Lenovo ThinkPad T14 и личном L380 Yoga.

Чего в итоге мы добьёмся:

  1. Включённый Secure boot с личными ключами для него. Так мы получим возможность загружать только EFI-файлы, подписанные нашим ключом. Это исключит возможность запуска сторонних EFI-файлов, подписанных другими ключами, например, Microsoft или производителем железа.

  2. Файл ядра и initramfs, которые подписаны нашим ключом. Это возможно благодаря использованию UKI. Так мы получаем EFI-файл, содержимое которого подписано. Это позволяет нам исключить из последовательности загрузки grub или systemd-boot. Исключение загрузчиков нужно для уменьшения возможного вектора взлома ноутбука.

  3. Зашифрованные разделы, кроме 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
  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"

Скрипт для установки Debian

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

Скрипт

Как перейти на вариант загрузки с подписанным uki ядром на уже работающем grub для UEFI

Стоит учитывать, что при переходе можно сломать загрузку системы, так как можно не учесть особенности именно вашей инсталляции. Чтобы избежать этого, нужно сделать следующее:

  1. Переведём загрузку ПК в режим настройки Secure boot. После этого он может быть настроен из операционной сиситемы.

  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. Сделаем дополнительную настройку для 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
  1. Используем 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
  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-файлы.

Используемые ссылки:


ссылка на оригинал статьи https://habr.com/ru/articles/835778/