Šifrování oddílů v GNU/Linuxu pomocí LUKS

Verze pro tiskPDF verze

Ještě před nedávnem existovalo vedle sebe více implementací šifrování diskových oddílů v GNU/Linuxu (loop-aes, dm-crypt), přičemž jednotlivé cesty bojovaly různě s problémy jako bezpečnost při šifrování tak ohromných objemů dat či vzájemná kompatibilita. Oba tyto problémy by měl vyřešit LUKS (Linux Unified Key Setup) o kterém je tento článek.

Oba problémy (stejně jako některé další) by měl vyřešit LUKS (Linux Unified Key Setup), který představuje standard pro šifrování oddílů v GNU/Linuxu a navíc implementuje špičkové metody pro bezpečné šifrování velkých objemů dat. Dosti však teorie (zejména vzhledem k tomu, že nejsem expert na šifrovací algoritmy) a pusťme se do návodu.

Budeme potřebovat balíček cryptsetup-luks, který v některých distribucích (Debian, Arch Linux) již dávno nahradil původní balíček cryptsetup. Ještě před tím, než předvedu, jak vytvořit zašifrovaný oddíl, pár slov k tomu, jak LUKS pracuje.

LUKS oddíl začíná hlavičkou, která obsahuje základní informace včetně použité šifry. Následují sloty pro celkem osm uživatelských klíčů a nakonec zašifrovaná data. Data jsou šifrována hlavním klíčem (master key), jehož kontrolní součet se nachází v hlavičce oddílu. Každý z použitých slotů obsahuje příslušným uživatelským heslem zašifrovaný master key. K dešifrování oddílu tedy postačí kterýkoliv klíč. Podrobnější informace o implementaci naleznete v příslušném sheetu nebo v mé seminární práci na téma diskové šifrování. Teď už nás čeká práce s LUKSem.

Oficiální dokumentace doporučuje provést před vytvořením šifrovaného oddílu jednak kontrolu špatných sektorů a přepsání celého oddílu náhodnými daty. K tomu je doporučován příkaz:

badblocks -c 10240 -s -w -t random -v /dev/hda4

Kontrolu špatných sektorů lze samozřejmě vynechat a oddíl zaplnit náhodnými daty pomocí dd. Zaplnění náhodnými daty generovanými pomocí /dev/urandom důrazně doporučuji, protože se jedná o jeden z nejkvalitnějších generátorů pseudonáhodných čísel. Příkaz pro zaplnění blokového zařízení hda4 náhodnými daty by vypadal takto :

dd if=/dev/urandom of=/dev/hda4

Očekávejte, že proces potrvá velmi dlouho, tzn. i několik hodin či v extrémních případech déle než den. Výsledkem však bude podstatně vyšší bezpečnost celého řešení. Já mohu snad jen doporučit použití nějakého pipemeteru, abyste měli přehled o tom, jak operace probíhá:

dd if=/dev/urandom | pipemeter | dd of=/dev/hda4

V mém případě trvalo zaplnění 200GB dat asi 20 hodin (Athlon 64 3200+, 2,0GHz). Když je příprava dokončena, můžeme vytvořit LUKS oddíl:

cryptsetup luksFormat /dev/hda4

Občas ale bývá lepší specifikovat jednotlivé parametry pro šifru, hash a velikost klíče ručně. S jádrem 2.6.20 a novějším máme podporu šifrovacího módu LRW, který je bezpečnější než CBC-ESSIV. Informace o šifrovacích módech a jejich bezpečnosti na diskové šifrování probírám ve své seminární práci. LRW tedy použijeme takto:

cryptsetup -c aes-lrw-benbi -h sha256 -s 384 -y luksFormat /dev/sdc2

Na starších jádrech použijeme alespoň CBC-ESSIV:

cryptsetup -c aes-cbc-essiv:sha256 -h sha256 -s 256 -y luksFormat /dev/sdc2

Jak vidíme, parametr -c nám umožňuje specifikovat šifru (aes, serpent, twofish, cast6, apod.), šifrovací mód (ecb, cbc, lrw) a způsob generování inicializačního vektoru (plain, essiv:hash, benbi), v tomto pořadí. Z hlediska bezpečnosti je nejhorším řešením pro diskové šifrování mód ecb a plain inicializační vektor (to už je snad lepší nešifrovat, abyste nepropadli falešnému pocitu bezpečí) a nejlepším lrw a benbi (pozor, benbi je určen pro "narrow block" módy, jako LRW, XEX, apod., není určen pro CBC). Obecně lze doporučit použití LRW s tím, že pokud jej nemůžete z nějakého důvodu použít, použijte alespoň CBC-ESSIV.

Následně vytvoříme příslušné zařízení device mapperu:

cryptsetup luksOpen /dev/hda4 zasifrovano

Druhý parametr určuje název vytvořeného zařízení v /dev/mapper, lze použít cokoliv, co uznáte za vhodné. Nyní na zařízení vytvoříme souborový systém:

mkfs.ext3 /dev/mapper/zasifrovano

Nyní již existující souborový systém připojíme:

mount /dev/mapper/zasifrovano /mnt/zasifrovano

A práce je skoro hotová. Pokud budeme chtít takto zašifrovat třeba /home nebo něco klíčového (třeba kořenový oddíl), buď nám v tom distribuce vyjde vstříc již předem upravenými startovacími skripty, nebo budeme muset příslušné změny provést sami.

Odpojení oddílu včetně odstranění zařízení device mapperu lze provést takto:

umount /dev/mapper/zasifrovano
cryptsetup luksClose zasifrovano

» Správa klíčů

Jak už jsem naznačil, je možné použít až osm klíčů, přičemž každý je schopen dešifrovat oddíl. Jak ale přidat či ubrat klíč? Snadno. Zkusíme přidat nový klíč:

cryptsetup luksAddKey /dev/hda4

Pokud zpozorníte u výpisů cryptsetupu, všimnete si zprávy "key slot 0 unlocked.". Tato zpráva vám říká, kterým klíčem jste si odemkli. V tomto případě prvním (resp. nultým) klíčem. Pokud jste přidali druhý klíč, následujícím příkazem ho odstraníte:

cryptsetup luksDelKey /dev/hda4 1

» Záloha hlavičky

Pokud nemáte RAID-1, hlavička je "single point of failure". Tu však lze snadno zálohovat pomocí dd. Nejprve si ale necháme vypsat informace z LUKS hlavičky oddílu:

cryptsetup luksDump /dev/hda4

Ve výpisu si všimněte čísla označeného jako "Payload offset:". Toto číslo pak zadejte jako parametr count= pro dd:

dd if=/dev/hda4 of=luks_header.hda4 count=cislo

» Použití USB flash disku jako tokenu

Není nic jednoduššího. Připojte flashku a vygenerujte příslušný klíč:

dd if=/dev/random of=/mnt/flashdisk/key.hda4 bs=1 count=256

Následně přidejte klíč do "klíčenky":

cryptsetup luksAddKey /dev/hda4 /mnt/flashdisk/key.hda4

A vytvořte zařízení device mapperu:

cryptsetup -d /mnt/flashdisk/key.hda4 luksOpen /dev/hda4 zasifrovano

» Zajištění swapu pro vyšší bezpečnost

Pokud budete používat zašifrované oddíly, bývá dobrým nápadem zajistit swapovací oddíl tak, aby z něj v případě, že si do něj linuxové jádro dočasně uloží obsah paměti i s vaším původním heslem, nebylo možné později tuto informaci vytáhnout. Úpravu konfigurace pro zajištění swapu při každém bootu nechám na vás, neb u každé distribuce bude mírně odlišná.

Swap zajistíme tak, že necháme jeho obsah šifrovat náhodným heslem při každém startu systému:

cryptsetup -d /dev/urandom create cswap /dev/hda2
mkswap /dev/mapper/cswap
swapon /dev/mapper/cswap

» Přenositelnost

Přenositelnost kontejnerů šifrovaných pomocí LUKS zajišťuje na platformě Windows projekt FreeOTFE. Pro jiné platformy (např. *BSD systémy) zatím o žádném řešení zpřístupnění LUKS kontejnerů nevím.

Zdroje: