mkinitcpio v42 сломал TPM-разблокировку LUKS
mkinitcpio v42 сломал TPM-разблокировку LUKS потому, что изменил состав initramfs: образы пересобрались, значения PCR-регистров TPM перестали совпадать с теми, на которые запечатан ключ, и автоматическая разблокировка отвалилась. Лечится за пару минут: стереть старый TPM-слот и записать ключ заново через systemd-cryptenroll. Пароль остаётся рабочим, данные в безопасности.
Что случилось с mkinitcpio v42
В 2026 году mkinitcpio добрался до версии 42: обновление оказалось не из безобидных. Пакет изменил hook systemd и состав initramfs: в образ попали другие юниты и бинарники, изменился порядок сборки. Само по себе это нормально.
При обновлении системы pacman-хук автоматически пересобирает initramfs. Используешь unified kernel image (UKI), пересобирается и он. Образ изменился, а TPM об этом «узнал»: содержимое initramfs замеряется в PCR-регистры, значения изменились, и запечатанный ключ больше не подходит.
Симптомы одинаковые: после обновления система при загрузке просит пароль LUKS, хотя раньше открывала диск сама. Кто-то падает в emergency shell. В логах: «Unsealing failed» или «Failed to enroll».
Почему systemd-cryptenroll перестал работать
Когда ты делал systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+7, systemd сгенерировал ключ, запечатал его в TPM и привязал к значениям PCR на тот момент. При каждой загрузке systemd-cryptsetup-generator просит TPM раскрыть ключ, а TPM сверяет текущие PCR с теми, что были при запечатывании. Не совпали, ключ не выдаёт.
Какие PCR меняются, зависит от загрузчика и набора при enroll:
- PCR 7: состояние Secure Boot;
- PCR 9: командная строка ядра (GRUB);
- PCR 11: командная строка ядра (systemd-boot, UKI);
- PCR 10 и 12: компоненты загрузчика и initramfs (раскладка зависит от загрузчика и версии systemd).
Обновление initramfs меняет PCR 10 или 12, загрузчика или cmdline: PCR 9 или 11, Secure Boot: PCR 7. Поэтому после mkinitcpio v42 у кого-то «отвалился» один регистр, у кого-то сразу несколько. Выбор загрузчика влияет на расклад: GRUB против systemd-boot.
Это не баг. TPM честно говорит: «система изменилась, ключ не отдам». Так и задумано, иначе злоумышленник подменил бы initramfs и получил ключ. Не настраивал? Вот как с нуля.
Как проверить, что PCR изменились
Сначала подтверди диагноз, посмотри логи:
journalctl -b -p err
Ищи строки про TPM: «Failed to enroll», «Unsealing failed», «Operation cancelled». Нашёл: дело в PCR. Про чтение журнала: в статье про journalctl -b.
Теперь посмотри текущие значения регистров. Пакет tpm2-tools:
sudo pacman -S tpm2-tools
tpm2_pcrread
Или через systemd:
systemd-analyze pcrs
Вывод покажет регистры с хешами (по умолчанию 0–15). Сравни с теми, что были при enroll, если записывал. Не записывал? Ошибок в journalctl уже достаточно.
Проверь Secure Boot:
ls /sys/firmware/efi/efivars
Пусто или нет директории: Secure Boot выключен, PCR 7 изменился. Подробности в статье про sbctl.
Как починить TPM-разблокировку
Решение одно: переучить TPM. Стереть старый слот и записать ключ заново. Пароль LUKS понадобится, держи под рукой.
Шаг 1. Бэкап заголовков LUKS
Перед манипуляциями со слотами сделай бэкап заголовков. Потеря заголовка = потеря данных. Как в статье про смену паролей LUKS2.
Шаг 2. Стереть старый TPM-слот
sudo systemd-cryptenroll --wipe-slot=tpm2 /dev/nvme0n1p2
--wipe-slot=tpm2 удаляет слот по типу токена, можно и по номеру: --wipe-slot=1. Замени /dev/nvme0n1p2 на свой LUKS-раздел.
Шаг 3. Записать ключ заново
sudo systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+7 /dev/nvme0n1p2
Команда запросит пароль LUKS, сгенерирует новый ключ и запечатает его в TPM с привязкой к текущим PCR. Набор 0+7 минимальный и самый устойчивый: прошивка и Secure Boot. Хочешь привязаться ещё и к cmdline ядра, добавь +11 (для UKI) или +9 (для GRUB). Но чем больше PCR, тем чаще ломается разблокировка. Документация Systemd-cryptenroll на ArchWiki.
Шаг 4. Проверить после перезагрузки
Перезагрузись. Диск должен открыться сам. Если снова просит пароль, смотри journalctl -b -p err и сверяй PCR через systemd-analyze pcrs. Привязался к регистру, который меняется при каждой пересборке initramfs? Вернись к 0+7.
Как защититься от повторения
Исключить такие сюрпризы нельзя: TPM так устроен. Но частоту снизить можно.
Не привязывайся к PCR, которые меняются при каждом обновлении. Регистры initramfs (10, 12) и cmdline (9, 11) самые «капризные». Набор 0+7 переживает почти всё, кроме смены прошивки и Secure Boot.
Держи пароль в отдельном слоте. TPM-ключ это удобство, пароль это страховка. Без пароля одно неудачное обновление прошивки = потеря данных.
Читай новости Arch перед обновлением. Крупные релизы mkinitcpio, systemd и ядра обсуждают заранее. Увидел предупреждение, знаешь, чего ждать.
Не паникуй при первом же пароле. Это не поломка, а штатная защита. Диагностика по журналу отдельная методика.
Частые вопросы
Это баг mkinitcpio v42?
Нет. mkinitcpio изменил состав initramfs, это его работа. TPM увидел изменения и отказался выдавать ключ, тоже его работа. Сломалось только «удобство», данные целы.
Данные потеряны?
Нет. Пароль LUKS продолжает работать всегда. TPM-ключ это дополнительный способ открыть диск, а не замена пароля.
Нужно ли пересобирать initramfs после enroll?
Нет. systemd-cryptenroll не трогает initramfs. Пересборка mkinitcpio -P нужна только при смене хуков или ядра.
Какие PCR выбрать, чтобы реже ломалось?
Минимум 0+7: прошивка и Secure Boot. Всё, что сверху (cmdline, initramfs), усиливает защиту, но повышает вероятность «отвала» при обновлениях.
Заключение
mkinitcpio v42: свежий пример того, как обновление initramfs ломает TPM-разблокировку LUKS. Механика простая: пересобрался образ, изменились PCR, запечатанный ключ перестал подходить. Лечится перерегистрацией слота: --wipe-slot=tpm2, затем enroll заново. Пароль всегда остаётся запасным вариантом. Держи его, не привязывайся к капризным PCR, и такие обновления станут лишь поводом вспомнить, как устроен TPM.
Полезные ресурсы
- Mkinitcpio (ArchWiki): хуки, конфигурация initramfs, UKI
Не получилось? Поможем настроить
Задай вопрос в чате — отвечаем быстро, по делу и без воды.

Комментарии