Всем доброго дня, ночи! Этот пост будет полезен тем, кто использует шифрование данных LUKS и хочет производить decryptдешифровку дисков под Linux (Debian, Ubuntu) на стадии расшифровки root раздела. И такой информации в интернете я найти не смог.
Совсем недавно с увеличением количества дисков в полках, столкнулся с проблемой расшифровки дисков с использованием более чем известного метода через /etc/crypttab. Лично я выделяю несколько проблем использования этого метода, а именно то, что файл читается только после загрузки (mount) root-раздела, что негативно сказывается на импорте ZFS, в частности если они были собраны из разделов на *_crypt устройстве, или же mdadm рейды, собранные так же из разделов. Мы же все знаем, что можно использовать parted на LUKS контейнерах? И также проблема раннего старта других служб, когда массивов еще нет, а использовать уже что-то надо (я работаю с кластеризованным Proxmox VE 5.x и ZFS over iSCSI).
И второй вопрос, который я рассмотрю, это чем производить расшифровку (это ключевой момент статьи). И об этом мы поговорим ниже, заходите под кат!
Чаще всего на просторах интернета используют ключевой файл (само-собой добавленный перед этим в слот командой — cryptsetup luksAddKey), либо в редких исключениях (в русско-язычном интернете очень скудная информация) — скрипт decrypt_derived, лежащий в /lib/cryptsetup/script/ (конечно, есть еще способы, но я использовал именно эти два, что и легло в основу статьи). Так же я стремился к полному автономному включению после перезагрузок, без каких либо дополнительных команд в консоли, чтобы у меня всё «взлетало» сразу. Поэтому, зачем ждать? —
Приступаем!
Предполагаем систему, например Debian, установленную на crypto-раздел sda3_crypt и десяток дисков, готовых к шифрованию и созданию чего душе угодно. Мы имеем ключевую фразу (passphrase) для разблокировки sda3_crypt и именно с этого раздела мы будем на запущенной (расшифрованной) системе снимать «хэш» от пароля и добавлять на остальные диски. Всё элементарно, в консоли выполняем:
где X — это наши диски, разделы и т.д.
После шифрования дисков «хешем» от нашей ключевой-фразы, необходимо узнать UUID, либо ID — смотря кто и к чему привык. Берём данные из /dev/disk/by-uuid и by-id соответственно.
Следующий этап подготовка файлов и мини-скриптов для работы необходимых нам функций, приступаем:
далее
далее
еще немного
и последнее, перед update-initramfs, нужно отредактировать файл /etc/initramfs-tools/scripts/local-top/cryptroot, начиная со строки ~360, кусок кода ниже
и приводим к такому виду
Обратите внимание, что здесь можно использовать либо 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 соберутся без проблем! И всё это до загрузки основных служб и сервисов, которым нужны эти диски/массивы.
update1: Как заметил AEP, данный способ работает только для LUKS1.
Совсем недавно с увеличением количества дисков в полках, столкнулся с проблемой расшифровки дисков с использованием более чем известного метода через /etc/crypttab. Лично я выделяю несколько проблем использования этого метода, а именно то, что файл читается только после загрузки (mount) root-раздела, что негативно сказывается на импорте ZFS, в частности если они были собраны из разделов на *_crypt устройстве, или же mdadm рейды, собранные так же из разделов. Мы же все знаем, что можно использовать parted на LUKS контейнерах? И также проблема раннего старта других служб, когда массивов еще нет, а использовать уже что-то надо (я работаю с кластеризованным Proxmox VE 5.x и ZFS over iSCSI).
Немного о ZFSoverISCSI
iSCSI работает у меня через LIO, и собственно когда стартует iscsi-таргет и не видит ZVOL устройств, он их просто-напросто удаляет из конфигурации, что не дает возможности загружаться гостевым системам. Отсюда либо восстановление бэкапа json файла, либо ручное добавление устройств с идентификаторами каждой VM, что просто ужас, когда таких машин десятки и в конфигурации каждой более 1 диска.
И второй вопрос, который я рассмотрю, это чем производить расшифровку (это ключевой момент статьи). И об этом мы поговорим ниже, заходите под кат!
Чаще всего на просторах интернета используют ключевой файл (само-собой добавленный перед этим в слот командой — cryptsetup luksAddKey), либо в редких исключениях (в русско-язычном интернете очень скудная информация) — скрипт decrypt_derived, лежащий в /lib/cryptsetup/script/ (конечно, есть еще способы, но я использовал именно эти два, что и легло в основу статьи). Так же я стремился к полному автономному включению после перезагрузок, без каких либо дополнительных команд в консоли, чтобы у меня всё «взлетало» сразу. Поэтому, зачем ждать? —
Приступаем!
Предполагаем систему, например Debian, установленную на crypto-раздел sda3_crypt и десяток дисков, готовых к шифрованию и созданию чего душе угодно. Мы имеем ключевую фразу (passphrase) для разблокировки sda3_crypt и именно с этого раздела мы будем на запущенной (расшифрованной) системе снимать «хэш» от пароля и добавлять на остальные диски. Всё элементарно, в консоли выполняем:
/lib/cryptsetup/scripts/decrypt_derived sda3_crypt | cryptsetup luksFormat /dev/sdX
где X — это наши диски, разделы и т.д.
После шифрования дисков «хешем» от нашей ключевой-фразы, необходимо узнать UUID, либо ID — смотря кто и к чему привык. Берём данные из /dev/disk/by-uuid и by-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 соберутся без проблем! И всё это до загрузки основных служб и сервисов, которым нужны эти диски/массивы.
update1: Как заметил AEP, данный способ работает только для LUKS1.