
Jika Anda khawatir tentang integritas sistem Anda, dm-verity adalah salah satu bagian penting dari ekosistem Linux untuk melakukan booting dengan aman dan mendeteksi gangguan penyimpanan. Awalnya, fitur ini merupakan bagian dari pemetaan perangkat kernel dan sekarang menjadi dasar untuk booting terverifikasi di Android, OpenWRT, dan distribusi yang menginginkan keamanan lebih tinggi.
Jauh dari sebuah konsep abstrak, dm-verity dikonfigurasi dan digunakan dengan alat nyata seperti veritysetup dan systemd-veritysetupIa memvalidasi blok secara langsung menggunakan pohon hash dan dapat bereaksi terhadap kerusakan dengan berbagai kebijakan, mulai dari pencatatan peristiwa hingga melakukan boot ulang atau membuat sistem crash. Mari kita bahas lebih lanjut, tanpa meninggalkan hal yang terlewat.
Apa itu dm-verity dan mengapa Anda mungkin peduli
dm-verity adalah target pemetaan perangkat di kernel yang memverifikasi integritas perangkat blok saat data dibacaCara kerjanya dengan menghitung dan memverifikasi hash setiap blok (biasanya 4K) terhadap pohon hash yang telah dihitung sebelumnya, biasanya menggunakan SHA-256.
Desain ini memungkinkan untuk File tidak dapat dimodifikasi secara diam-diam antara reboot atau selama eksekusiIni adalah kunci untuk memperluas rantai kepercayaan boot ke sistem operasi, membatasi persistensi malware, memperkuat kebijakan keamanan, dan memastikan enkripsi dan mekanisme MAC selama boot.
Di Android (sejak 4.4) dan Linux secara umum, Kepercayaan berlabuh di hash akar pohon, yang ditandatangani dan divalidasi dengan kunci publik yang terletak di lokasi yang dilindungi (misalnya, pada partisi boot atau di UKI bertanda tangan Boot Aman). Memecah blok apa pun akan memerlukan pemecahan hash kriptografi yang mendasarinya.
Verifikasi dilakukan per blok dan sesuai permintaan: Latensi tambahannya minimal dibandingkan dengan biaya I/OJika pemeriksaan gagal, kernel akan menampilkan kesalahan I/O dan sistem berkas akan tampak rusak, yang wajar terjadi jika data tidak dapat diandalkan. Aplikasi dapat memutuskan untuk melanjutkan atau tidak berdasarkan toleransi kesalahannya.
Cara kerja pohon verifikasi secara internal
Pohon verifikasi dibangun berlapis-lapis. Lapisan 0 adalah data mentah dari perangkat, dibagi menjadi blok 4K; hash SHA-256 (salted) dihitung untuk setiap blok. Hash ini kemudian digabungkan untuk membentuk lapisan 1. Lapisan 1 kemudian dikelompokkan ke dalam blok dan di-hash ulang untuk membentuk lapisan 2, dan seterusnya hingga semuanya masuk ke dalam satu blok: blok tersebut, setelah di-hash, menghasilkan hash akar.
Jika ada lapisan yang tidak melengkapi blok secara tepat, Ini diisi dengan angka nol hingga mencapai 4K Untuk menghindari ambiguitas. Ukuran total pohon bergantung pada ukuran partisi yang diperiksa; dalam praktiknya, biasanya kurang dari 30 MB untuk partisi sistem pada umumnya.
Proses umumnya adalah: pilih garam acak, hash ke 4K, hitung SHA-256 dengan garam per blok, menggabungkan untuk membentuk level, mengisi batas blok dengan nol, dan mengulangi level sebelumnya hingga tersisa satu hash akar. Hash akar tersebut, beserta garam yang digunakan, akan dimasukkan ke tabel dm-verity dan tanda tangan.
Versi format disk dan algoritmanya
Format blok hash pada disk memiliki versi. Versi 0 adalah versi asli yang digunakan di Chromium OS:Garam ditambahkan pada akhir proses hashing, intisari disimpan terus-menerus, dan sisa blok diisi dengan angka nol.
La Versi 1 direkomendasikan untuk perangkat baruGaram ditambahkan sebelum hash, dan setiap intisari diberi angka nol hingga pangkat dua, sehingga meningkatkan keselarasan dan ketahanan. Tabel dm-verity juga menentukan algoritma (misalnya, sha1 atau sha256), meskipun untuk keamanan saat ini, sha256 yang digunakan.
tabel dm-verity dan parameter penting
Tabel target dm-verity menjelaskan di mana datanya, di mana pohon hashnya, dan bagaimana cara memverifikasinyaBidang tabel yang umum:
- dev: perangkat dengan data yang akan diverifikasi (jenis jalur /dev/sdXN atau lebih besar:lebih kecil).
- hash_dev: perangkat dengan pohon hash (bisa sama; jika demikian, hash_start harus berada di luar rentang yang dicentang).
- ukuran_blok_data: ukuran blok data dalam byte (misalnya 4096).
- ukuran_blok_hash: ukuran blok hash dalam byte.
- jumlah_blok_data: jumlah blok data yang dapat diverifikasi.
- hash_start_block: offset (dalam blok hash_block_size) ke blok akar pohon.
- algoritma: algoritma hash (misalnya sha256).
- intisari: pengkodean heksadesimal dari hash blok akar (termasuk garam menurut versi format); nilai ini adalah yang dapat dipercaya.
- garam: garam heksadesimal.
Selain itu, ada parameter opsional sangat berguna untuk menyesuaikan perilaku:
- abaikan_korupsi: Catatan tersebut merusak blok, tetapi memperbolehkan pembacaan dilanjutkan.
- mulai ulang saat terjadi kerusakan: mulai ulang saat mendeteksi kerusakan (tidak kompatibel dengan ignore_corruption dan memerlukan dukungan ruang pengguna untuk menghindari pengulangan).
- kepanikan terhadap korupsi: : menyebabkan kepanikan saat mendeteksi kerusakan (tidak kompatibel dengan versi sebelumnya).
- restart_on_error y panik_saat_terjadi_kesalahan: reaksi yang sama tetapi untuk kesalahan I/O.
- abaikan_nol_blok: tidak memeriksa blok yang diharapkan bernilai nol dan mengembalikan nol.
- gunakan_fec_dari_perangkat + fec_roots + fec_blok + fec_mulai: Aktifkan Reed–Solomon (FEC) untuk memulihkan data saat verifikasi gagal; area data, hash, dan FEC tidak boleh tumpang tindih, dan ukuran blok harus cocok.
- periksa_paling_banyak_sekali: Memeriksa setiap blok data hanya saat pertama kali dibaca (mengurangi overhead dengan mengorbankan keamanan dalam serangan langsung).
- root_hash_sig_key_desc: Referensi ke kunci dalam gantungan kunci untuk memvalidasi tanda tangan PKCS7 dari hash root saat membuat pemetaan (memerlukan konfigurasi kernel yang tepat dan gantungan kunci tepercaya).
- coba_verifikasi_di_tasklet: Jika hash di-cache dan ukuran I/O memungkinkan, periksa bagian bawah untuk mengurangi latensi; disesuaikan dengan /sys/module/dm_verity/parameters/use_bh_bytes per kelas I/O.
Tanda tangan, metadata, dan penjangkaran kepercayaan
Agar dm-verity dapat diandalkan, Hash root harus dipercaya dan biasanya ditandatanganiPada Android klasik, kunci publik disertakan dalam partisi boot, yang diverifikasi secara eksternal oleh pabrikan; ini memvalidasi tanda tangan hash root dan memastikan bahwa partisi sistem belum diubah.
Metadata Verity menambahkan struktur dan kontrol versi. Blok metadata mencakup angka ajaib 0xb001b001 (byte b0 01 b0 01), versi (saat ini 0), tanda tangan tabel dalam PKCS1.5 (biasanya 256 byte untuk RSA-2048), panjang tabel, tabel itu sendiri, dan bantalan nol hingga 32K.
Dalam implementasi Android, verifikasi bergantung pada fs_mgr dan fstab: Menambahkan tanda centang pada entri yang sesuai dan menempatkan kunci di /boot/verity_key. Jika angka ajaib tidak berada di tempat yang seharusnya, verifikasi dihentikan untuk menghindari pengecekan yang salah.
Mulai operasi terverifikasi
Perlindungan ada di kernel: Jika dikompromikan sebelum kernel di-boot, penyerang tetap memegang kendaliItulah sebabnya produsen biasanya memvalidasi setiap tahapan secara ketat: kunci yang dibakar ke dalam perangkat memverifikasi bootloader pertama, yang memverifikasi bootloader aplikasi berikutnya, dan terakhir, kernel.
Dengan kernel yang terverifikasi, dm-verity diaktifkan saat memasang perangkat blok terverifikasiAlih-alih melakukan hashing pada seluruh perangkat (yang akan lambat dan membuang-buang energi), perangkat diverifikasi blok demi blok saat diakses. Kegagalan menyebabkan kesalahan I/O, dan layanan serta aplikasi bereaksi sesuai toleransinya: melanjutkan tanpa data tersebut atau mengalami crash total.
Koreksi Kesalahan Maju (FEC)
Sejak Android 7.0, FEC (Reed–Solomon) digabungkan dengan teknik interlacing untuk mengurangi ruang dan meningkatkan kemampuan memulihkan blok yang rusak. Hal ini bekerja sama dengan dm-verity: jika pemeriksaan gagal, subsistem dapat mencoba memperbaikinya sebelum menyatakannya tidak dapat dipulihkan.
Kinerja dan optimalisasi
Untuk mengurangi dampak: Aktifkan akselerasi SHA-2 oleh NEON pada ARMv7 dan ekstensi SHA-2 pada ARMv8 dari kernel. Sesuaikan parameter read-ahead dan prefetch_cluster untuk perangkat keras Anda; verifikasi per blok biasanya hanya menambah sedikit biaya I/O, tetapi pengaturan ini berpengaruh.
Memulai di Linux (systemd, veritysetup) dan Android
Pada Linux modern dengan systemd, dm-verity memungkinkan root hanya-baca yang terverifikasi Menggunakan veritysetup (bagian dari cryptsetup), systemd-veritysetup.generator, dan systemd-veritysetup@.service. Disarankan untuk menyertakan Secure Boot dan UKI (unified kernel image) yang telah ditandatangani, meskipun keduanya tidak sepenuhnya diwajibkan.
Persiapan dan partisi yang direkomendasikan
Bagian dari sistem yang fungsional dan disesuaikan. Cadangkan volume untuk pohon hash (8–10% dari ukuran root biasanya sudah cukup) dan pertimbangkan untuk memisahkan /home dan /var jika Anda perlu menulis. Skema yang umum meliputi: ESP (untuk bootloader), XBOOTLDR (untuk UKI), root (dengan atau tanpa enkripsi), partisi VERITY, dan opsional /home dan /var.
Sebagai akar, EROFS adalah alternatif yang sangat menarik untuk ext4 atau squashfs: : Desainnya hanya-baca, dengan kinerja yang sangat baik pada flash/SSD, kompresi lz4 secara default, dan banyak digunakan pada ponsel Android dengan dm-verity.
File yang harus dapat ditulis
Dengan root ro, beberapa program berharap untuk menulis ke /etc atau selama initAnda dapat memindahkannya ke /var/etc dan menautkan simbol apa pun yang perlu diubah (misalnya, koneksi NetworkManager di /etc/NetworkManager/system-connections). Perhatikan bahwa systemd-journald mengharuskan /etc/machine-id berada di direktori root (bukan tautan simbolis) untuk menghindari kerusakan saat startup awal.
Untuk mengetahui perubahan apa saja yang terjadi dalam eksekusi, gunakan dracut-overlayroot: melapisi tmpfs di atas root, dan semua yang ditulis akan muncul di /run/overlayroot/u. Tambahkan modul ke /usr/lib/dracut/modules.d/, sertakan overlayroot di dracut, dan atur overlayroot=1 pada baris kernel; dengan cara ini Anda akan melihat apa yang harus dimigrasikan ke /var.
Contoh yang berguna: pacman dan NetworkManager
Di Arch, itu nyaman Pindahkan database Pacman ke /usr/lib/pacman agar rootfs selalu mencerminkan paket yang terinstal. Kemudian, alihkan cache ke /var/lib/pacman dan tautkan. Untuk mengubah daftar mirror tanpa mengubah root, pindahkan ke /var/etc dan tautkan.
Dengan NetworkManager, pindahkan koneksi sistem ke /var/etc/NetworkManager dan tautan dari /etc/NetworkManager/system-connections. Ini menjaga root tetap utuh dan konfigurasi tetap aktif di tempat yang seharusnya dapat ditulis.
Konstruksi veritas dan pengujian
Dari live dan dengan segala sesuatunya sempurna dan terpasang di ro, buat pohon dan roothash dengan format veritysetupSaat dijalankan, program akan mencetak baris Root Hash, yang dapat Anda simpan ke roothash.txt. Jalankan program untuk pengujian dengan veritysetup, buka root-device root verity-device $(cat roothash.txt) dan mount /dev/mapper/root.
Jika kamu memilih, pertama kali menghasilkan pohon ke dalam sebuah file (verity.bin) lalu menuliskannya ke partisi VERITY. Set yang dihasilkan adalah: citra root, pohon verity, dan hash root yang akan Anda pin saat boot.
Konfigurasikan baris kernel
Tambahkan parameter ini: systemd.verity=1, roothash=contents_of_roothash.txt, systemd.verity_root_data=ROOT-PATH (misalnya LABEL=OS), dan systemd.verity_root_hash=VERITY-PATH (misalnya LABEL=VERITY). Atur systemd.verity_root_options ke restart-on-corruption atau panic-on-corruption untuk kebijakan yang ketat.
Pilihan lain yang direkomendasikan: ro (jika Anda tidak menggunakan EROFS/squashfs), rd.darurat=mulai ulang y rd.shell=0 (mencegah shell yang tidak sah jika boot gagal), dan penguncian=kerahasiaan untuk melindungi memori kernel dari akses.
Partisi tambahan dengan verity
Bukan hanya akarnya: Anda dapat menentukan pemetaan lainnya di /etc/veritytab dan systemd-veritysetup@.service akan merakitnya saat boot. Ingat: lebih mudah untuk memasang RW pada partisi non-root, dan pengguna root dapat menonaktifkan Verity pada partisi tersebut, sehingga nilai keamanannya lebih rendah.
Keamanan: Boot Aman, UKI, dan modul yang ditandatangani
dm-verity bukanlah solusi ajaib. Tandatangani UKI dan aktifkan Secure Boot dengan kunci Anda sendiri untuk mencegah siapa pun mengganti kernel/initramfs/cmdline (yang mencakup hash root). Alat seperti sbupdate-git atau sbctl membantu menjaga agar gambar tetap ditandatangani dan rantai boot tetap utuh.
Jika Anda mengaktifkan penguncian kernel atau verifikasi tanda tangan modul, Modul DKMS atau modul di luar pohon harus ditandatangani Atau, kernel tersebut tidak akan dimuat. Pertimbangkan kernel khusus dengan dukungan penandatanganan untuk pipeline Anda (lihat modul kernel yang ditandatangani).
Enkripsi, TPM, dan pengukuran
dm-verity melindungi integritas, kerahasiaanAnda dapat membiarkan root tidak terenkripsi jika tidak mengandung rahasia apa pun dan rantai boot terlindungi. Jika Anda menggunakan berkas kunci dari root untuk membuka kunci volume lain, sebaiknya enkripsi berkas tersebut.
Dengan TPM 2.0, systemd-cryptenroll memungkinkan pengikatan kunci ke PCR 0,1,5,7 (firmware, opsi, GPT, status boot aman). Tambahkan rd.luks.options=LUKS_UUID=tpm2-device=auto dan pastikan untuk menyertakan dukungan TPM2 di initramfs. systemd-boot mengukur kernel.efi di PCR4, berguna untuk membatalkan kunci jika UKI atau cmdline-nya berubah.
Pembaruan dan model penerapan
Root baca-saja yang terverifikasi Tidak diperbarui dengan manajer paket dengan cara tradisionalIdealnya adalah membangun citra baru dengan alat seperti proyek Yocto dan menerbitkannya. systemd memiliki systemd-sysupdate dan systemd-repart untuk pengunduhan dan flashing citra yang kuat.
Strategi lain adalah Skema A/BAnda menyimpan dua root dan dua veritas. Salin root yang aktif ke root yang tidak aktif, terapkan perubahan, dan ulangi veritas. Beralih kembali saat boot berikutnya. Jika Anda menggunakan UKI, ingatlah untuk memperbarui hash root di baris perintah cmd atau membangun ulang UKI yang telah ditandatangani.
Untuk persistensi opsional, gunakan OverlayFS pada root yang terverifikasi dengan upper di tmpfs atau disk. Anda juga dapat meneruskan systemd.volatile=overlay untuk persistensi sementara. Flatpak memudahkan pemasangan aplikasi di /var dan /home tanpa menyentuh /.
Ada paket otomatis (misalnya verity-squash-root di AUR) yang membangun root squashfs dan tandatangani roothash dengan kernel dan initramfs, memungkinkan Anda memilih antara mode persisten atau sementara dan menyimpan rootfs terbaru sebagai cadangan. Catatan: menambahkan persistensi ke root yang terverifikasi memiliki kasus penggunaan yang terbatas; coba simpan data aplikasi di partisi terpisah.
Android: sistem-sebagai-root, AVB dan overlay vendor
Sejak Android 10, RootFS berhenti berjalan pada disk RAM dan terintegrasi dengan system.img. (sistem-sebagai-root). Perangkat yang diluncurkan dengan Android 10 selalu menggunakan skema ini dan memerlukan ramdisk untuk dm-linear. BOARD_BUILD_SYSTEM_ROOT_IMAGE disetel ke false dalam versi ini untuk membedakan antara penggunaan ramdisk dan pengaktifan system.img secara langsung.
Android 10 menggabungkan partisi dinamis dan inisiasi tahap pertama yang mengaktifkan partisi sistem logis; kernel tidak lagi memasangnya secara langsung. OTA khusus sistem memerlukan desain sistem sebagai root, yang wajib pada perangkat Android 10.
Tidak ada A/B, pisahkan pemulihan dari bootTidak seperti A/B, tidak ada cadangan boot_a/boot_b, jadi menghapus pemulihan di non-A/B dapat membuat Anda tanpa mode pemulihan jika pembaruan boot gagal.
Kernel memasang system.img ke /converity melalui dua jalur: vboot 1.0 (patch untuk kernel untuk mengurai metadata Android di /system dan memperoleh parameter dm-verity; cmdline mencakup root=/dev/dm-0, skip_initramfs dan init=/init dengan dm=…) atau vboot 2.0/AVB, di mana bootloader mengintegrasikan libavb, membaca deskriptor hashtree (dalam vbmeta atau sistem), membuat parameter dan meneruskannya ke kernel dalam cmdline, dengan dukungan FEC dan bendera seperti restart_on_corruption.
Dengan sistem-sebagai-root, jangan gunakan BOARD_ROOT_EXTRA_FOLDERS untuk folder root khusus perangkat: folder ini akan hilang saat mem-flash GSI. Tentukan mount spesifik di /mnt/vendor/ , yang dibuat oleh fs_mgr secara otomatis, dan merujuknya di fstab pada pohon perangkat.
Android memungkinkan overlay vendor dari /product/vendor_overlay/:init akan memasang subdirektori di /vendor yang memenuhi persyaratan konteks SELinux dan keberadaan /vendor/ Memerlukan CONFIG_OVERLAY_FS=yy, pada kernel lama, patch override_creds=off.
Implementasi tipikal: menginstal file yang telah dikompilasi sebelumnya di perangkat/ / /vendor_overlay/, tambahkan ke PRODUCT_COPY_FILES dengan find-copy-subdir-files ke $(TARGET_COPY_OUT_PRODUCT)/vendor_overlay, tentukan konteks di file_contexts untuk etc dan app (misalnya vendor_configs_file dan vendor_app_file), dan izinkan pemasangan pada konteks tersebut di init.te. Uji dengan atest vfs_mgr_vendor_overlay_test di userdebug.
Pemecahan masalah: pesan kerusakan dm-verity di Android
Pada perangkat dengan slot A/B, ubah slot atau Flashing vbmeta/boot tanpa konsistensi roothash Ini mungkin memicu peringatan: dm-verity corrupt, perangkat Anda tidak tepercaya. Perintah seperti fastboot flash –disable-verity –disable-verification vbmeta vbmeta.img menonaktifkan verifikasi, tetapi membiarkan sistem tanpa jaminan integritas.
Beberapa bootloader mendukung fastboot oem menonaktifkan_dm_verity dan kebalikannya, enable_dm_verity. Ini berfungsi pada beberapa model, tetapi tidak pada model lainnya; dan mungkin memerlukan kernel/magisk dengan flag yang disesuaikan. Gunakan dengan risiko Anda sendiri: tindakan yang bijaksana adalah menyelaraskan boot, vbmeta, dan sistem, tandatangani atau buat ulang pohon dan pastikan hash akar yang diharapkan cocok dengan yang dikonfigurasi.
Jika setelah peringatan Anda dapat terus menekan daya, sistem akan mulai, tetapi Anda tidak lagi memiliki rantai kepercayaan yang utuhUntuk menghapus pesan tanpa mengorbankan keamanan, pulihkan gambar asli yang ditandatangani atau bangun kembali/verifikasi vbmeta dengan hashtree yang benar, daripada menonaktifkan verity.
Platform i.MX dan OpenWrt
Pada i.MX6 (misalnya sabresd), konfigurasikan kernel dengan dukungan DM_VERITY dan FEC, buat pohon dengan veritysetup, simpan hash root dengan aman, dan berikan parameter yang sesuai di baris cmd atau integrasikan melalui initramfs dengan systemd-veritysetup. Jika Anda tidak menggunakan dm-crypt, Anda tidak memerlukan CAAM untuk verity; fokusnya adalah pada integritas.
Di OpenWrt dan di sistem Linux tertanam dengan OpenEmbedded, Ada upaya untuk mengintegrasikan dm-verity dan SELinux (Pekerjaan Bootlin direvisi dengan tujuan menyertakan dukungan). Ini adalah pilihan yang tepat: router dan peralatan jaringan mendapatkan manfaat dari root yang tidak dapat diubah, terverifikasi, dan terlindungi MAC.
Konstruksi pohon manual dan metadata (tampilan detail)
cryptsetup dapat membuat pohon untuk Anda, tetapi jika Anda lebih suka memahami formatnya, definisi baris tabel ringkas meliputi: nama pemetaan, perangkat data, ukuran blok data dan hash, ukuran gambar dalam blok, posisi hash_start (citra blok + 8 jika digabungkan), hash root, dan salt. Setelah menghasilkan lapisan yang digabungkan (dari atas ke bawah, kecuali lapisan 0), Anda menulis pohon tersebut ke disk.
Untuk mengemas semuanya, menyusun tabel dm-verity, menandatanganinya (khas RSA-2048) dan mengelompokkan tanda tangan+tabel dalam metadata dengan header versi dan angka ajaib. Kemudian, ia menggabungkan citra sistem, metadata verity, dan pohon hash. Di fstab, ia menandai fs_mgr sebagai verifikasi dan menempatkan kunci publik di /boot/verity_key untuk memvalidasi tanda tangan.
Optimalkan dengan Peningkatan kecepatan SHA-2 untuk CPU Anda dan sesuaikan read-ahead/prefetch_cluster. Pada perangkat keras ARM, ekstensi NEON SHA-2 (ARMv7) dan SHA-2 (ARMv8) secara signifikan mengurangi overhead verifikasi.
Dalam setiap penempatan, ingatlah bahwa nilai hash root harus dilindungi: baik dikompilasi ke dalam UKI yang ditandatangani, ke dalam partisi boot yang ditandatangani, atau divalidasi oleh bootloader menggunakan AVB. Semua yang ada setelah titik tersebut mewarisi kepercayaan tersebut.
Dengan semua hal di atas, dm-verity menjadi fondasi yang kokoh untuk sistem yang tidak dapat diubah, bergerak, dan tertanam, mendukung pembaruan transaksional, hamparan konfigurasi, dan model keamanan modern yang mengurangi permukaan serangan dan mencegah persistensi tanpa mengorbankan kinerja.


