Dekódování LUKS kontejneru během startu systému

Všem přeji dobrý den či noc! Tento příspěvek bude užitečný těm, kteří používají šifrování dat LUKS a chtějí provádět dešifrování disků pod Linuxem (Debian, Ubuntu) na stádiu dešifrování root oddílu. A takové informace jsem na internetu nemohl najít.

Nedávno jsem se při zvyšování počtu disků v policích setkal s problémem dešifrování disků pomocí dobře známé metody přes /etc/crypttab. Osobně vyzdvihuji několik problémů s používáním této metody, a to, že soubor se čte pouze po načtení (mount) root-oddílu, což negativně ovlivňuje import ZFS, zejména pokud byly sestaveny z oddílů na *_crypt zařízení, nebo mdadm RAIDy, které byly také sestaveny z oddílů. Všichni víme, že lze použít parted na LUKS kontejnerech? A také problém brzkého spouštění dalších služeb, když pole ještě neexistují, a použít už je něco potřeba (pracuji s clusterovaným Proxmox VE 5.x a ZFS přes iSCSI).

Trochu o ZFS over iSCSIiSCSI u mě funguje přes LIO, a když se spouští iSCSI cíl a nevidí ZVOL zařízení, prostě je odstraní z konfigurace, což brání startování hostitelských systémů. Odtud buď obnova zálohy json souboru, nebo ruční přidání zařízení s identifikátory každé VM, což je skutečně hrozné, když těchto strojů je deset a v konfiguraci každého je více než 1 disk.

A druhá otázka, kterou budu zvažovat, je, čím provádět dešifrování (to je klíčový bod článku). O tom budeme hovořit níže, pojďte dál!

Nejčastěji se na internetu používá klíčový soubor (samozřejmě dříve přidaný do slotu příkazem — cryptsetup luksAddKey), nebo v raritních výjimkách (v rusky mluvícím internetu je velmi skromné množství informací) — skript decrypt_derived, který leží v /lib/cryptsetup/script/ (samozřejmě existují i další způsoby, ale právě tyto dva jsem použil, což se stalo základem článku). Také jsem usiloval o plnou autonomní aktivaci po restartu, bez jakýchkoli dalších příkazů v konzoli, abych měl vše „vzhůru“ okamžitě. Tak proč čekat? —

Začínáme!

Předpokládáme systém, například Debian, nainstalovaný na crypto-partici sda3_crypt a desítku disků připravených k šifrování a vytvoření čehokoli, co si přejeme. Máme klíčovou frázi (passphrase) pro odemknutí sda3_crypt a právě z této partice budeme na spuštěném (dešifrovaném) systému generovat „hash“ z hesla a přidávat ho na ostatní disky. Všechno je elementární, v konzoli provedeme:

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

kde X jsou naše disky, partition a tak dále.

Po šifrování disků „heshem“ naší klíčové fráze je nutné zjistit UUID nebo ID — podle toho, co kdo preferuje. Bereme data z /dev/disk/by-uuid a by-id odpovídajícími.

Dalším krokem je příprava souborů a mini-skriptů pro potřebné funkce, začínáme:

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/

dále

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

Obsah .. /decrypt

#!/bin/sh

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

dále

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

Obsah .. /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"

ještě trochu

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

Obsah .. /partprobe

#!/bin/sh

$DESTDIR/bin/partprobe

a poslední věc, před update-initramfs, je potřeba upravit soubor /etc/initramfs-tools/scripts/local-top/cryptroot, začínající od řádku ~360, kousek kódu níže

Originál


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

a přivést k tomuto formátu

Upravený


                # 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

Všimněte si, že zde lze použít buď UUID, nebo ID. Hlavně, aby potřebné ovladače na zařízeních HDD/SSD byly přidány do /etc/initramfs-tools/modules. Zjistit používaný ovladač lze příkazem udevadm info -a -n /dev/sdX | egrep 'looking|DRIVER'.

Teď, když jsme hotovi a všechny soubory jsou na svém místě, spouštíme update-initramfs -u -k all -v, v logování by neměly být chyby vykonávání našich skriptů. Restartujeme, zadáme klíčovou frázi a trochu počkáme, v závislosti na počtu disků. Poté se systém spustí a ve finální fázi spuštění, konkrétně po „mountování“ root-partice, se provede příkaz partprobe — ten najde a připojí všechny vytvořené partition na LUKS zařízeních a jakékoliv pole, ať už ZFS nebo mdadm, se sestaví bez problémů! A to vše před načtením hlavních služeb a servisů, které potřebují tyto disky/pole.

update1: Jak poznamenal AEP, tento způsob funguje pouze pro LUKS1.

Zdroj: habr.com

Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster