Хабрахабр

[Из песочницы] Расшифровка LUKS контейнера в момент загрузки системы

Всем доброго дня, ночи! Этот пост будет полезен тем, кто используется шифрование данных LUKS и хочет производить decryptдешифровку дисков под Linux (Debian, Ubuntu) на стадии расшифровки root раздела. И такой информации в интернете я найти не смог.

Лично я выделяю несколько проблем использования этого метода, а именно то, что файл читается только после загрузки (mount) root-раздела, что негативно сказывается на импорте ZFS, в частности если они были собраны из разделов на *_crypt устройстве, или же mdadm рейды, собранные так же из разделов. Совсем недавно с увеличением количества дисков в полках, столкнулся с проблемой расшифровки дисков с использованием более чем известного метода через /etc/crypttab. Мы же все знаем, что можно использовать parted на LUKS контейнерах? И также проблема раннего старта других служб, когда массивов еще нет, а использовать уже что-то надо (я работаю с кластеризованным Proxmox VE 5.x и ZFS over iSCSI).

Немного о ZFSoverISCSI

Отсюда либо восстановление бэкапа json файла, либо ручное добавление устройств с идентификаторами каждой VM, что просто ужас, когда таких машин десятки и в конфигурации каждой более 1 диска.
iSCSI работает у меня через LIO, и собственно когда стартует iscsi-таргет и не видит ZVOL устройств, он их просто-напросто удаляет из конфигурации, что не дает возможности загружаться гостевым системам.

И второй вопрос, который я рассмотрю, это чем производить расшифровку (это ключевой момент статьи). И об этом мы поговорим ниже, заходите под кат!
Чаще всего на просторах интернета используют ключевой файл (само-собой добавленный перед этим в слот командой — cryptsetup luksAddKey), либо в редких исключениях (в русско-язычном интернете очень скудная информация) — скрипт decrypt_derived, лежащий в /lib/cryptsetup/script/ (конечно, есть еще способы, но я использовал именно эти два, что и легло в основу статьи). Так же я стремился к полному автономному включению после перезагрузок, без каких либо дополнительных команд в консоли, чтобы у меня всё «взлетало» сразу. Поэтому, зачем ждать? —

Приступаем!

Мы имеем ключевую фразу (passphrase) для разблокировки sda3_crypt и именно с этого раздела мы будем на запущенной (расшифрованной) системе снимать «хэш» от пароля и добавлять на остальные диски. Предполагаем систему, например Debian, установленную на crypto-раздел sda3_crypt и десяток дисков, готовых к шифрованию и созданию чего душе угодно. Всё элементарно, в консоли выполняем:

/lib/cryptsetup/scripts/decrypt_derived sda3_crypt | cryptsetup luksFormat /dev/sdX

где X — это наши диски, разделы и т.д.

Берём данные из /dev/disk/by-uuid и by-id соответственно. После шифрования дисков «хешем» от нашей ключевой-фразы, необходимо узнать UUID, либо ID — смотря кто и к чему привык.

Следующий этап подготовка файлов и мини-скриптов для работы необходимых нам функций, приступаем:

cp -p /usr/share/initramfs-tools/hooks/cryptroot /etc/initramfs-tools/hooks/
cp -p /usr/share/initramfs-tools/scripts/local-top/cryptroot /etc/initramfs-tools/scripts/local-top/

далее

touch /etc/initramfs-tools/hooks/decrypt && chmod +x /etc/initramfs-tools/hooks/decrypt

Содержимое ../decrypt

#!/bin/sh cp -p /lib/cryptsetup/scripts/decrypt_derived "$DESTDIR/bin/decrypt_derived"

далее

touch /etc/initramfs-tools/hooks/partcopy && chmod +x /etc/initramfs-tools/hooks/partcopy

Содержимое ../partcopy

#!/bin/sh cp -p /sbin/partprobe "$DESTDIR/bin/partprobe"
cp -p /lib/x86_64-linux-gnu/libparted.so.2 "$DESTDIR/lib/x86_64-linux-gnu/libparted.so.2"
cp -p /lib/x86_64-linux-gnu/libreadline.so.7 "$DESTDIR/lib/x86_64-linux-gnu/libreadline.so.7"

еще немного

touch /etc/initramfs-tools/scripts/local-bottom/partprobe && chmod +x /etc/initramfs-tools/scripts/local-bottom/partprobe

Содержимое ../partprobe

#!/bin/sh $DESTDIR/bin/partprobe

и последнее, перед update-initramfs, нужно отредактировать файл /etc/initramfs-tools/scripts/local-top/cryptroot, начиная со строки ~360, кусок кода ниже

Оригинал

# decrease $count by 1, apparently last try was successful. count=$(( $count - 1 )) message "cryptsetup ($crypttarget): set up successfully" break

и приводим к такому виду

Отредактированный

# decrease $count by 1, apparently last try was successful. count=$(( $count - 1 )) /bin/decrypt_derived $crypttarget | cryptsetup luksOpen /dev/disk/by-uuid/ *CRYPT_MAP* /bin/decrypt_derived $crypttarget | cryptsetup luksOpen /dev/disk/by-id/ *CRYPT_MAP* message "cryptsetup ($crypttarget): set up successfully" break

Обратите внимание, что здесь можно использовать либо UUID, либо ID. Главное чтобы нужные драйвера на устройства HDD/SSD были добавлены в /etc/initramfs-tools/modules. Узнать используемый драйвер можно командой udevadm info -a -n /dev/sdX | egrep 'looking|DRIVER'.

Перезагружаемся, вводим ключевую-фразу и немного ждём, в зависимости от количества дисков. Теперь, когда мы закончили и все файлы на месте, запускаем update-initramfs -u -k all -v, в логировании не должно быть ошибок выполнения наших скриптов. И всё это до загрузки основных служб и сервисов, которым нужны эти диски/массивы. Далее система запустится и на конечной стадии запуска, а именно после «маунтинга» root-раздела, будет выполнена команда partprobe — она найдет и подцепит все созданные разделы на LUKS устройствах и любые массивы, будь то ZFS или mdadm соберутся без проблем!

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть