- dm-verity верификује блокове у реалном времену користећи криптографско хеш стабло, спречавајући тихе измене на критичним партицијама.
- Поверење је усидрено у коренском хешу и његовом потпису, интегрисаном у ланац боот верификовано заједно са покретачким програмима, кернелом и Secure Boot-ом.
- Андроид, линук и уграђени системи користе dm-verity за корене само за читање, комбинујући га са FEC-ом, ТПМ и шифровање ради ојачавања система.
- Ажурирање система помоћу dm-verity-ја заснива се на непроменљивим сликама, A/B шемама и преклапањима, избегавајући директне промене на верификованом корену.
Ако радите са Андроидом, Линуксом или уграђеним системима, вероватно сте видели поруке попут „dm-verity corruption“ или сте чули за verified boot, AVB или Secure Boot. Иза свега тога стоји кључна компонента језгра: dm-verity, механизам дизајниран да осигура да систем датотека није неовлашћено мењан , било док је уређај укључен или између поновних покретања.
Можда делује као проблем ниског нивоа, али заправо утиче на свакодневне ствари попут спречавања телефона да садржи злонамерни софтвер скривен у системској партицији или осигуравања да се рутер или „затворени“ сервер увек покреће у истом поузданом стању. dm-verity се ослања на SHA-256 хеш стабло и криптографске потписе како би проверио, блок по блок, да ли су подаци на диску и даље онакви какви би требало да буду . Ако се нешто не поклапа, језгро може вратити грешке читања, поново покренути рачунар или чак паничити како би избегло извршавање било ког сумњивог кода.
Шта је dm-verity и који проблем решава?
`dm-verity` је циљ подсистема `device-mapper` у Линуксовом кернелу који омогућава проверу интегритета блок уређаја у реалном времену , обично партиције или слике која садржи коренски фајл систем или критичну партицију (нпр. `/system` на Андроиду). Уместо „слепо“ читања диска, сваки приступљени блок се криптографски проверава у односу на унапред израчунато хеш стабло.
У Андроиду од верзије 4.4 и у многим модерним Линукс дистрибуцијама, dm-verity је основа верификованог покретања : осигурава да је системска партиција потпуно иста као када је слика креирана. Ово отежава руткиту или другој врсти малвера да опстане након поновног покретања система убризгавањем злонамерних датотека или бинарних датотека у систем.
Једна од предности овог приступа је то што се dm-verity уређаји појављују као нормални блок уређаји под /dev/mapper , што им омогућава да се монтирају баш као и било који други диск. За основни фајл систем (ext4, EROFS, squashfs, итд.), све изгледа стандардно, али свака операција читања се филтрира кроз verity-јев криптографски филтер.
Зашто је то неопходно: злонамерни софтвер са root приступом и поузданим покретањем система

У системима попут Андроида, апликације или бинарне датотеке које добијају root привилегије могу се боље сакрити од система за детекцију . Имање више дозвола од антивирусних или безбедносних алата им омогућава да „лажу“ о датотекама, процесима или конфигурацијама, што их чини тежим за откривање и уклањање.
Без механизма као што је dm-verity, нападач може да модификује системске бинарне датотеке, библиотеке или скрипте за покретање како би постигао перзистентност , спречавајући тако алате за верификацију интегритета датотека да открију измену; другим речима, остајање чак и након што се уређај искључи и поново укључи. Ово је класична ноћна мора перзистентних руткитова.
dm-verity делује као чувар у темељима система: језгро прихвата као валидне само оне блокове који се подударају са очекиваним хешем из стабла верификације . Ако је неко изменио системску партицију без дозволе, хешеви се више неће подударати, а језгро ће то открити чим покуша да прочита измењене податке.
Како dm-verity функционише интерно
Основна идеја је једноставна, али моћна: криптографско стабло хешева (обично SHA-256) се гради хијерархијски преко свих блокова на уређају. Ово стабло се чува на диску и, током нормалне употребе, користи се за валидацију сваког прочитаног блока.
Структура хеш стабла
Стабло верификације је структурирано у слојевима. Слој 0 садржи стварне податке (нпр. слику система ext4/EROFS), подељене на блокове од 4K . SHA-256 хеш се израчунава за сваки од ових блокова (обично са случајном сољу ради отпорности на нападе пре израчунавања).
Хешови из слоја 0 се спајају да би се формирао слој 1. Слој 1 се затим групише у блокове од 4K и за сваки резултујући блок се израчунава SHA-256 хеш , чиме се добија слој 2. Процес се понавља слој по слој док се цео скуп хешева не уклопи у један блок; хеш тог последњег блока је коренски хеш, који представља цело стабло.
Када слој не попуњава цео блок, он се допуњава нулама док не достигне 4K . Ово избегава двосмислености и омогућава откривање покушаја „скраћивања“ стабла заменом делова произвољним подацима: очекивана структура укључује ово познато допуњавање нулама.
На диску се стабло чува спајањем нивоа од највишег слоја надоле (искључујући слој података 0) . Укупна величина стабла варира у зависности од величине партиције која се проверава, али у пракси је обично прилично мала, типично мања од 30 MB чак и за велике системске партиције.
Верзије формата и хеш алгоритми
Формат у којем се чувају хеш блокови је еволуирао. Верзија 0 формата, коју је првобитно користио Chromium OS, додавала је „сол“ на крај приликом израчунавања хеша и чувала је сажетке континуирано , допуњујући остатак блока нулама.
Верзија 1, која се препоручује за новије системе, додаје „со“ хешу пре података и допуњује сваки дајџ на степен два. Ово побољшава поравнање и робусност против одређених врста напада или оштећења. Табела dm-verity такође показује коришћени алгоритам (sha1, sha256, итд.), иако је данас разумно користити SHA-256.
Корак-по-корак израчунавање коренског хеша
Ако желите ручно да изградите стабло, општа шема је јасна. Прво, бирате случајну со у хексадецималном формату, делите слику на блокове од 4K и за сваки блок израчунавате његов сољени SHA-256 . Ови хешеви формирају први „логички“ ниво изнад података.
Затим се хешеви спајају док се не попуни 4K блокова ; ако нема довољно простора, додају се нуле. Сваки резултујући блок се такође хешира помоћу SHA-256 алгоритма да би се формирао следећи ниво стабла. Овај процес „хеш на хешеве“ се понавља док не остане само један хеш: коренски хеш.
У практичним имплементацијама, алати попут cryptsetup/veritysetup обрађују сва ова прорачуна и директно генеришу датотеку стабла (verity.bin) и вредност коренског хеша (roothash) , спремне за употребу у dm-verity табели или у потписаним метаподацима.
dm-verity табела: опис шта и како проверити
Да би језгро користило dm-verity, потребан му је прецизан опис где се подаци налазе, где се налази хеш стабло и које параметре треба користити. Тај опис је dm-verity табела, линија параметара које мапер уређаја интерпретира приликом креирања верификованог логичког уређаја.
У типичној поједностављеној верзији , дефиниција се може посматрати као:
<име мапирања> <уређај за податке> <величина блока података> <величина хеш блока> <величина слике у блоковима> <почетак_хеша> <коренски хеш> <сол>
Најважнија поља у dm-verity табели су обично:
- дев: уређај који садржи податке које треба верификовати (на пример, партиција /dev/sdXN или пар major:minor).
- хеш_развој: уређај који чува хеш стабло; може бити исто што и dev, све док hash_start показује ван опсега верификованих података.
- величина_блока_података: величина блока података у бајтовима, обично 4096.
- величина_хеш_блока: величина блока за хешеве, обично је такође 4096.
- број_блокова_податакаброј блокова података које треба заштитити.
- хеш_почетни_блок: помак у блоковима од почетка уређаја до места где почиње хеш стабло.
- алгоритам: хеш алгоритам (sha256 је де факто стандард).
- дајџест (коренски хеш): хеш коренског блока стабла, изражен у хексадецималном систему; то је поуздано „сидро“.
- соСо се користи при израчунавању хешева, такође у хексадецималном облику.
Поред ових основних поља, постоје опциони параметри који подешавају како систем реагује на оштећење или грешке . На пример, можете навести да се у случају оштећења систем поново покрене, да се „паничи“, да се игнорише и само евидентира или да се FEC опоравак активира пре квара.
Напредне опције табеле: корупција, FEC и перформансе
dm-verity укључује скуп заставица за понашање профилисања. ignore_corruption омогућава континуирано читање чак и ако се открије оштећење, али оставља траг у логовима , што је корисно у окружењима где је доступност приоритетнија од строгог интегритета.
За строже спровођење, `restart_on_corruption` или `panic_on_corruption` приморавају рестарт или панику када блок не успе на верификацији . Сличне варијанте постоје за I/O грешке (`restart_on_error`, `panic_on_error`). Постоји и опција `ignore_zero_blocks` која избегава верификацију блокова за које се очекује да буду нула и директно враћа нуле.
За системе који укључују корекцију унапред, `use_fec_from_device` заједно са `fec_roots`, `fec_blocks` и `fec_start` омогућавају употребу Рид-Соломонових кодова . Са FEC-ом, у случају неуспеха верификације, може се покушати реконструисати блок користећи редундантне информације пре него што се напусти.
Друге опције, као што је `check_at_most_once`, дозвољавају да се сваки блок провери само први пут када му се приступи , смањујући оптерећење по цену неоткривања активних измена; то је компромис између безбедности и перформанси. Заставице попут `root_hash_sig_key_desc` омогућавају језгру да валидира PKCS7 потпис коренског хеша користећи кључеве сачуване у привеску кључева.
Потпис, метаподаци и магични број верити
Да би све имало смисла, вредност коренског хеша мора бити поуздана. У класичном Андроиду, јавни кључ је укључен у партицију за покретање, а произвођач је одговоран за његову екстерну верификацију . Овај кључ се користи за валидацију потписа коренског хеша или dm-verity табеле, осигуравајући да хеш стабло није измењено.
Веритијеви метаподаци обухватају ове информације. Блок од 32 КБ садржи магични број, верзију, потпис, дужину табеле и садржај, плус нулто попуњавање . Ова контролисана структура омогућава недвосмислено лоцирање и валидацију метаподатака.
Типична поља у овим метаподацима укључују:
- Магични број: фиксна вредност 0xb001b001, коју користе компоненте као што је fs_mgr да би препознале да је у питању валидан блок верити.
- Версион: тренутно 0, користи се за увођење промена формата у будућности.
- Компанија: dm-verity потпис табеле, обично PKCS1.5 са RSA-2048 (256 бајтова) кључем.
- Дужина столаВеличина dm-verity табеле сачуване испод у бајтовима.
- Табла: сама серијализована dm-verity табела.
- Пуњено: нуле док се не заврши 32.000 бајтова блока.
Ако се магични број не пронађе приликом анализе краја системске слике, претпоставља се да партиција није спремна за верификацију и да процес верификације није активиран . Ово спречава, на пример, третирање партиције као верификоване када није.
У Андроиду, fs_mgr и датотека fstab контролишу које партиције се верификују . Једноставно додајте заставицу верификације (на пример, „verify“ у заставицама fs_mgr) и поставите одговарајући јавни кључ у /boot/verity_key да бисте активирали ток верификације од почетка до краја.
Како се повезује са верификованим стартапом
dm-verity не би био од велике користи ако би нападач могао да убаци модификовано језгро или покретачки програм који прихвата било шта. Зато су на мобилним уређајима и безбедним платформама коренски хеш и dm-verity табела део ланца поверења који почиње на нивоу хардвера.
Обично произвођач уграђује јавни кључ на уређај. Овај кључ валидира потпис првог покретача система, који затим верификује следећи ниво, покретач апликације и коначно, слику језгра . Одатле, верификовано језгро преузима контролу и користи dm-verity да прошири то поверење на системску партицију.
У модерним Андроид системима са AVB (Android Verified Boot 2.0), бутлоудер укључује libavb и чита дескрипторе хеш стабла са партиција или vbmeta . Користећи ове информације, конструише dm-verity параметре и прослеђује их језгру путем командне линије , заједно са инструкцијама као што су да ли је FEC присутан, шта урадити у случају оштећења и тако даље.
dm-verity на Андроиду: поруке о системском приступу као root, AVB и оштећењу
Андроид се годинама ослања на dm-verity. Од Андроида 4.4, користи се као основа за верификовано покретање, а од Андроида 10 па надаље, дизајн system-as-root директно интегрише rootfs у system.img , елиминишући многа класична монтирања и захтевајући да се dm-verity обрађује из прве фазе иницијализације.
Са системским приступом као кореном и модерним ОТА ажурирањима, системска партиција је обично само за читање, заштићена верификованим хеш стаблом . Језгро је види преко dm-verity уређаја, транспарентно за горњи слој Андроида.
Грешке слотова A/B, vbmeta и „dm-verity corruption“
На уређајима са А/Б шемом, прилично је лако да нешто крене наопако. Ако флешујете boot или vbmeta без подударања roothash-а и стварног стабла системских партиција, типичан резултат је застрашујућа порука „dm-verity оштећење, ваш уређај није поуздан“.
Да бисте заобишли верификацију, постоје команде попут `fastboot flash --disable-verity --disable-verification vbmeta vbmeta.img` или, за неке произвођаче, `fastboot oem disable_dm_verity`. Али будите опрезни: ово онемогућава верификовано покретање и елиминише гаранције интегритета , чак и ако успете да покренете систем без икаквих досадних порука.
„Чист“ начин да се ово поправи подразумева осигуравање да су системске, бут и vbmeta слике међусобно конзистентне , регенерисање (или враћање) verity стабла и ажурирање потписа или дескриптора тако да очекивани коренски хеш одговара стварном. Само на овај начин можете одржати ланац поверења без прибегавања опасним триковима.
Веза са TWRP-ом, откључаним бутлоудером и модовима
У стварном свету, многи људи се сусрећу са dm-verity приликом инсталирања ROM-ова, модификованих кернела или рутовања својих уређаја. Да би експериментисали са TWRP-ом, флешовали фирмвер или инсталирали модове, обично је неопходан откључани покретачки програм јер верификовано покретање спречава покретање са непотписаних слика за покретање.
Неке процедуре препоручују, на пример, прво флешовање одређеног фирмвера, поновно покретање система у режиму бутлоудера и извршавање команди попут „fastboot oem disable_dm_verity“ праћено „fastboot oem enable_dm_verity“ , а затим инсталирање новијег фирмвера. Ови кораци имају за циљ „ресетовање“ стања верити-ја тако да се нове слике прихватају без грешака услед оштећења.
Ако, након падова система или грешака при флешовању, почнете да видите поруке „dm-verity corruption“ при сваком поновном покретању, паметно је проверити да систем партиција није физички оштећен и да ли су слике које користите исправне за ваш модел . Понекад једноставна неусклађеност између модема, покретачког програма и системског фирмвера може да поремети процес верификованог покретања.
dm-verity на Linux рачунарима и серверима (systemd, veritysetup)
dm-verity није ексклузиван за Андроид. У модерним Линукс дистрибуцијама, посебно са systemd, постаје популаран као основа за коренске системе високог поверења, само за читање , слично као што раде неки рутери, уређаји или медијски уређаји.
Типично root монтирање помоћу dm-verity укључује: root слику или партицију, датотеку која садржи verity стабло (verity.bin), root хеш вредност, systemd-veritysetup јединице и одговарајуће параметре језгра . Опционо, додају се потписани UKI (Unified Kernel Image) и Secure Boot ради додатне безбедности система.
Шема партиционисања и систем датотека
Уобичајена препорука је резервисање одређене партиције за хешеве. Уобичајени распоред се састоји од: EFI партиције (ESP), XBOOTLDR партиције за UKI-је, коренске партиције (са или без енкрипције), VERITY партиције за стабло и опционо, партиција на које се може писати /home и /var.
Уместо класичног ext4 за root приступ, EROFS је веома занимљива опција : дизајниран је само за читање, има одличне перформансе на флеш меморији и SSD дисковима и подржава lz4 компресију одмах по инсталацији. Није случајно што се широко користи на Андроид телефонима у комбинацији са dm-verity.
Датотеке које треба писати и уобичајени трикови
Ако је коренски директоријум монтиран само за читање, потребно је пажљиво размотрити које датотеке треба да буду доступне за уређивање. Многи програми очекују да пишу у /etc, /var или сличне путање . Уместо да /etc буде потпуно доступан за писање, ефикасније је преместити само неопходне датотеке у /var/etc и симболички их повезати из /etc.
На пример, везе NetworkManager-а могу се преместити у /var/etc/NetworkManager/system-connections и оставити симболички линк на /etc/NetworkManager/system-connections. Ово не нарушава дизајн непроменљивог корена, али конфигурације које треба променити и даље могу бити модификоване.
Да бисте открили шта се заправо пише током покретања и извршавања система, можете користити `dracut-overlayroot`, који монтира tmpfs прекривач преко коренског директоријума и бележи сва стварна писања у `/run/overlayroot/u` . Након што неко време користите систем, једноставно прегледајте тај директоријум да бисте видели шта треба преместити из верификованог коренског директоријума.
У Arch Linux-у је такође уобичајено да се pacman база података премести у /usr/lib/pacman, а кеш у /var/lib/pacman , тако да коренска слика увек одражава „запечаћено“ стање система, док се операције синхронизације и ажурирања обављају у областима за писање.
Креирање Verity-ја и конфигурисање процеса покретања помоћу Systemd-а
Типичан ток рада на Linux систему који жели да користи dm-verity за root приступ би био:
- Покрените систем из живог окружења и монтирајте коренски директоријум као само за читање., када је систем остављен тачно онако како желите да буде „замрзнут“.
- Покрените `veritysetup format root-device verity-device` да бисте генерисали хеш стабло и коренски хеш.Команда обично исписује ред са Root Hash-ом, који је сачуван у датотеци (на пример, roothash.txt).
- Тестирајте мапирање са отвореним veritysetup-ом, креирајући верификовани /dev/mapper/root и монтирајући га да би се проверило да ли све ради.
Затим, треба да подесимо командну линију језгра. Са systemd-ом, користимо параметре као што су systemd.verity=1, roothash=…, systemd.verity_root_data=… и systemd.verity_root_hash=… , као и опције као што су systemd.verity_root_options=restart-on-corruption или panic-on-corruption у зависности од жељене чврстоће.
Ако се користи UKI, сви ови параметри су интегрисани у kernel.efi слику, која је потписана и покренута помоћу Secure Boot-а . Ово спречава било кога да промени roothash у командној линији без поништавања потписа, чиме се одржава модел поверења.
Безбедно покретање, шифровање и TPM: спајање делова
dm-verity гарантује само интегритет, а не поверљивост. Подаци се могу прегледати ако нису шифровани, али се не могу мењати без откривања . Зато се често комбинује са шифровањем (LUKS) и TPM-ом ради заштите кључева.
Уобичајена стратегија је повезивање LUKS кључева за дешифровање са одређеним TPM PCR-овима користећи systemd-cryptenroll (PCR-ови 0, 1, 5 и 7, на пример), тако да промена фирмвера, распореда партиције или статуса Secure Boot-а поништава кључеве. Ово спречава нападача да онемогући Secure Boot како би инсталирао језгро које игнорише Verity, а да истовремено не прекине ланац дешифровања.
Ако се користи systemd-boot, bootloader мери kernel.efi слику у PCR 4. Ако се ово мерење промени, повезани кључеви се не отпуштају и шифрована партиција се не отвара. Ово је још једна веза у осигуравању да језгро, initramfs и cmdline (укључујући roothash) нису измењени.
Употреба ван корена: друге партиције, преклапања и ажурирања
Иако је заштита коренске партиције најчешћа пракса, dm-verity се може применити и на друге партиције које се монтирају при покретању система . На системима који користе systemd, ове додатне партиције су описане у /etc/ veritytab и конфигуришу се аутоматски.
Међутим, верификована партиција која није root је мање безбедна: може се релативно лако читати/писати на root партицију, а root корисник може онемогућити Verity на њој . Упркос томе, корисна је за податке које желите да пратите или за слике само за читање монтиране негде другде.
Што се тиче ажурирања, верификовани root само за читање мења начин размишљања. Од администратора се више не очекује да покреће „pacman -Syu“ или сличне команде на продукцијском root-у ; уместо тога, генеришу се нове системске слике, заједно са одговарајућим verity стаблима, и распоређују се трансакционо.
Постоји неколико стратегија за ово: коришћење алата као што су systemd-sysupdate и systemd-repart за преузимање и флешовање нових слика или подржавање A/B шеме са два root-а и две verity партиције, где ажурирате неактивну партицију, а затим мењате улоге.
За већу флексибилност, можете монтирати верификовани коренски директоријум као нижи директоријум на OverlayFS-у, са горњим слојем на tmpfs-у или disku . На овај начин, промене се примењују на горњи слој, али основа остаје верификована слика. Можете чак да се одлучите за опциону или ефемерну перзистентност (нпр. systemd.volatile=overlay) да бисте имали „једнократне сесије“.
У свету десктоп рачунара, технологије попут Flatpak-а се добро уклапају у ову филозофију , јер инсталирају и ажурирају апликације у /var и /home директоријумима без додиривања коренског директоријума заштићеног Verity-јем. Ово одржава непроменљиви основни систем и омогућава независно управљање апликацијама.
Читав овај екосистем чини dm-verity много више од пуке куриозитета кернела: он је камен темељац непроменљивих, мобилних и уграђених система који се увек морају покретати у познатом стању, детектовати сваку манипулацију складиштењем и интегрисати се са верификованим покретањем, безбедним покретањем, енкрипцијом и TPM-ом како би понудио модеран без жртвовања превише перформанси или флексибилности.
Страствени писац о свету бајтова и технологије уопште. Волим да делим своје знање кроз писање, и то је оно што ћу радити на овом блогу, показивати вам све најзанимљивије ствари о гаџетима, софтверу, хардверу, технолошким трендовима и још много тога. Мој циљ је да вам помогнем да се крећете у дигиталном свету на једноставан и забаван начин.