Добавить в корзинуПозвонить
Найти в Дзене
File Energy

dm-verity и dm-integrity как два разных ответа на один вопрос о доверии к диску в Linux

Когда говорят о целостности данных на диске, обычно имеют в виду что-то одно: данные либо в порядке, либо нет. Но за этой простой формулировкой скрываются два принципиально разных вопроса. Первый: "Не изменились ли данные с момента, когда мы их записали?" Второй: "Не были ли они подменены кем-то намеренно?" Звучит похоже, но решения требуют совершенно разной архитектуры. Именно поэтому в Linux существуют два отдельных механизма устройственного отображения, dm-verity и dm-integrity, и путаница между ними стоит дорого, особенно когда речь заходит о безопасности продакшен-систем. Оба инструмента живут в подсистеме device mapper ядра Linux. Оба работают на уровне блочного устройства, прозрачно для файловой системы, которая находится сверху. Но на этом сходство и заканчивается. dm-verity появился в ядре Linux версии 3.4 в 2012 году. Его история началась в Google: именно команда Chromium OS разработала этот механизм, чтобы гарантировать, что системный раздел устройства не изменился с момента
Оглавление

Когда говорят о целостности данных на диске, обычно имеют в виду что-то одно: данные либо в порядке, либо нет. Но за этой простой формулировкой скрываются два принципиально разных вопроса. Первый: "Не изменились ли данные с момента, когда мы их записали?" Второй: "Не были ли они подменены кем-то намеренно?" Звучит похоже, но решения требуют совершенно разной архитектуры. Именно поэтому в Linux существуют два отдельных механизма устройственного отображения, dm-verity и dm-integrity, и путаница между ними стоит дорого, особенно когда речь заходит о безопасности продакшен-систем.

Оба инструмента живут в подсистеме device mapper ядра Linux. Оба работают на уровне блочного устройства, прозрачно для файловой системы, которая находится сверху. Но на этом сходство и заканчивается.

Как dm-verity выстраивает цепочку доверия от загрузчика до файла

dm-verity появился в ядре Linux версии 3.4 в 2012 году. Его история началась в Google: именно команда Chromium OS разработала этот механизм, чтобы гарантировать, что системный раздел устройства не изменился с момента сборки образа. Android использует dm-verity для защиты системного раздела начиная с версии 4.4, то есть сегодня этот механизм работает на миллиардах устройств по всему миру.

Идея проста и элегантна. При создании защищённого образа утилита veritysetup строит дерево хешей, где листовые узлы содержат хеши каждого блока данных, а промежуточные узлы хешируют своих потомков. Вершина дерева, корневой хеш, становится единственным значением, которое нужно защитить и проверить. Если хоть один байт в любом блоке данных будет изменён, корневой хеш окажется другим, и ядро немедленно вернёт ошибку ввода-вывода при попытке прочитать затронутый блок.

Создание защищённого раздела выглядит так:

veritysetup format /dev/sda1 /dev/sda2

Первый аргумент это раздел с данными, второй это раздел для хранения дерева хешей. Утилита выводит корневой хеш, который нужно сохранить в подписанном загрузчиком параметре ядра. Активация устройства с проверкой:

veritysetup open /dev/sda1 verified_root /dev/sda2 \
<root_hash>

После этого /dev/mapper/verified_root ведёт себя как обычное блочное устройство, но любое обращение к блоку, чей хеш не совпадает с ожидаемым, завершается ошибкой. Проверка происходит лениво, только при первом чтении блока в страничный кэш, что даёт минимальные накладные расходы. Для 10 гигабайт данных дерево хешей занимает около 81 мегабайта.

Критически важная деталь: dm-verity работает только с устройствами в режиме чтения. Записать что-либо на защищённый раздел невозможно физически. Это не ограничение реализации, а архитектурное решение. Если данные неизменны, их целостность можно гарантировать навсегда. Как только появляется запись, гарантия исчезает.

Что dm-verity не умеет и почему это честно

Честно говоря, dm-verity намеренно не решает ряд задач. Он не защищает от физического вскрытия устройства и замены чипа хранилища, если при этом обновить и дерево хешей. Он не обеспечивает конфиденциальность: данные на диске хранятся в открытом виде, и любой, кто получит физический доступ, сможет их прочитать. Он не защищает от атак во время работы системы, если злоумышленник уже получил права root.

Всё это не недостатки, а честные границы инструмента. dm-verity решает конкретную задачу: доказать, что загруженная система является именно той, которую собрали и подписали. Ни больше ни меньше. Проверить статус работающего устройства:

veritysetup status verified_root

Вывод покажет алгоритм хеширования, размер блока, корневой хеш и текущее состояние. Если хоть один блок вернул несовпадение хеша, это отразится в счётчике ошибок.

Зачем нужен dm-integrity, если уже есть dm-verity

dm-integrity отвечает на другой вопрос: что происходит с данными, которые система активно пишет и читает прямо сейчас? Тихая порча данных, silent data corruption, это явление, о котором мало говорят, но которое встречается куда чаще, чем принято думать. Контроллер диска может вернуть устаревшие данные после сбоя питания. Бит может перевернуться в оперативной памяти во время передачи. Прошивка накопителя может молча записать не туда.

dm-integrity хранит тег целостности для каждого сектора и проверяет его при каждом чтении. В отличие от dm-verity, это устройство поддерживает запись. Именно здесь начинается вся сложность.

Инициализация устройства с внутренним хешированием на базе crc32c:

integritysetup format /dev/sdb --integrity crc32c
integritysetup open /dev/sdb integrity_disk --integrity crc32c

Для криптографически стойкой защиты с использованием HMAC:

integritysetup format /dev/sdb \
--integrity hmac-sha256 \
--integrity-key-size 32 \
--integrity-key-file /etc/integrity.key

integritysetup open /dev/sdb integrity_disk \
--integrity hmac-sha256 \
--integrity-key-size 32 \
--integrity-key-file /etc/integrity.key

Проверить состояние активного устройства:

integritysetup status integrity_disk

Режимы журналирования и настоящая цена надёжности

Запись с контролем целостности сложнее, чем простая запись. Если данные записаны, а тег целостности ещё нет, и в этот момент пропадает питание, при следующей загрузке устройство обнаружит несовпадение и вернёт ошибку, хотя данные физически на месте. Это ложная тревога, которая может быть катастрофой для базы данных.

Чтобы решить эту проблему, dm-integrity предлагает три режима работы. В журнальном режиме, который является режимом по умолчанию, данные и теги сначала записываются в журнал, потом атомарно применяются. Это гарантирует согласованность, но каждая запись происходит дважды, что снижает пропускную способность записи примерно вдвое. В режиме битовой карты, доступном с ядра 5.2, ведётся карта регионов, для которых теги ещё не синхронизированы. После сбоя эти регионы пересчитываются. Быстрее, но без гарантии обнаружения порчи именно в момент сбоя. Режим без журнала даёт нативную скорость, но не является отказоустойчивым.

Активация в режиме битовой карты для SSD, где важна долговечность и скорость:

integritysetup open /dev/sdb integrity_disk \
--integrity crc32c \
--integrity-bitmap-mode

На практике журнальный режим снижает скорость последовательной записи примерно на 60 процентов по сравнению с устройством без dm-integrity. Режим битовой карты снижает примерно на 10 процентов. Для SSD битовая карта также вдвое уменьшает количество операций записи, что напрямую продлевает срок службы накопителя.

Связка dm-integrity и dm-crypt как аутентифицированное шифрование

По-настоящему интересная история начинается, когда dm-integrity работает не сам по себе, а в паре с dm-crypt. В этой конфигурации dm-crypt генерирует теги целостности на основе HMAC и передаёт их в dm-integrity через механизм bio_integrity_payload. Результат - аутентифицированное шифрование на уровне блочного устройства: данные зашифрованы, и любая попытка их подменить будет обнаружена немедленно.

LUKS2 поддерживает эту связку напрямую через cryptsetup. Создать том с аутентифицированным шифрованием:

cryptsetup luksFormat --type luks2 \
--cipher aes-gcm-random \
--integrity aead \
/dev/sdc

cryptsetup open /dev/sdc encrypted_integrity

Просмотреть параметры существующего тома:

cryptsetup luksDump /dev/sdc

Разница между этой связкой и простым dm-crypt принципиальна. Классическое шифрование защищает конфиденциальность, но не целостность: злоумышленник с физическим доступом может изменить зашифрованные блоки, и расшифровка вернёт мусор вместо ошибки. С dm-integrity любая модификация зашифрованных данных возвращает явную ошибку ввода-вывода, а не тихо испорченные данные.

Когда что выбирать и как они дополняют друг друга

Выбор между двумя инструментами определяется не тем, какой из них "лучше", а тем, какую угрозу нужно закрыть.

dm-verity подходит, когда раздел создаётся один раз и должен оставаться неизменным навсегда: системный раздел встраиваемого устройства, образ контейнера, read-only корневая файловая система сервера. Он встраивается в цепочку доверия от загрузчика через Secure Boot к подписанному ядру и подписанному образу. Любое отклонение от эталона обнаруживается до того, как системой успеют воспользоваться.

dm-integrity решает задачи там, где данные живут и изменяются: базы данных, файловые хранилища, любые системы, где тихая порча данных хуже явной ошибки. В самостоятельном режиме с crc32c он защищает от случайной физической порчи. В связке с dm-crypt и HMAC он даёт полноценную защиту от целенаправленной подмены зашифрованных данных.

Разумный подход для сервера с чувствительными данными: использовать оба инструмента в своих зонах ответственности. Системный раздел защищается через dm-verity с корневым хешем в подписанном образе ядра. Раздел данных защищается через LUKS2 с aead, что внутри означает именно связку dm-crypt и dm-integrity. Первый инструмент следит за тем, что система не тронута. Второй следит за тем, что данные не испорчены и не подменены в процессе работы.

Люди, впервые сталкивающиеся с этой темой, нередко спрашивают: зачем два инструмента, если можно сделать один, который умеет всё? Ответ прост: инструмент, который пытается делать всё сразу, обычно не делает ни одну вещь достаточно хорошо. dm-verity быстр именно потому, что никогда не пишет. dm-integrity гибок именно потому, что решает только задачу тегирования секторов, не занимаясь шифрованием и деревьями хешей одновременно. Эта специализация, а не универсальность, и делает их надёжными инструментами для продакшена.

https://fileenergy.com/linux