Мне бы хотелось иметь возможность собирать и проверять контрольные суммы для больших наборов файлов, обычно вложенных в сложную иерархию каталогов.
Нужна ли контрольная сумма каждому файлу? Есть ли способы использовать существующую структуру каталогов, чтобы, скажем, проверить только узел в дереве файлов, а не обязательно каждый файл внутри?
решение1
Самый эффективный способ использования контрольных сумм — заставить компьютер делать все это. Используйте файловую систему, такую как ZFS, которая проверяет контрольные суммы (на самом деле она использует хэши, которые сильнее контрольной суммы) всех данных при их записи и проверяет их каждый раз при чтении данных. Конечно, недостатком является то, что ZFS не знает, когда удаление или перезапись файла является ошибкой, а когда это нормальная операция, но поскольку ZFS использует семантику копирования при записи для всего, вы можете использовать ее функцию моментальных снимков, чтобы снизить риск.
ZFS также может автоматически восстанавливать данные, не прошедшие проверку хэша, используя любую настроенную вами избыточность, будь то четность в стиле raid5, зеркала дисков или дубликаты копий (добавьте свойство copys=N к любой файловой системе ZFS, и она будет хранить N копий любых записанных вами данных). Она также сохраняет хэши в дереве Меркла, где хэш-значение файла зависит от хэшей блоков, хэш записи каталога зависит от хэш-значений файлов и каталогов, которые она содержит, хэш файловой системы зависит от хэша корневого каталога и т. д.
Независимо от того, какое решение вы выберете, вы неизбежно обнаружите, что процесс ограничен скоростью ваших дисков, а не скоростью вашего процессора.
Кроме того, не забывайте учитывать BER ваших дисков. В конце концов, это всего лишь пластины вращающейся ржавчины. Диск потребительского уровня имеет частоту ошибок 1 неправильно прочитанный бит на каждые 10^14 прочитанных бит, что составляет 1 бит на каждые 11 прочитанных вами терабайт. Если у вас есть набор данных объемом 11 терабайт и вы вычисляете хэш каждого файла в нем, вы неправильно вычислите одну из этих контрольных сумм и навсегда повредите один блок одного из файлов в наборе данных. Однако ZFS знает хэш каждого блока, который она записала на каждый диск в вашем пуле, и, следовательно, знает, какой блок был потерян. Затем она может использовать избыточность (четность, зеркала или дополнительные копии) в вашем пуле, чтобы перезаписать данные в этом блоке с правильными значениями. Эти функции безопасности также применяются, когда вы используете отправку или получение zfs для копирования данных из вашей основной системы в резервные копии.
Однако Бен поднимает в комментариях хорошую тему. ZFS не раскрывает пользователю ни одного из вычисляемых ею хэш-значений, поэтому данные, которые поступают в систему ZFS или покидают ее, должны сопровождаться хэшами. Мне нравится, как это делает Internet Archive с помощью xml-файла, который сопровождает каждый элемент в архиве. Смотритеhttps://ia801605.us.archive.org/13/items/fakebook_the-firehouse-jazz-band-fake-book/fakebook_the-firehouse-jazz-band-fake-book_files.xmlВ качестве примера.
решение2
Может быть, сейчас самое время поднять этот вопрос?BagIt. Это очень простой, но мощный формат упаковки файлов, предназначенный для архивирования, долгосрочного хранения и передачи цифровых объектов. Среди пользователей — Библиотека Конгресса и Калифорнийская цифровая библиотека.
Инструмент BagIt (они существуют на нескольких языках программирования) помещает ваши файлы в определенную структуру каталогов и выполняет контрольное суммирование/хеширование за вас. Вот и все.
PS: Конечно, инструменты BagIt также могут проверять сумки по включенным контрольным суммам/хэшам, и вы можете добавлять некоторые метаданные к сумкам. Но это так сложно, как только могут быть сумки.
решение3
Я бы сгенерировал контрольную сумму для каждого файла. Контрольные суммы очень малы, а генерация контрольной суммы для всего каталога потребовала бы обработки каждого файла (по крайней мере, если вы не говорите о контрольной сумме каталога, сделанной только из записей каталога — я бы сделал и их, чтобы гарантировать, что никакие данные не будут удалены).
Предположим, у вас есть одна контрольная сумма для всего архива. Вы знаете, что данные повреждены, но вы не знаете, является ли это только одним файлом, и, что более важно, какой из них. Наличие отдельных контрольных сумм дает вам большую гибкость. Вы можете обнаружить один файл, который поврежден, и заменить его файлом из другой резервной копии (которая, в свою очередь, может иметь поврежденный другой файл).
Таким образом, ваши данные с большей вероятностью сохранятся.
решение4
Я просмотрел ответы, и хотя мне нравится идея положиться на ZFS для обработки ошибок уровня данных, все еще остается проблема изменения файлов, как по ошибке, так и злонамеренно. ZFS не защитит вас в этом случае, и, как кто-то еще упомянул, он не даст вам видимый пользователем "хэш", который можно будет сохранить где-то еще для внешней проверки.
Есть приложение Linux под названием TripWire, которое широко использовалось для мониторинга исполняемых файлов системы, чтобы проверить, не были ли они изменены после атаки. Этот проект, по-видимому, сейчас заброшен, но есть новый, который называется AIDE (Advanced Intrusion Detection Environment)
, рекомендуемый на ServerFault:
https://serverfault.com/questions/62539/tripwire-and-alternatives
При установке он будет запускаться каждые x минут, настраиваемый пользователем, и будет проверять все указанные вами папки на наличие изменений в файлах. Он должен запуститься один раз, чтобы вычислить все хэши файлов, а затем после этого он проверяет все хэши с текущим файлом и убеждается, что они все еще одинаковы. Вы можете указать, какой тип хеша или комбинацию хешей использовать (я бы не рекомендовал ничего слабее SHA-256), какие атрибуты файла использовать (содержимое, размер, измененная временная метка и т. д.), частоту, с которой он будет проверять, как/где хранить базу данных хешей и т. д.
Некоторые могут посчитать это излишеством, но в зависимости от требований ОП, это может дать ему больше уверенности в том, что хранимые им данные останутся прежними по истечении определенного периода времени.