Расшыфроўка LUKS кантэйнера ў момант загрузкі сістэмы

Усім добрага дня, ночы! Гэты пост будзе карысны тым, хто выкарыстоўвае шыфраванне дадзеных LUKS і жадае вырабляць decryptдэшыфроўку дыскаў пад Linux (Debian, Ubuntu) на стадыі расшыфроўкі root часткі. І такой інфармацыі ў інтэрнэце я знайсці не здолеў.

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

Трохі аб ZFSoverISCSIiSCSI працуе ў мяне праз 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 збяруцца без праблем! І ўсё гэта да загрузкі асноўных службаў і сэрвісаў, якім патрэбны гэтыя дыскі/масівы.

абнаўленне1: Як заўважыў AEP, дадзены спосаб працуе толькі для LUKS1.

Крыніца: habr.com

Дадаць каментар