NILFS2 — пуленепробиваемая файловая система для /home
Как известно, если неприятность может произойти, то она обязательно произойдёт. Наверное, у каждого были случаи, когда случайно был стёрт свежий важный файл, или случайно был выделен и уничтожен текст в текстовым редакторе.
Если вы — хостер или владелец сайта, то, наверное, сталкивались со взломами пользовательских аккаунтов или своего сайта. В таких случаях важно восстановить хронологию, найти способ проникновения и уязвимость, которую использовал злоумышленник.
Для решения подобных проблем прекрасно подойдёт файловая система NILFS2.
Она присутствует в ядре Linux, начиная с версии 2.6.30.
Особенностью данной файловой системы является то, что она подобна системе контроля версий: вы всегда можете откатить состояние системы назад и посмотреть на то, какой она была некоторое время назад.
Для обеспечения этого функционала вам не нужно настраивать Cron-скрипты, делать снепшоты и т.п. Файловая система NILFS2 делает это всё сама. Она никогда не переписывает старые данные и всегда пишет в новые области диска, если достаточно свободного дискового пространства. В полном соответствии с принципом Copy-on-Write.
Фактически, любое изменение файла влечёт за собой автоматическое создание нового снимка файловой системы, поэтому вы можете использовать эту ФС как машину времени и отматывать назад состояние файлов.
История
NILFS2 была разработана в недрах Nippon Telegraph and Telephone Corporation, фактически, государственной (оно имеет контрольный пакет) и крупнейшей телекоммуникационной компании Японии. А конкретнее в в лаборатории CyberSpace Laboratories под руководством Ryusuke Konishi.
Для чего конкрентно она разрабатывалась — неизвестно, однако, можно предположить, что подобная ФС, с её функционалом «машины времени» идеальна для хранения данных, в которых может возникнуть желание поковыряться спецслужбам, чтобы повторно проиграть всю картину СМС, емейлов и т.п…
NILFS2 также, потенциально, очень ценный инструмент для служб внутренней безопасности, так как позволяет восстановить все удалённые письма в почтовой базе данных, вскрыть косяки сотрудников, которые впоследствии могут попытаться их замаскировать, удалив или изменив свои файлы.
Однако что-то пошло не так. То ли правительство Японии передумало за всеми следить (а-ля принцип Яровой), то ли производительность NILFS2 на традиционных HDD оказалась ниже плинтуса, и NILFS2 была выпущена под GPL лицензией и очень быстро вошла в ядро Linux, так как особых претензий к коду, написанному высококвалифицированными японцами, у разработчиков ядра Linux не было.
На что похожа NILFS2?
С точки зрения использования: на систему контроля версий SVN. Каждый чекпойнт ФС — это коммит, который делается автоматически без ведома пользователя при любом изменении: будь-то удаление, изменение содержимого файла или прав доступа. Каждый коммит имеет номер, который линейно увеличивается.
С точки зрения программиста: на циклический буфер. Файловая система копит изменения и записывает их в кусок равный примерно 8 МБ (2000×4096, где 2000 — число элементов в блоке, а 4096 — размер страницы памяти). Весь диск поделен на такие чанки. Запись идёт последовательно.
Основные плюшки NILFS2
- Версионность!!!
- Процедура восстановления ФС после сбоя элементарна: при загрузке ищется последний чанк, имеющий верную контрольную сумму, и на него устанавливается суперблок. Это практически моментальная операция.
- В связи с тем, что запись всегда идёт линейно, то:
- может показывать хорошие результаты при работе на SSD, с медленной случайной записью.
- NILFS2 экономит ресурс SSD, так как отсутствует фактор мультипликации записи.
- Потенциальная простота реализации репликации на удалённую NILFS2 ФС
NILFS2 для /home
В Unix-подобных ОС, как правило, присутствует папка /home, в которой хранятся данные пользователей. Различные программы сохраняют в этой папке свои настройки относящиеся к конкретному пользователю.
А кто, как не пользователи, чаще всего косячит? Поэтому, как говорится, сам Бог велел использовать на /home NILFS2.
Тем более, что с повсеместным распостранением SSD мы теперь можем не волноваться насчёт сильной просадки при использовании CoW файловых систем.
Да, снимки ФС (снепшоты) мы можем сколько угодно часто создавать и в ZFS и BTRFS, но всегда есть риск, что потерянное изменение файла окажется между снимками. И снимки ещё нужно администрировать: удалять старые. В NILFS2 всё это происходит автоматически, буквально каждые несколько секунд.
Я создал логический том с помощью lvcreate (в группе томов nvme, тонкий пул thin). Я рекомендую создавать именно на томе lvm, так как в последствии он может быть легко расширен.
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 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
Она работает довольно быстро для избранного способа реализации: ищет различия между файлами методом бисекции, быстро монтируя и сравнивая файл/директорию в разных снимках.
В дальнейшем планирую также добавить команду diff
для утилиты, а также диапазоны чекпоинтов по номерам и датам.
Клич к разработчикам
На Хабре много спецов. Прошу, допилите NILFS2. Сделайте репликацию, низкоуровневый быстрый diff между ревизиями, reflink и другие плюшки!
Благодарности:
- Разработчикам 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. Замеченные ошибки направляйте в личку. Повышаю за это карму.
Вы можете поэкспериментировать с CoW-файловыми системами, заказав виртуальную машину у RUVDS по купону ниже.