🐧 Защита целостности данных на Ext4 и XFS с помощью dm-integrity и LUKS |

🐧 Защита целостности данных на Ext4 и XFS с помощью dm-integrity и LUKS

Мануал

В отличие от файловых систем COW, таких как BTRFS и ZFS, традиционные файловые системы Linux, такие как ext4 и XFS, не имеют возможности обнаружить медленную деградацию данных (также известную как bitrot), поскольку они не выполняют контрольное суммирование данных.

Однако при использовании этих файловых систем мы можем хранить и проверять информацию о целостности на уровне блоков, используя dm-integrity.

🐧 Как проверить и восстановить файловую систему EXT4 на Linux

В этом руководстве мы узнаем, как создавать устройства dm-integrity с помощью утилиты integritysetup, а при создании контейнеров LUKS – с помощью cryptsetup.

Имитация битрота на традиционных файловых системах Linux

Как мы уже говорили, традиционные файловые системы Linux, такие как ext4 и XFS, не имеют возможности проверять целостность данных и не способны обнаружить повреждения.

Давайте продемонстрируем это.

Для начала создадим файл с помощью dd, выделив 512 Мбайт пространства:

dd if=/dev/zero of=blkdevice bs=1M count=512

С помощью приведенной выше команды мы приказали dd считать 512 блоков по 1 Мбайт каждый с псевдоустройства /dev/zero и записать их в файл «blkdevice» в текущем рабочем каталоге.

Создав файл, мы можем использовать его как блочное устройство и построить на нем файловую систему.

В данном примере мы будем использовать ext4:

mkfs.ext4 blkdevice

Мы можем монтировать файловую систему так же, как если бы мы имели дело с любым другим «настоящим» блочным устройством:

sudo mount blkdevice /mnt

В этот момент мы записываем в файл случайные данные, позволяя им заполнить все свободное пространство:

sudo dd if=/dev/urandom of=/mnt/testfile

Мы должны получить результат, аналогичный приведенному ниже:

dd: writing to '/mnt/testfile': No space left on device 
976521+0 records in 
976520+0 records out 
499978240 bytes (500 MB, 477 MiB) copied, 3.95061 s, 127 MB/s

Теперь давайте получим контрольную сумму только что созданного файла:

sha256sum /mnt/testfile

В этом случае мы получаем следующий результат:

22eba8b04d389cd8f89ce055794823baa85c196e7ef81cc2465fb2a50e0f4f1e  /mnt/testfile

Мы принимаем это к сведению и размонтируем файловую систему:

sudo umount /mnt

Теперь, чтобы имитировать повреждение данных, или битрот, мы можем записывать случайные данные непосредственно на блочное устройство.

В примере ниже мы указываем, что хотим записать один выходной блок (count=1) размером 1 Мбайт (bs=1M) и начать запись со смещением на 15 выходных блоков того же размера от начала целевого устройства (seek=15).

Мы делаем это, чтобы гарантировать, что покроем область файловой системы, в которой находится «testfile»

Наконец, мы используем conv=notrunc, чтобы гарантировать, что наше «блочное устройство» не будет усечено:

dd if=/dev/urandom of=blkdevice seek=15 count=1 bs=1M conv=notrunc

В этот момент мы снова монтируем файловую систему и проверяем, изменилась ли контрольная сумма файла «testfile»:

sudo mount blkdevice /mnt
sha256sum /mnt/testfile

Вот результат, который мы получаем:

fb91581b5ed08eae9f3f8400d27bed0b4ad5a8fb4742f2fbabcc0ed409792160  /mnt/testfile

Как и ожидалось, контрольная сумма файла стала другой.

Изменение произошло бесшумно: традиционные файловые системы не отслеживают контрольные суммы данных, поэтому у них нет возможности заметить «битрот».

Вот здесь-то и может помочь dm-integrity.

Использование dm-integrity на одном диске

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

Однако возможность заметить повреждение все же может быть полезна, возможно, как признак возможного отказа диска.

Установка утилиты integritysetup

Чтобы использовать dm-integrity, нам нужно отформатировать наше устройство с помощью утилиты integritysetup.

Чтобы установить ее на Fedora и другие дистрибутивы семейства Red Hat, мы можем выполнить команду:

sudo dnf install integritysetup

На OpenSuse (Leap/Tumbleweed) мы можем использовать «zypper» для установки одноименного пакета:

sudo zypper in integritysetup

В дистрибутивах Debian и Debian-подобных утилита поставляется в пакете «cryptsetup-bin».

Мы можем установить его, выполнив команду:

sudo apt install cryptsetup-bin

В Archlinux утилита integritysetup входит в пакет «cryptsetup», доступный в репозитории «core»:

sudo pacman -S cryptsetup

Создание тома dm-integrity

Чтобы создать том dm-integrity, мы используем утилиту «integritysetup» для форматирования раздела/блочного устройства.

Следуя нашим предыдущим примерам, мы работаем с существующим файлом «blkdevice», рассматривая его как блочное устройство.

Чтобы отформатировать его, мы используем следующую команду:

sudo integritysetup format blkdevice

Нам будет предложено подтвердить, что мы хотим выполнить эту операцию, поскольку она перезапишет все данные на устройстве:

WARNING!
========
This will overwrite data on blkdevice irrevocably.

Are you sure? (Type 'yes' in capital letters): YES

После создания тома dm-integrity мы должны открыть его и задать для него имя device-mapper.

В данном руководстве мы используем «testdevice»:

sudo integritysetup open blkdevice testdevice

На этом этапе мы можем создать новую файловую систему на сопоставленном устройстве (/dev/mapper/testdevice):

sudo mkfs.ext4 /dev/mapper/testdevice

Давайте еще раз смонтируем файловую систему и создадим файл «testfile», заполнив его случайными данными:

sudo mount /dev/mapper/testdevice /mnt
sudo dd if=/dev/urandom of=/mnt/testfile

Как и раньше, мы следим за контрольной суммой файла:

sha256sum /mnt/testdevice
3b0d6256f991d4a352ed9181621813ba6b909b5cab0547a9554cac400074c3a5  /mnt/testdevice

Пришло время размонтировать файловую систему, закрыть устройство integritysetup и снова смоделировать повреждение данных:

sudo umount /mnt
sudo integritysetup close testdevice
dd if=/dev/urandom of=blkdevice seek=15 count=1 bs=1M conv=notrunc

В этот момент мы можем перемонтировать файловую систему и попытаться получить контрольную сумму файла:

sudo integritysetup open blkdevice testdevice
sudo mount /dev/mapper/testdevice /mnt
sha256sum /mnt/testfile

На этом этапе мы можем создать новую файловую систему на сопоставленном устройстве (/dev/mapper/testdevice):

sudo mkfs.ext4 /dev/mapper/testdevice

Давайте еще раз смонтируем файловую систему и создадим файл «testfile», заполнив его случайными данными:

sudo mount /dev/mapper/testdevice /mnt
sudo dd if=/dev/urandom of=/mnt/testfile

Как и раньше, мы следим за контрольной суммой файла:

sha256sum /mnt/testdevice
3b0d6256f991d4a352ed9181621813ba6b909b5cab0547a9554cac400074c3a5  /mnt/testdevice

Пришло время размонтировать файловую систему, закрыть устройство integritysetup и снова смоделировать повреждение данных:

sudo umount /mnt
sudo integritysetup close testdevice
dd if=/dev/urandom of=blkdevice seek=15 count=1 bs=1M conv=notrunc

В этот момент мы можем перемонтировать файловую систему и попытаться получить контрольную сумму файла:

sudo integritysetup open blkdevice testdevice
sudo mount /dev/mapper/testdevice /mnt
sha256sum /mnt/testfile

Как только мы пытаемся прочитать файл, мы получаем ошибку:

sha256sum: /mnt/testdevice: Input/output error

Что же случилось?

Поскольку мы теперь используем dm-integrity, повреждение данных было замечено, и файловая система вернула ошибку ввода/вывода.

Более подробную информацию об инциденте мы можем найти, заглянув в журналы ядра:

sudo dmesg | tail -5

Мы должны быть в состоянии прочитать что-то подобное:

[32942.115228] device-mapper: integrity: dm-8: Checksum failed at sector 0x5782 
[32942.117906] device-mapper: integrity: dm-8: Checksum failed at sector 0x5758 
[32942.119440] device-mapper: integrity: dm-8: Checksum failed at sector 0x5758 
[32942.119532] device-mapper: integrity: dm-8: Checksum failed at sector 0x5758 
[32942.119614] device-mapper: integrity: dm-8: Checksum failed at sector 0x5758

Использование dm-integrity с избыточностью данных

Как мы уже говорили, при использовании одного диска у нас нет возможности исправить повреждения, поскольку у нас есть только одна копия данных.

Ситуация меняется при использовании избыточности данных, например RAID1.

Давайте смоделируем это. Сначала создадим два файла: blkdevice1 и blkdevice2.

Мы будем использовать их в качестве блочных устройств:

dd if=/dev/zero of=blkdevice1 bs=1M count=512
dd if=/dev/zero of=blkdevice2 bs=1M count=512

На каждом из них мы создадим том dm-integrity.

Ниже мы используем опцию -q (сокращение от –batch-mode), чтобы пропустить запрос на подтверждение:

sudo integritysetup -q format blkdevice1
sudo integritysetup -q format blkdevice2

Давайте откроем их:

sudo integritysetup open blkdevice1 testdevice1
sudo integritysetup open blkdevice2 testdevice2

Теперь мы можем собрать устройства в RAID1 с помощью утилиты mdadm:

sudo mdadm --create /dev/md0 --level 1 --raid-devices=2 /dev/mapper/testdevice1 /dev/mapper/testdevice2

Мы создаем новый массив с помощью опции –create и указываем путь к устройству: /dev/md0.

Мы указываем уровень RAID с помощью опции –level, количество активных устройств с помощью –raid-devices и, наконец, передаем путь к блочным устройствам, которые мы хотим включить в массив.

Когда RAID собран, мы можем создать файловую систему на результирующем устройстве:

sudo mkfs.ext4 /dev/md0

Теперь смонтируем только что созданную файловую систему, запишем файл, заполненный случайными данными, и создадим повреждение данных на первом из двух дисков, входящих в массив:

sudo mount /dev/md0 /mnt
sudo dd if=/dev/urandom of=/mnt/testfile
dd if=/dev/urandom of=blkdevice1 seek=15 count=1 bs=1M conv=notrunc

Теперь мы можем выполнить очистку данных: записав «test» в файл /sys/block/md0/md/sync_action, мы заставим RAID прочитать все блоки данных на всех устройствах:

echo "check" | sudo tee /sys/block/md0/md/sync_action

Как мы уже видели, об ошибках целостности сообщается в журналах ядра.

Вот соответствующая часть:

[36735.559800] md: check of RAID array md0 
[36735.579268] device-mapper: integrity: dm-8: Checksum failed at sector 0x5b00 
[36735.579465] device-mapper: integrity: dm-8: Checksum failed at sector 0x5b80 
[36735.579508] device-mapper: integrity: dm-8: Checksum failed at sector 0x5980 
[36735.579522] device-mapper: integrity: dm-8: Checksum failed at sector 0x5a00 
[36735.579533] device-mapper: integrity: dm-8: Checksum failed at sector 0x5c80 
[36735.579544] device-mapper: integrity: dm-8: Checksum failed at sector 0x5900 
[36735.579606] device-mapper: integrity: dm-8: Checksum failed at sector 0x5a80 
[36735.579617] device-mapper: integrity: dm-8: Checksum failed at sector 0x5c00 
[36735.581460] device-mapper: integrity: dm-8: Checksum failed at sector 0x5780 
[36735.582377] device-mapper: integrity: dm-8: Checksum failed at sector 0x5e80 
[36737.803123] md: md0: check done.

В этот момент, если мы снова запустим data-scrub и проверим журналы ядра, мы не должны заметить никаких сообщений об ошибках:

[37245.887325] md: check of RAID array md0 
[37248.101670] md: md0: check done.

Благодаря dm-integrity повреждение данных было обнаружено и автоматически исправлено.

Использование dm-integrity с LUKS

LUKS (Linux Unified Key Setup) – это стандарт для шифрования дисков в Linux.

При форматировании необработанного блочного устройства или раздела как контейнера LUKS мы можем указать, что хотим использовать dm-integrity без использования integritysetup.

Для этого достаточно вызвать cryptsetup с опцией –integrity и передать в качестве аргумента алгоритм целостности, который мы хотим использовать:

sudo cryptsetup luksFormat --type luks2 --integrity hmac-sha256 blkdevice1

Заключение

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

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

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

В этой статье, по понятным причинам, мы упомянули не все возможные опции, которые можно использовать для тонкой настройки dm-integrity. Чтобы узнать об этом больше, пожалуйста, загляните на manpage integritysetup и в соответствующую документацию.

 

Пожалуйста, не спамьте и никого не оскорбляйте. Это поле для комментариев, а не спамбокс. Рекламные ссылки не индексируются!
Добавить комментарий