Jak používat dm-verity v Linuxu: Kompletní a praktický průvodce

  • dm-verity ověřuje bloky za běhu pomocí podepsaného kořenového hašovacího stromu, čímž ukotřuje bootovací řetězec důvěryhodnosti.
  • Jeho moderní nasazení kombinuje veritysetup, systemd-veritysetup, Secure Boot a UKI k ochraně jádra, initramfs a cmdline.
  • Android používá system-as-root a AVB k předávání parametrů dm-verity; FEC a reakční politiky zvyšují robustnost.
  • Neměnný kořenový adresář vyžaduje oddělení zapisovatelných dat (/var, /home) a plánování aktualizací pomocí obrazů nebo A/B schémat.

dm-verity v Linuxu

Pokud máte obavy o integritu svého systému, dm-verity je jednou z klíčových součástí ekosystému Linuxu. pro bezpečné spouštění a detekci manipulace s úložištěm. Vznikl jako součást mapovače zařízení jádra a nyní je základem pro ověřené spouštění v Androidu, OpenWrt a distribucích, které hledají vyšší zabezpečení.

Daleko od abstraktního pojmu, dm-verity se konfiguruje a používá se skutečnými nástroji, jako jsou veritysetup a systemd-veritysetup.Ověřuje bloky za běhu pomocí hašovacích stromů a dokáže reagovat na poškození pomocí politik od protokolování události až po restartování nebo pád systému. Pojďme se na to podívat blíže, aniž bychom nechali nějaké volné konce.

Co je dm-verity a proč by vás to mohlo zajímat

Ověření integrity pomocí dm-verity

dm-verity je cíl mapovače zařízení v jádře, který ověřuje integritu blokového zařízení při čtení datFunguje tak, že vypočítává a ověřuje hash každého bloku (obvykle 4K) oproti předem vypočítanému hash stromu, typicky pomocí SHA-256.

Tato konstrukce umožňuje Soubory nelze tiše upravovat mezi restarty nebo během provádění.Je to klíčové pro rozšíření bootovacího řetězce důvěryhodnosti operačního systému, omezení perzistence malwaru, posílení bezpečnostních zásad a zajištění šifrovacích a MAC mechanismů během bootování.

V systému Android (od verze 4.4) a obecně v Linuxu, Důvěra je zakotvena v kořenovém hashu stromu., který je podepsán a ověřen veřejným klíčem umístěným na chráněném místě (např. na bootovacím oddílu nebo v UKI podepsaném Secure Boot). Prolomení jakéhokoli bloku by vyžadovalo prolomení podkladového kryptografického hashe.

Ověřování se provádí blokově a na vyžádání: Přidaná latence je minimální ve srovnání s náklady na I/O.Pokud kontrola selže, jádro vrátí chybu I/O a souborový systém se jeví jako poškozený, což se očekává, když jsou data nespolehlivá. Aplikace se mohou na základě své odolnosti vůči chybám rozhodnout, zda budou pokračovat či nikoli.

Jak interně funguje ověřovací strom

Verifikační strom je sestaven ve vrstvách. Vrstva 0 obsahuje nezpracovaná data ze zařízení, rozdělená do bloků o velikosti 4K.Pro každý blok se vypočítá hash SHA-256 (salted). Tyto hashe se poté zřetězí a vytvoří vrstvu 1. Vrstva 1 se poté seskupí do bloků a znovu se hashuje, aby se vytvořila vrstva 2, a tak dále, dokud se vše nevejde do jednoho bloku: tento blok po hashování vytvoří kořenový hash.

Pokud některá vrstva přesně nedokončí blok, Doplňuje se nulami, dokud nedosáhne 4K. aby se předešlo nejasnostem. Celková velikost stromu závisí na velikosti kontrolovaného oddílu; v praxi je u typických systémových oddílů obvykle menší než 30 MB.

Obecný postup je: vybrat náhodnou sůl, hašovat na 4K, vypočítat SHA-256 se solí pro každý blok, zřetězuje se a vytváří úrovně, doplňuje hranici bloku nulami a opakuje se s předchozí úrovní, dokud nezůstane jediný kořenový hash. Tento kořenový hash spolu s použitou solí (salt) slouží k uložení do tabulky dm-verity a signatury.

Verze formátu disku a algoritmus

Formát hašovacích bloků na disku má verzi. Verze 0 byla původní verzí používanou v Chromium OS.Sůl se přidává na konci hašovacího procesu, digesty se ukládají průběžně a zbytek bloku se doplňuje nulami.

La Pro nová zařízení se doporučuje verze 1.Sůl je připojena k haši a každý digest je doplněn nulami až do mocnin dvou, což zlepšuje zarovnání a robustnost. Tabulka dm-verity také specifikuje algoritmus (např. sha1 nebo sha256), ačkoli pro aktuální zabezpečení se používá sha256.

Tabulka dm-verity a základní parametry

Cílová tabulka dm-verity popisuje kde se nacházejí data, kde se nachází hašovací strom a jak to ověřitTypická pole tabulky:

  • dev: zařízení s ověřovanými daty (typ cesty /dev/sdXN nebo vyšší:nižší).
  • hash_dev: zařízení s hašovacím stromem (může být stejné; pokud ano, hash_start musí být mimo zaškrtnutý rozsah).
  • velikost_bloku_dat: velikost datového bloku v bajtech (např. 4096).
  • velikost_hash_bloku: velikost hash bloku v bajtech.
  • počet_bloků_dat: počet ověřitelných datových bloků.
  • hash_start_block: posun (v blocích hash_block_size) vůči kořenovému bloku stromu.
  • algoritmus: hašovací algoritmus (např. sha256).
  • strávithexadecimální kódování hashe kořenového bloku (včetně soli podle verze formátu); této hodnotě se důvěřuje.
  • sůlhexadecimální sůl.

Kromě toho existují volitelné parametry velmi užitečné pro úpravu chování:

  • ignorovat_korupciZaznamenává poškozené bloky, ale umožňuje pokračování čtení.
  • restart_on_corruptionrestart při detekci poškození (není kompatibilní s ignore_corruption a vyžaduje podporu uživatelského prostoru, aby se zabránilo smyčkám).
  • panika_o_korupci: : způsobuje paniku při detekci poškození (není kompatibilní s předchozími verzemi).
  • restart_při_chybě y panika_při_chyběStejné reakce, ale pro chyby I/O.
  • ignore_zero_blocks: nekontroluje bloky, které jsou očekávány jako nuly, a vrací nuly.
  • use_fec_from_device + fec_roots + fec_blocks + fec_startPovolí Reed-Solomonově metodě (FEC) obnovu dat v případě selhání ověření; oblasti dat, hash a FEC se nesmí překrývat a velikosti bloků se musí shodovat.
  • zkontrolovat_nejvíce_jednouKontroluje každý blok dat pouze při prvním čtení (snižuje režijní náklady na úkor zabezpečení při útokech v reálném čase).
  • kořenový_hash_podpisový_klíč_popisOdkaz na klíč v svazku klíčů pro ověření podpisu PKCS7 kořenového hashe při vytváření mapování (vyžaduje odpovídající konfiguraci jádra a důvěryhodné svazky klíčů).
  • try_verify_in_taskletPokud jsou hashe uloženy v mezipaměti a velikost I/O to umožňuje, kontroluje se spodní polovina pro snížení latence; upraveno pomocí /sys/module/dm_verity/parameters/use_bh_bytes pro každou třídu I/O.

Podpis, metadata a ukotvení důvěryhodnosti

Aby byla dm-verity spolehlivá, Kořenový hash musí být důvěryhodný a obvykle podepsaný.V klasickém Androidu je v bootovacím oddílu obsažen veřejný klíč, který je externě ověřen výrobcem; ověřuje kořenový hash podpis a zajišťuje, že systémový oddíl nebyl změněn.

Metadata Verity přidávají strukturu a kontrolu verzí. Blok metadat obsahuje magické číslo 0xb001b001 (bajty b0 01 b0 01), verze (aktuálně 0), podpis tabulky v PKCS1.5 (obvykle 256 bajtů pro RSA-2048), délka tabulky, samotná tabulka a doplnění nulami až do 32K.

V implementacích pro Android se ověřování spoléhá na fs_mgr a fstabPřidání zaškrtávací značky k odpovídající položce a umístění klíče do /boot/verity_key. Pokud magické číslo není tam, kde by mělo být, ověřování se zastaví, aby se zabránilo kontrole nesprávné položky.

Spuštění operace ověřeno

Ochrana je obsažena v jádře: Pokud je systém napaden před spuštěním jádra, útočník si udrží kontrolu.Proto výrobci obvykle striktně ověřují každou fázi: klíč zaznamenaný do zařízení ověří první bootloader, který ověří další, bootloader aplikace, a nakonec jádro.

S ověřeným jádrem, dm-verity je povoleno při montáži ověřeného blokového zařízení.Místo hašování celého zařízení (což by bylo pomalé a plýtvalo by energií), je ověřováno blok po bloku při přístupu. Selhání způsobí chybu I/O a služby a aplikace reagují podle své tolerance: buď pokračují bez těchto dat, nebo se zcela zhroutí.

Dopředná korekce chyb (FEC)

Od Androidu 7.0, FEC (Reed-Solomon) je začleněn do technik prokládání aby se zmenšil prostor a zvýšila se schopnost obnovit poškozené bloky. Toto funguje ve spojení s dm-verity: pokud kontrola selže, subsystém se může pokusit o opravu, než ji prohlásí za neopravitelnou.

Výkon a optimalizace

Pro snížení dopadu: Povolit akceleraci SHA-2 pomocí NEON na ARMv7 a rozšíření SHA-2 na ARMv8 z jádra. Upravte parametry read-ahead a prefetch_cluster pro váš hardware; ověřování jednotlivých bloků obvykle jen málo zvyšuje náklady na I/O, ale tato nastavení mají vliv.

Začínáme s Linuxem (systemd, veritysetup) a Androidem

Konfigurace dm-verity v systémech Linux a Android

Na moderním Linuxu se systemd, dm-verity umožňuje ověřený root přístup pouze pro čtení. pomocí veritysetup (součást cryptsetup), systemd-veritysetup.generator a systemd-veritysetup@.service. Doporučuje se zahrnout Secure Boot a podepsaný UKI (unified kernel image), i když to není striktně vyžadováno.

Příprava a doporučené rozdělení

Součást funkčního a upraveného systému. Rezervovat svazek pro hašovací strom (Obvykle stačí 8–10 % velikosti kořenového adresáře) a pokud potřebujete zapisovat, zvažte oddělení /home a /var. Typické schéma zahrnuje: ESP (pro bootloader), XBOOTLDR (pro UKI), root (se šifrováním nebo bez něj), oddíl VERITY a volitelně /home a /var.

Jako kořen, EROFS je velmi zajímavá alternativa k ext4 nebo squashfs.Je navržen pouze pro čtení, s velmi dobrým výkonem na flash/SSD, standardně kompresí lz4 a široce používán na telefonech Android s dm-verity.

Soubory, které musí být zapisovatelné

S root ro některé programy očekávají zápis do /etc nebo během inicializaceMůžete jej přesunout do /var/etc a přidat symbolický odkaz na cokoli, co je potřeba změnit (např. připojení NetworkManageru v /etc/NetworkManager/system-connections). Upozorňujeme, že systemd-journald vyžaduje, aby /etc/machine-id existoval v kořenovém adresáři (ne jako symbolický odkaz), aby se zabránilo přerušení předčasného spuštění.

Chcete-li zjistit, jaké změny se mění v provedení, použijte dracut-overlayroot: překryje tmpfs přes kořenový adresář a vše zapsané se zobrazí v /run/overlayroot/u. Přidejte modul do /usr/lib/dracut/modules.d/, uveďte overlayroot v dracut a nastavte overlayroot=1 na řádku kernelu; tímto způsobem uvidíte, co migrovat do /var.

Užitečné příklady: pacman a NetworkManager

V Archu je to pohodlné Přesuň databázi Pacmana do /usr/lib/pacman ...aby kořenový souborový soubor (rootfs) vždy zrcadlil nainstalované balíčky. Poté přesměrujte mezipaměť do /var/lib/pacman a prolinkujte ji. Chcete-li změnit seznam zrcadel bez dotčení kořenového adresáře, přesuňte jej do /var/etc a i tak prolinkujte.

S programem NetworkManager, přesunout systémová připojení do /var/etc/NetworkManager a propojte jej z /etc/NetworkManager/system-connections. Tím se udrží kořenový adresář neměnný a konfigurace zůstane aktivní tam, kde by měla být zapisovatelná.

Konstrukce pravdivosti a testování

Z živého prostředí, se vším perfektně nainstalovaným v ro, vytvořte strom a roothash pomocí formát veritysetupPo spuštění se vypíše řádek Root Hash, který si můžete uložit do souboru roothash.txt. Pro testování jej spusťte pomocí příkazu veritysetup: open root-device root verity-device $(cat roothash.txt) a mount /dev/mapper/root.

Pokud preferujete, nejprve vygeneruje strom do souboru (verity.bin) a poté jej zapište na oddíl VERITY. Výsledná sada je: kořenový obraz, strom verity a kořenový hash, který uložíte při spuštění.

Konfigurace řádku jádra

Přidejte tyto parametry: systemd.verity=1, roothash=contents_of_roothash.txt, systemd.verity_root_data=ROOT-PATH (např. LABEL=OS) a systemd.verity_root_hash=VERITY-PATH (např. LABEL=VERITY). Pro striktní zásady nastavte systemd.verity_root_options na restart-on-corruption nebo panic-on-corruption.

Další doporučené možnosti: ro (pokud nepoužíváte EROFS/squashfs), rd.emergency=restart y rd.shell=0 (zabránit neoprávněným shellům v případě selhání bootování) a uzamčení = důvěrnost k ochraně paměti jádra před přístupem.

Další příčky s verity

Nejen kořen: Další mapování můžete definovat v souboru /etc/veritytab. a systemd-veritysetup@.service je sestaví při spuštění. Nezapomeňte: je snazší připojit RW oddíl bez oprávnění root a uživatel root by mohl na těchto oddílech zakázat Verity, takže hodnota zabezpečení je tam nižší.

Zabezpečení: Secure Boot, UKI a podepsané moduly

dm-verity není zázračné řešení. Podepište UKI a povolte Secure Boot pomocí vlastních klíčů aby se zabránilo komukoli v přepsání kernelu/initramfs/cmdline (který obsahuje kořenový hash). Nástroje jako sbupdate-git nebo sbctl pomáhají udržovat podepsané obrazy a zaváděcí řetězec neporušený.

Pokud povolíte uzamčení jádra nebo ověřování podpisu modulů, Moduly DKMS nebo out-of-tree musí být podepsány. nebo se nenačtou. Zvažte vlastní jádro s podporou podepisování pro váš pipeline (viz podepsané moduly jádra).

Šifrování, TPM a měření

dm-verity chrání integritu, nedůvěrnostRoot svazek můžete nechat nešifrovaný, pokud neobsahuje žádné tajné kódy a bootovací řetězec je chráněn. Pokud používáte klíčové soubory z root svazku k odemknutí jiných svazků, je vhodné ho zašifrovat.

S TPM 2.0, systemd-cryptenroll umožňuje vázání klíčů na PCR 0,1,5,7 (firmware, možnosti, GPT, stav zabezpečeného bootování). Přidejte rd.luks.options=LUKS_UUID=tpm2-device=auto a nezapomeňte v initramfs zahrnout podporu TPM2. systemd-boot měří kernel.efi v PCR4, což je užitečné pro zneplatnění klíčů, pokud se změní UKI nebo jeho příkazový řádek.

Aktualizace a modely nasazení

Ověřený kořenový server pouze pro čtení Neaktualizuje se tradičním způsobem pomocí správce balíčků.Ideální je vytvářet nové obrazy pomocí nástrojů, jako je projekt Yocto a publikujte je. Systemd má k dispozici systemd-sysupdate a systemd-repart pro robustní stahování a flashování obrazů.

Další strategií je A/B schémaPonecháte dva kořenové adresáře a dvě verity adresáře. Zkopírujte aktivní kořenový adresář do neaktivního kořenového adresáře, aplikujte změny a zopakujte verity adresáře. Při dalším spuštění se vraťte zpět. Pokud používáte UKI, nezapomeňte aktualizovat hash kořenového adresáře v příkazovém řádku nebo znovu sestavit podepsaný UKI.

Pro volitelnou perzistenci, použijte OverlayFS na ověřeném kořenovém adresáři s horním v tmpfs nebo disku. Pro dočasnou perzistenci můžete také zadat systemd.volatile=overlay. Flatpak usnadňuje instalaci aplikací do /var a /home bez nutnosti dotýkat se /.

Existují automatizované balíčky (např. verity-squash-root v AUR), které vytvářejí kořenový adresář squashfs a podepište roothash pomocí kernelu a initramfs, což vám umožňuje vybrat si mezi trvalým a dočasným režimem a uchovávat nejnovější kořenové soubory jako zálohu. Poznámka: přidání trvalosti k ověřenému kořenovému složce má úzké případy použití; zkuste uchovávat data aplikací na samostatných oddílech.

Android: systém jako root, AVB a překryvy dodavatelů

Od Androidu 10, RootFS přestane běžet na RAM disku a integruje se se souborem system.img. (system-as-root). Zařízení spouštěná s Androidem 10 vždy používají toto schéma a vyžadují ramdisk pro dm-linear. BOARD_BUILD_SYSTEM_ROOT_IMAGE je v této sestavě nastaven na hodnotu false, aby se rozlišilo mezi použitím ramdisku a přímou aktivací souboru system.img.

Android 10 obsahuje dynamické oddíly a inicializace první fáze který aktivuje logický systémový oddíl; jádro jej již nepřipojuje přímo. OTA pouze pro systém vyžadují design system-as-root, který je povinný na zařízeních s Androidem 10.

V žádném A/B, oddělte obnovu od bootováníNa rozdíl od A/B neexistuje žádná záloha boot_a/boot_b, takže odstranění obnovy v jiném režimu než A/B vás může nechat bez režimu obnovy, pokud se aktualizace bootování nezdaří.

Jádro připojuje soubor system.img k /converity dvěma cestami: vboot 1.0 (záplaty pro jádro, které parsuje metadata Androidu v /system a odvozuje parametry dm-verity; příkazový řádek obsahuje root=/dev/dm-0, skip_initramfs a init=/init s dm=…) nebo vboot 2.0/AVB, kde bootloader integruje libavb, čte deskriptor hashtree (ve vbmeta nebo system), konstruuje parametry a předává je jádru v cmdline s podporou FEC a příznaky jako restart_on_corruption.

Se systémem jako root, Nepoužívejte BOARD_ROOT_EXTRA_FOLDERS pro kořenové složky specifické pro zařízení: tyto zmizí po flashování GSI. Definujte konkrétní připojení v /mnt/vendor/ , které fs_mgr automaticky vytvoří, a odkazují na ně v souboru fstab stromu zařízení.

Android umožňuje překryv dodavatele z /product/vendor_overlay/: init připojí do /vendor podadresáře, které splňují požadavky kontextu SELinuxu a existenci /vendor/ Vyžaduje CONFIG_OVERLAY_FS=yy, na starších jádrech patch override_creds=off.

Typická implementace: nainstaluje předkompilované soubory do zařízení/ / /overlay_dodavatele/, přidejte je do PRODUCT_COPY_FILES pomocí find-copy-subdir-files do $(TARGET_COPY_OUT_PRODUCT)/vendor_overlay, definujte kontexty ve file_contexts pro etc a app (např. vendor_configs_file a vendor_app_file) a povolte mounton na těchto kontextech v init.te. Otestujte s atest vfs_mgr_vendor_overlay_test v userdebug.

Odstraňování problémů: hláška o poškození dm-verity v systému Android

U zařízení se sloty A/B změňte sloty nebo Flashování vbmeta/boot bez konzistence s roothashem To může spustit varování: dm-verity corruption, your device is untrusted. Příkazy jako fastboot flash –disable-verity –disable-verification vbmeta vbmeta.img deaktivují ověření, ale ponechávají systém bez jakékoli záruky integrity.

Některé bootloadery podporují fastboot oem disable_dm_verity a jeho opak, enable_dm_verity. Funguje na některých modelech, ale na jiných ne; a může vyžadovat kernel/magisk s upravenými příznaky. Používejte na vlastní nebezpečí: rozumný postup je zarovnání boot, vbmeta a system, podepište nebo regenerujte strom a ujistěte se, že očekávaný kořenový hash odpovídá nakonfigurovanému.

Pokud po varování můžete pokračovat v stisknutí tlačítka napájení, systém se spustí, ale už nemáš neporušený řetězec důvěryChcete-li zprávu odstranit bez obětování zabezpečení, obnovte původní podepsané obrazy nebo znovu sestavte/ověřte vbmeta se správným hashtreeem namísto deaktivace verity.

Platformy i.MX a OpenWrt

Na i.MX6 (např. sabresd), nakonfigurujte jádro s podporou DM_VERITY a FEC, vygenerujte strom pomocí veritysetup, bezpečně uložte kořenový hash a předejte příslušné parametry v příkazovém řádku nebo integrujte pomocí initramfs pomocí systemd-veritysetup. Pokud nepoužíváte dm-crypt, nepotřebujete pro verity CAAM; důraz je kladen na integritu.

V OpenWrt a v Vestavěné Linuxové systémy s OpenEmbedded, Existují snahy o integraci dm-verity a SELinuxu (Úlohy Bootlin byly revidovány s cílem začlenit podporu). Je to přirozené propojení: routery a síťová zařízení těží z neměnného, ​​ověřeného a MAC-zabezpečeného kořenového adresáře.

Ruční konstrukce stromu a metadat (podrobný pohled)

cryptsetup může strom vygenerovat za vás, ale pokud chcete porozumět formátu, definice kompaktního řádku tabulky obsahuje: název mapování, datové zařízení, velikosti datových bloků a hashů, velikost obrazu v blocích, hash_start position (obrázek bloku + 8, pokud je zřetězeno), kořenový hash a sůl. Po vygenerování zřetězených vrstev (shora dolů, s výjimkou vrstvy 0) zapíšete strom na disk.

Abychom všechno sbalili, sestavit tabulku dm-verity, podepsat ji (typicky RSA-2048) a seskupit tabulku podpisů+v metadatech s verzovanou hlavičkou a magickým číslem. Poté zřetězí obraz systému, metadata Verity a hašovací strom. V souboru fstab označí fs_mgr jako verify a umístí veřejný klíč do /boot/verity_key pro ověření podpisu.

Optimalizovat s Zrychlení SHA-2 pro váš CPU a upravte čtení předem/prefetch_cluster. Na hardwaru ARM výrazně snižují rozšíření NEON SHA-2 (ARMv7) a SHA-2 (ARMv8) režijní náklady na ověřování.

Při jakémkoli nasazení pamatujte na to kořenová hašovací hodnota musí být chráněna: ať už je zkompilováno do podepsaného UKI, do podepsaného bootovacího oddílu nebo ověřeno bootloaderem pomocí AVB. Všechno po tomto bodě zdědí tuto důvěryhodnost.

Se všemi výše uvedenými podmínkami se dm-verity stává solidní základ pro neměnné, mobilní a vestavěné systémy, s podporou transakčních aktualizací, konfiguračních překryvů a moderního bezpečnostního modelu, který snižuje plochu pro útok a zabraňuje jeho vytrvalosti bez obětování výkonu.

Co je projekt Yocto?
Související článek:
Co je projekt Yocto: Kompletní průvodce vestavěnými systémy