Как известно, если неприятность может произойти, то она обязательно произойдёт. Наверное, у каждого были случаи, когда случайно был стёрт свежий важный файл, или случайно был выделен и уничтожен текст в текстовом редакторе.
Если вы — хостер или владелец сайта, то, наверное, сталкивались со взломами пользовательских аккаунтов или своего сайта. В таких случаях важно восстановить хронологию, найти способ проникновения и уязвимость, которую использовал злоумышленник.
Для решения подобных проблем прекрасно подойдёт файловая система NILFS2.
Она присутствует в ядре Linux, начиная с версии 2.6.30.
Особенностью данной файловой системы является то, что она подобна системе контроля версий: вы всегда можете откатить состояние системы назад и посмотреть на то, какой она была некоторое время назад.
Для обеспечения этого функционала вам не нужно настраивать Cron-скрипты, делать снепшоты и т.п. Файловая система NILFS2 делает это всё сама. Она никогда не переписывает старые данные и всегда пишет в новые области диска, если достаточно свободного дискового пространства. В полном соответствии с принципом Copy-on-Write.
Фактически, любое изменение файла влечёт за собой автоматическое создание нового снимка файловой системы, поэтому вы можете использовать эту ФС как машину времени и отматывать назад состояние файлов.
История
NILFS2 была разработана в недрах Nippon Telegraph and Telephone Corporation, фактически, государственной (оно имеет контрольный пакет) и крупнейшей телекоммуникационной компании Японии. А конкретнее в лаборатории CyberSpace Laboratories под руководством Ryusuke Konishi.
Для чего конкрентно она разрабатывалась — неизвестно, однако, можно предположить, что подобная ФС, с её функционалом “машины времени” идеальна для хранения данных, в которых может возникнуть желание поковыряться спецслужбам, чтобы повторно проиграть всю картину СМС, емейлов и т.п…
NILFS2 также, потенциально, очень ценный инструмент для служб внутренней безопасности, так как позволяет восстановить все удалённые письма в почтовой базе данных, вскрыть косяки сотрудников, которые впоследствии могут попытаться их замаскировать, удалив или изменив свои файлы.
Как можно отследить всю историю переписки
В Linux на серверах (а именно туда и стоит ставить NILFS2 для целей внутренней безопасности) для хранения почтовых сообщений очень часто используется файловый способ хранения е-мейлов. Так называемый формат Maildir. Достаточно поставить Courier Mail Server и сконфигурировать хранение писем в Maildir. Другой формат mbox представляет из себя большой текстовый файл, который легко парсится на отдельные сообщения.
Если же почтовый сервер использует базу данных, то NILFS2 даст возможность восстановить точный хронометраж изменений базы и возможность восстановить базу на любой из этих моментов. А дальше нужно воспользоваться инструментами БД, чтобы посмотреть что в ней было на тот момент времени…
Если же почтовый сервер использует базу данных, то NILFS2 даст возможность восстановить точный хронометраж изменений базы и возможность восстановить базу на любой из этих моментов. А дальше нужно воспользоваться инструментами БД, чтобы посмотреть что в ней было на тот момент времени…
Однако что-то пошло не так. То ли правительство Японии передумало за всеми следить (а-ля принцип Яровой), то ли производительность NILFS2 на традиционных HDD оказалась ниже плинтуса, и NILFS2 была выпущена под GPL лицензией и очень быстро вошла в ядро Linux, так как особых претензий к коду, написанному высококвалифицированными японцами, у разработчиков ядра Linux не было.
На что похожа NILFS2?
С точки зрения использования: на систему контроля версий SVN. Каждый чекпоинт ФС — это коммит, который делается автоматически без ведома пользователя при любом изменении: будь то удаление, изменение содержимого файла или прав доступа. Каждый коммит имеет номер, который линейно увеличивается.
С точки зрения программиста: на циклический буфер. Файловая система копит изменения и записывает их в кусок равный примерно 8 МБ (2048 * 4096, где 2048 — число элементов в блоке, а 4096 — размер страницы памяти). Весь диск поделен на такие чанки. Запись идёт последовательно. Когда заканчивается свободное место, то самые старые снимки удаляются, а чанки перезаписываются.
Основные плюшки NILFS2
- Версионность!!!
- Процедура восстановления ФС после сбоя элементарна: при загрузке ищется последний чанк, имеющий верную контрольную сумму, и на него устанавливается суперблок. Это практически моментальная операция.
- В связи с тем, что запись всегда идёт линейно, то:
- может показывать хорошие результаты при работе на SSD, с медленной случайной записью.
- NILFS2 экономит ресурс SSD, так как почти отсутствует фактор мультипликации записи.
Точнее говоря, он не более 2.Дело в том, что при циклической перезаписи всего диска NILFS2 будет переносит неизменяемые данные в новые куски (чанки).
Если мы имеем на диске 10% неизменяющихся данных, то мы получим 10% прирост записи при 1 полной перезаписи. Ну и 50% прирост при 50% заполненности устройства на 1 полную перезапись диска.
Максимальный коэффициент усиления записи 2. Это очень мало с учётом того, что всё пишется последовательно. В целом мультипликация записи будет меньше, чем у обычной фрагментированной ФС с сектором 4096 байт. (На мысли наведено комментом).
- Потенциальная простота реализации репликации на удалённую NILFS2 ФС
NILFS2 для /home
В Unix-подобных ОС, как правило, присутствует папка /home, в которой хранятся данные пользователей. Различные программы сохраняют в этой папке свои настройки, относящиеся к конкретному пользователю.
А кто, как не пользователи, чаще всего косячит? Поэтому, как говорится, сам Бог велел использовать на /home NILFS2.
Тем более, что с повсеместным распостранением SSD мы теперь можем не волноваться насчёт сильной просадки при использовании CoW файловых систем.
Да, снимки ФС (снепшоты) мы можем сколько угодно часто создавать и в ZFS и BTRFS, но всегда есть риск, что потерянное изменение файла окажется между снимками. И снимки ещё нужно администрировать: удалять старые. В NILFS2 всё это происходит автоматически, буквально каждые несколько секунд.
Я создал логический том с помощью lvcreate (в группе томов nvme, тонкий пул thin). Я рекомендую создавать именно на томе lvm, так как в последствии он может быть легко расширен. Рекомендую иметь 50% свободного места на диске с NILFS2 для приличной глубины версионности.
lvcreate -V10G -T nvme/thin -n home
и отформатировал его в NILFS2:
mkfs.nilfs2 -L nvme_home /dev/nvme/home
mkfs.nilfs2 (nilfs-utils 2.1.5)
Start writing file system initial data to the device
Blocksize:4096 Device:/dev/nvme/home1 Device Size:10737418240
File system initialization succeeded !!
После этого нужно скопировать все данные с текущего /home.
Я это сделал сразу после загрузки компьютера, до входа в свой аккаунт, из-под пользователя root. Если бы я зашёл под своим пользователем, то какие-нибудь программы открыли бы сокеты и файлы в папке моего пользователя /home/user, что сделало бы чистое копирование затруднительным. Как известно, домашняя папка для пользователя root обычно находится по пути /root, поэтому на разделе /home никакие файлы не откроются.
mkdir /mnt/newhome
mount -t nilfs2 /dev/nvme/home /mnt/newhome
cp -a /home/. /mnt/newhome
По поводу последней строки см. статью.
Далее правим /etc/fstab, в которой монтируется файловая система для /home, на
/dev/disk/by-label/nvme_home /home nilfs2 noatime 0 0
Опция
noatime
нужна для повышения производительности, чтобы при каждом обращении к файлам не менялось atime. Далее перезагружаемся.Виды снимков в NILFS2.
Обычный снимок без иммунитета к удалению называется чекпоинт (checkpoint или точка восстановления).
Снимок с защитой от автоудаления называется снепшот (snapshot), далее просто снимок.
Просмотр чекпойтов делается с помощью команды lscp
Просмотр снимков (снепшотов) lscp -s
Мы можем и сами создавать снимки и чекпоиты в любой момент с помощью:
mkcp [-s] устройство
Восстанавливаем данные.
NILFS позволяет нам монтировать сколько угодно старых снимков параллельно с работой с основной ветвью ФС. Но только в режиме для чтения.
Устроено всё так. Обычные чекпоинты, которые делает NILFS2, могут быть ей автоматически удалены в любой момент (когда кончится дисковое пространство или по правилам nilfs_cleanerd), поэтому перед монтажом мы должны перевести чекпоинт в снепшот или, по-русски говоря, зафиксировать снимок.
chcp ss номер_чекпоинта
После этого мы может примонтировать снимок, например, так:
mount -t nilfs2 -r -o cp=номер_чекпоинта /dev/nvme/home /mnt/nilfs/номер_чекпоинта
После чего мы копируем восстанавливаемые файлы из снимка в /home.
А впоследствии снимаем флаг неудалимости со снимка, чтобы в будущем автоматический сборщик мусора мог удалить устаревшие данные:
chcp cp номер_чекпоинта
Утилиты для NILFS2
А вот с этим беда. Да, конечно, мы можем создавать ФС, менять её размер он-лайн, просматривать список чейпоинтов, делать и удалять их. Пакет nilfs2-utils предоставляет минимальный джентельменский набор.
Поскольку NTT свернула финансирование, то нет быстрых низкоуровневых утилит, которые позволяют выводить историю изменений файлов, делать diff между снимками.
Моя утилита n2u
Чтобы заполнить этот вакуум я написал свою утилиту n2u, которая умеет выводить историю изменений конкретного файла/директории:
n2u log filename
Вывод примерно такой:
CHECKPOINT DATE TIME TYPE SIZE MODE
1787552 2019-11-24 22:08:00 first 7079 cp
1792659 2019-11-25 23:09:05 changed 7081 cp
Она работает довольно быстро для избранного способа реализации: ищет различия между файлами методом бисекции, быстро монтируя и сравнивая файл/директорию в разных снимках.
Можно задать диапазон чекпоинтов с помощью ключа
-cp CP1:CP2
или -cp {YEAR-MM-DD}:{YEAR-MM-DD}
.Также можно посмотреть разницу между чекпоинтами для определённого файла или директории:
n2u diff -r cp1:cp2 filename
Можно вывести всю хронологию изменений: все разницы между чекпоинтами определенного файла/директории:
n2u blame [-r cp1:cp2] filename
Интервал дат в в этой команде также поддерживается.
Клич к разработчикам
На Хабре много спецов. Прошу, допилите NILFS2. Сделайте репликацию, низкоуровневый быстрый diff между ревизиями, reflink и другие плюшки!
Ссылки
Официальный сайт NILFS.
Репозитории:
NILFS2.
NILFS2 утилиты и модули.
Рассылки:
Е-мейл рассылка разработчиков NILFS2. Идентификатор для подписки linux-nilfs.
Архив рассылки.
Руководство по настройке nilfs_cleanerd.
Сравнительные тесты производительности EXT4, Btrfs, XFS & NILFS2.
Благодарности:
- Разработчикам NILFS2: Ryusuke Konishi, Koji Sato, Naruhiko Kamimura, Seiji Kihara, Yoshiji Amagai, Hisashi Hifumi and Satoshi Moriai. Other major contributors are: Andreas Rohner, Dan McGee, David Arendt, David Smid, dexen deVries, Dmitry Smirnov, Eric Sandeen, Jiro SEKIBA, Matteo Frigo, Hitoshi Mitake, Takashi Iwai, Vyacheslav Dubeyko.
- Компаниям Amblin Entertainment и Universal Pictures за чудесную серию фильмов «Назад в будущее». Первая картинка поста взята из фильма «Назад в будущее — 3».
- Компании RUVDS за поддержку и возможность публикации в своем блоге на Хабре.
P.S. Замеченные ошибки направляйте в личку. Повышаю за это карму.
Вы можете поэкспериментировать с NILFS2, заказав виртуальную машину у RUVDS по купону ниже. Для всех новых клиентов бесплатный тестовый период 3 дня.