How to Configure dm-verity Block Device Integrity Verification in Ubuntu Using veritysetup

Protecting operating system partitions from unauthorized rootkits, persistent offline tampering, and malicious firmware implants requires cryptographically enforced block-level integrity. While standard filesystem permissions defend against unprivileged processes, they provide zero protection if an adversary boots an alternative live OS and modifies system binaries on disk. The Linux kernel’s Device Mapper Verity (dm-verity) target resolves this vulnerability by computing transparent, real-time cryptographic hashes across every storage block. Using a Merkle hash tree anchored to a single root hash, the kernel validates each sector as it is read into RAM. If even a single byte is altered, the I/O read fails instantly. In Ubuntu, system administrators and embedded security engineers configure dm-verity using veritysetup.

Understanding dm-verity and Merkle Hash Trees

The dm-verity architecture operates between the raw block device and the filesystem (such as ext4 or squashfs):

  • Data Device: The primary block device containing the read-only operating system filesystem (e.g. /dev/sdb1 or a raw image file).
  • Hash Device: A dedicated block partition or auxiliary file that stores the multi-tiered Merkle tree containing SHA-256 hashes of every 4096-byte data block.
  • Root Hash: A single 32-byte cryptographic digest that represents the cryptographic top of the Merkle tree. Providing this root hash to the kernel at boot binds the entire filesystem’s validity. If any data block is modified, its hash changes, propagating an invalid checksum up to the root hash.
  • Kernel Enforcement: Integrated directly into the Linux kernel block layer. Reads that pass verification are served transparently at native hardware speeds; modified blocks trigger an I/O error (EIO) or panic the kernel based on restart policies.

Installing Cryptsetup and Verity Utilities on Ubuntu

The veritysetup binary is distributed as part of the standard cryptsetup-bin package in Ubuntu:

sudo apt update && sudo apt install -y cryptsetup-bin

Ensure the dm-verity kernel module is active in the system:

sudo modprobe dm-verity
lsmod | grep dm_verity

Formatting a Block Device with dm-verity

To establish block integrity, first prepare a clean read-only filesystem on your data device. For testing, create an ext4 filesystem on a dedicated partition (or loopback image):

# Create data and hash images for demonstration
dd if=/dev/zero of=rootfs.img bs=1M count=500
mkfs.ext4 -F rootfs.img

# Create dedicated hash image
dd if=/dev/zero of=hash.img bs=1M count=50

Format the hash device and generate the Merkle tree using veritysetup format:

veritysetup format rootfs.img hash.img

The command computes the Merkle tree and displays crucial cryptographic parameters:

VERITY header information for hash.img
UUID:                   12345678-abcd-ef01-2345-6789abcdef01
Hash type:              1
Data blocks:            128000
Data block size:        4096
Hash block size:        4096
Hash algorithm:         sha256
Salt:                   a1b2c3d4e5f6...
Root hash:              e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

Crucial: Record the Root hash string. This value is required to mount and verify the volume.

Activating and Mounting the Verified Device

Map the verified block device to the device mapper using veritysetup open:

sudo veritysetup open rootfs.img verified_root hash.img e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855

Once opened, the mapped device becomes available under /dev/mapper/verified_root. Mount it as a read-only filesystem:

sudo mkdir -p /mnt/secure_root
sudo mount -o ro /dev/mapper/verified_root /mnt/secure_root

Verify the mount status:

df -h /mnt/secure_root
sudo veritysetup status verified_root

Simulating Tamper Detection and Block Corruption

To verify that dm-verity detects unauthorised modifications, deliberately corrupt a single byte on the raw underlying data image while mounted:

# Overwrite a byte inside the underlying raw data block
printf '\xff' | dd of=rootfs.img bs=1 seek=1048576 count=1 conv=notrunc

Attempt to read or compute a checksum across the mounted filesystem:

cat /mnt/secure_root/* > /dev/null

Check the kernel system logs:

sudo dmesg | grep -i verity

The kernel flags the corrupted block immediately:

device-mapper: verity: 7:0: metadata block 256 is corrupted
Buffer I/O error on dev dm-0, logical block 256, async page read

The read call is aborted with an Input/Output error, preventing compromised code from executing in memory.

Closing the Verified Device

When unmounting and closing the verified block mapper:

sudo umount /mnt/secure_root
sudo veritysetup close verified_root

Deploying dm-verity with veritysetup establishes an immutable, cryptographic root of trust for Ubuntu systems, securing appliances and critical servers against persistent offline disk tampering.

Get the best tech tips delivered straight to your inbox.

Join thousands of readers mastering Apple, Google, Microsoft, and Linux.