Выберите продукт

Systemd-boot и UKI: unified kernel images для Secure Boot-ready VDS на Debian/Ubuntu

Практический разбор UKI (unified kernel image) и systemd-boot для Debian/Ubuntu на VDS: проверяем UEFI и ESP, ставим загрузчик, собираем UKI через ukify/sd-stub, фиксируем cmdline, обновляем ядро без сюрпризов и готовим процесс подписи для Secure Boot.
Systemd-boot и UKI: unified kernel images для Secure Boot-ready VDS на Debian/Ubuntu

Systemd-boot и UKI (unified kernel image) — практичный способ сделать загрузку Linux более предсказуемой: ядро, initrd, командная строка и метаданные хранятся в одном EFI-файле. Для админа на VDS это означает меньше «магии» вокруг initramfs, меньше рассинхрона конфигов и понятный путь к Secure Boot: подписываем один артефакт на каждое ядро.

Ниже — пошаговая схема для Debian/Ubuntu, ориентированная на сервер без физической консоли. Разберём, что такое sd-stub, как UKI живёт в ESP, как обновлять kernel/initrd без сюрпризов и где чаще всего ломают систему.

Что такое UKI и почему это удобно на VDS

UKI — единый исполняемый EFI-образ (PE/COFF), внутри которого упакованы:

  • ядро Linux (vmlinuz);
  • initrd/initramfs;
  • командная строка ядра (kernel cmdline);
  • опционально микрокод CPU;
  • опционально OS-метаданные (ID, версия, build-id);
  • возможность подписать всё как один файл для Secure Boot.

Для загрузчика это модель «всё-в-одном»: systemd-boot (через bootctl) видит EFI-файлы в ESP и предлагает их в меню. Не нужно поддерживать отдельные записи «ядро тут, initrd там», которые легко рассинхронизировать при обновлении.

На сервере без удобной консоли ценится предсказуемость: UKI снижает шанс получить ситуацию «ядро обновилось, а initrd/параметры — нет».

Как это связано с Secure Boot

Secure Boot в идеале требует, чтобы загрузчик и то, что он запускает, было подписано доверенным ключом. В классической схеме с отдельными vmlinuz и initrd цепочка сложнее: больше объектов, больше мест, где можно ошибиться путём или версией.

UKI упрощает задачу: мы подписываем один EFI-файл на каждую версию ядра. Сам systemd-boot подписывается отдельно. В итоге «цепочка доверия» короче и проще в эксплуатации.

Важно: на многих VDS Secure Boot может быть недоступен на уровне виртуальной прошивки UEFI, или провайдер не даёт им управлять. Но конфигурация «Secure Boot-ready» всё равно полезна: вы выстраиваете процесс сборки/подписи артефактов, и при появлении Secure Boot не придётся переделывать весь boot-процесс.

FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

Схема ESP: каталоги loader, EFI/systemd и EFI/Linux для UKI

Проверяем UEFI, ESP и готовим безопасный план отката

Перед изменениями убедитесь, что система действительно загружена через UEFI (иначе systemd-boot не заработает):

test -d /sys/firmware/efi && echo UEFI || echo BIOS

Проверьте, где смонтирован ESP (EFI System Partition). Обычно это /boot/efi, иногда /efi или /boot:

findmnt -no SOURCE,TARGET,FSTYPE,OPTIONS /boot/efi
ls -la /boot/efi/EFI

Если ESP не смонтирован — смонтируйте и добавьте в /etc/fstab. UUID берите через blkid.

На сервере «без рук» держите страховки:

  • не удаляйте старый загрузчик/старые записи, пока не подтвердили успешную перезагрузку;
  • по возможности обеспечьте out-of-band доступ (serial/VNC в панели);
  • всегда держите минимум два загрузочных варианта: «текущий рабочий» и «новый тестовый».

Устанавливаем systemd-boot и понимаем структуру ESP

Systemd-boot — UEFI-загрузчик, управляется утилитой bootctl. Он читает конфиги в ESP (обычно /boot/efi/loader) и подхватывает UKI из стандартного каталога EFI/Linux.

Базовые команды:

bootctl status
bootctl install
bootctl status

Полезно понимать, что именно появится в ESP:

  • EFI/systemd/systemd-bootx64.efi (или другой arch) — сам загрузчик;
  • loader/loader.conf — глобальные настройки;
  • EFI/Linux/ — стандартное место для UKI.

Минимальный loader.conf (без интерактивного редактирования cmdline в меню):

cat > /boot/efi/loader/loader.conf <<'EOF'
default  @saved
timeout  3
console-mode max
editor   no
EOF

Опция editor no — небольшой, но полезный hardening: в меню нельзя интерактивно править параметры ядра (актуально, если у кого-то появится доступ к консоли).

Из чего состоит UKI: sd-stub, initrd и cmdline

В экосистеме systemd ключевой компонент — sd-stub. Это EFI-«обёртка», которая запускает Linux-ядро и передаёт ему встроенный initrd и командную строку. UKI — это по сути EFI-файл с «приклеенными» секциями.

Сборку UKI обычно делает ukify (часть systemd в современных релизах). Проверка наличия:

ukify --help

Если команды нет, проверьте версию systemd:

systemd --version

На старых Debian/Ubuntu может понадобиться выбрать другой маршрут (например, генерация UKI средствами вашей initramfs-системы). Но базовая эксплуатационная логика всё равно одна: фиксируем cmdline, собираем UKI в ESP, держим минимум 2 версии для отката.

Готовим cmdline для UKI (самое важное на VDS)

В GRUB параметры часто лежат в /etc/default/grub. Для UKI удобнее вынести cmdline в отдельный файл, чтобы сборка была воспроизводимой. Главная задача — корректно указать root и (при необходимости) параметры консоли.

Сначала выясните, на чём живёт корень:

findmnt -no SOURCE,FSTYPE,OPTIONS /
blkid

Надёжнее всего использовать root=UUID=.... Создайте файл:

mkdir -p /etc/kernel
cat > /etc/kernel/cmdline <<'EOF'
root=UUID=PUT-YOUR-ROOT-UUID-HERE ro
EOF

Если у вас используется serial-консоль, добавьте явные console= (значения зависят от платформы/провайдера):

cat > /etc/kernel/cmdline <<'EOF'
root=UUID=PUT-YOUR-ROOT-UUID-HERE ro console=tty0 console=ttyS0,115200n8
EOF

Не копируйте параметры вслепую: лишняя или неверная console= может «спрятать» вывод на ожидаемой консоли и усложнить диагностику.

Собираем первый UKI вручную через ukify

Базовый рецепт: берём текущее ядро и текущий initramfs, собираем EFI-файл в /boot/efi/EFI/Linux/. На Debian/Ubuntu пути обычно такие:

  • ядро: /boot/vmlinuz-<version>;
  • initrd: /boot/initrd.img-<version>.

Узнайте текущую версию ядра:

uname -r

Соберите UKI:

mkdir -p /boot/efi/EFI/Linux
ukify build --linux=/boot/vmlinuz-$(uname -r) --initrd=/boot/initrd.img-$(uname -r) --cmdline=@/etc/kernel/cmdline --output=/boot/efi/EFI/Linux/uki-$(uname -r).efi

Systemd-boot обычно автоматически подхватывает UKI из EFI/Linux. Проверьте список:

bootctl list

Если записи нет, проверьте типовые причины:

  • ESP действительно смонтирован (и вы пишете именно в него);
  • архитектура совпадает (x64/aa64);
  • файл реально лежит в /boot/efi/EFI/Linux/;
  • systemd-boot установлен в ту же ESP, откуда грузится система.

Обновления ядра без сюрпризов: 2–3 UKI, место в ESP и уборка

После установки нового kernel появляется новая пара vmlinuz и initrd. Если UKI собираете вручную (или полуавтоматически), заведите дисциплину:

  • после установки нового ядра — собрать новый UKI;
  • старый UKI не удалять до успешной перезагрузки;
  • держать лимит на количество UKI (ESP часто небольшая).

Практичный минимум для сервера: хранить 2–3 последних UKI, именовать по версии ядра, а после подтверждения работоспособности нового ядра — удалять самое старое ядро штатными средствами ОС, а уже затем чистить соответствующий UKI.

Контролируйте свободное место в ESP:

df -h /boot/efi

Если ESP переполнена, UKI может не записаться целиком или сборка упадёт, а вы заметите это только после перезагрузки. Это один из самых неприятных классов ошибок на VDS.

Если вы настраиваете сервер «в долгую», заранее продумайте разметку: иногда имеет смысл выделить ESP побольше. Отдельно про практику работы с дисками и ФС на VPS/VDS у нас есть материал: выбор и настройка ext4/XFS под VDS.

Процесс подписи EFI-файлов: ключи, UKI и загрузчик в рабочем процессе админа

Автоматизация: безопасный хук на kernel update

На Debian/Ubuntu обновление ядра запускает хуки. Ваша автоматизация должна:

  • собирать UKI для конкретной версии ядра, которую только что установили;
  • не ломать загрузку, если сборка не удалась (старый UKI должен остаться);
  • давать понятный лог результата.

Ниже — пример скрипта, который собирает UKI для заданной версии ядра. Его удобно вызывать из вашего hook-механизма (конкретный путь хука зависит от дистрибутива и того, как у вас устроены обновления ядра).

cat > /usr/local/sbin/uki-build-one <<'EOF'
#!/bin/sh
set -eu
kver="$1"
esp="/boot/efi"
cmdline="/etc/kernel/cmdline"
linux="/boot/vmlinuz-$kver"
initrd="/boot/initrd.img-$kver"
out="$esp/EFI/Linux/uki-$kver.efi"
mkdir -p "$esp/EFI/Linux"
ukify build --linux="$linux" --initrd="$initrd" --cmdline=@"$cmdline" --output="$out"
EOF
chmod +x /usr/local/sbin/uki-build-one

Перед подключением к хукам прогоните вручную (например, для текущего ядра), чтобы убедиться, что CLI ukify в вашей версии systemd понимает --cmdline=@/path:

/usr/local/sbin/uki-build-one $(uname -r)

Дальше подключайте к хукам так, чтобы сбой сборки UKI не прерывал установку пакета ядра и не удалял старые артефакты. На проде лучше иметь отдельный мониторинг на свободное место ESP и на факт появления нового UKI после kernel update.

FastFox SSL
Надежные SSL-сертификаты
Мы предлагаем широкий спектр SSL-сертификатов от GlobalSign по самым низким ценам. Поможем с покупкой и установкой SSL бесплатно!

Secure Boot-ready на практике: ключи, подпись и рутина

Чтобы UKI был «готов к Secure Boot», нужен процесс подписи:

  • ключи (генерация, хранение, ротация);
  • подпись systemd-boot*.efi и каждого uki-*.efi;
  • автоподпись нового UKI при обновлении ядра;
  • контроль того, что именно вы подписываете (исходники/артефакты/хэши).

Главный практический вопрос на VDS: где хранить приватный ключ подписи. Держать его на самом сервере удобно, но рискованно: компрометация ОС означает компрометацию ключа. Более безопасная схема — подписывать артефакты в CI/на отдельной машине и доставлять на сервер уже подписанные EFI-файлы.

Secure Boot — это не «галочка», а процесс управления ключами и артефактами. UKI просто делает этот процесс проще и прозрачнее.

Даже если Secure Boot недоступен у провайдера, вы можете выстроить «готовность»: единый каталог EFI/Linux, единый файл cmdline, воспроизводимая сборка UKI и привычка хранить 2–3 версии для отката. А когда потребуется защищать внешний периметр, уместно добавить SSL-сертификаты для сервисов и интерфейсов управления (это уже другой слой безопасности, но в продакшене обычно нужен).

Типовые проблемы и диагностика

systemd-boot не появляется после install

Проверьте, что вы ставите в ту ESP, с которой реально загружается UEFI. На некоторых VDS бывают несколько дисков/разделов, и «правильная» ESP не та, что примонтирована в /boot/efi. Начните с:

bootctl status

Если доступ к переменным UEFI разрешён, посмотрите записи загрузки:

efibootmgr -v

Если efibootmgr не работает (ограничения прошивки/гипервизора), ориентируйтесь на фактическое содержимое ESP и на то, как был установлен исходный образ ОС.

UKI лежит в ESP, но не виден в меню

Проверьте путь EFI/Linux, расширение .efi и то, что вы используете именно systemd-boot. Быстрая проверка:

bootctl list

Если UKI не подхватился, временно можно создать явный entry-файл, но в большинстве случаев проще привести расположение UKI к стандартному каталогу EFI/Linux и пересобрать образ.

После обновления kernel система не грузится

Чаще всего виноваты:

  • неверный root=UUID=... в cmdline;
  • UKI собран с «чужим» initrd (перепутали версию);
  • ESP переполнена и UKI не записался корректно;
  • параметры консоли настроены так, что вывод «уходит не туда».

Именно поэтому правило «не удалять старый UKI до успешной перезагрузки» — не бюрократия, а обязательная страховка.

Рабочий регламент для продакшена

  1. Перед миграцией убедиться в UEFI и корректном ESP.

  2. Установить systemd-boot через bootctl install и настроить loader.conf.

  3. Зафиксировать cmdline в /etc/kernel/cmdline (root по UUID, при необходимости — serial console).

  4. Собрать UKI для текущего ядра, проверить bootctl list.

  5. Сделать тестовую перезагрузку в окно работ и убедиться, что есть путь отката.

  6. Добавить автоматизацию сборки UKI при kernel update с «мягким» fail.

  7. По мере взросления процесса — добавить подпись UKI и процессы управления ключами.

Итоги

Systemd-boot + UKI превращают загрузку Linux в понятный набор артефактов: один EFI-файл на ядро, единый cmdline и прозрачная схема обновлений. На VDS это особенно полезно: цена ошибки при kernel update выше, а доступ к консоли может быть ограничен.

Если аккуратно организовать хранение UKI в ESP, дисциплину обновлений и (по возможности) подпись, вы получаете «Secure Boot-ready» подход, который проще поддерживать, автоматизировать и проверять.

Поделиться статьей

Вам будет интересно

systemd: journalctl, systemctl status и лимиты запуска StartLimit/Timeout* без боли OpenAI Статья написана AI (GPT 5)

systemd: journalctl, systemctl status и лимиты запуска StartLimit/Timeout* без боли

Если сервис в systemd уходит в restart loop, падает с failed to start или «не успевает» подняться — почти всегда дело в логах и ли ...
Linux: TCP Fast Open (TFO) для Nginx через systemd sysctl — включение, проверка и отладка OpenAI Статья написана AI (GPT 5)

Linux: TCP Fast Open (TFO) для Nginx через systemd sysctl — включение, проверка и отладка

TCP Fast Open (TFO) ускоряет старт TCP-соединения за счёт данных в SYN при повторных подключениях. Показываю, как включить net.ipv ...
OpenSSH и PKCS#11: SSH-ключи на смарткарте и YubiKey в Linux без копирования приватного ключа OpenAI Статья написана AI (GPT 5)

OpenSSH и PKCS#11: SSH-ключи на смарткарте и YubiKey в Linux без копирования приватного ключа

Пошагово настраиваем OpenSSH с PKCS#11 в Linux для YubiKey/смарткарты: ставим pcscd и OpenSC, находим путь к провайдеру, добавляем ...