Знакомство с Linux. Часть 18. Восстановление данных

Информация - загадочная субстанция с точки зрения экономики и физики. Вот грамм золота - это всегда грамм золота. А данные, занимающие один и тот же объём, могут оказаться необходимыми - а может выйти и так, что от них захочется как можно скорее избавиться.
С Windows в этом отношении просто. Когда требуется что-то удалить, достаточно щёлкнуть в "Проводнике" по клавише Delete - и указанный файл перемещается в своего рода отстойник, остроумно названный кем-то "Корзиной". Впоследствии можно будет либо восстановить помеченную как ненужная информацию (если вы вдруг ошиблись или передумали), либо уничтожить её окончательно - точнее, произвести формальный процесс удаления файла. Информация о нём при этом исчезнет из корневого каталога диска, но сами сектора, заполненные данными "стрёртого" файла, останутся нетронутыми. Существуют особые утилиты, так называемые шреддеры, которые позволяют действительно "снести" с поверхности диска любые следы удалённого файла - чтобы никто уже не смог его восстановить в случае чего.

С точки же зрения Linux, процедура ликвидации информации не так уж проста и обратима. Файлы в этой операционной системе представляют собой логические контейнеры данных, с каждым из которых связана структура индексного дескриптора (inode, index-node structure). Эта структура содержит важные с точки зрения ОС метаданные о файле: сведения о его владельце, правах доступа, времени последнего обновления и т. п. Так вот, при удалении файла в Linux (в файловой системе ext2) даже индексные дескрипторы физически не стираются с диска, - они просто помечаются как свободные. Соответственно, и содержимое удалённых файлов остаётся (в теории) доступным для восстановления; по крайней мере, пока на занимаемые ими физические сектора не была записана новая информация. Но как же до этого содержимого добраться?

Прежде всего обратим внимание на восстановление информации особого рода. Есть на каждом разделе винчестера запись, наиболее ценная с точки зрения пользователя: так называемый суперблок - "точка отсчёта" файловой системы. Размер суперблока всего лишь 1024 байта, но содержит он массу важнейших данных: размер файловой системы; количество, список и индексы свободных блоков; размер списка индексов и т. д. "Затереть" суперблок, вообще говоря, не так-то просто - доступ к занимаемой им области винчестера имеет не каждая программа. И всё же есть вероятность того, что он будет просто механически разрушен - вследствие аппаратного сбоя диска, например. Что в таком случае делать? Пользоваться резервными копиями. Автоматически, на наше счастье, создаваемыми при форматировании раздела.

Если в системе произошёл сбой суперблока на одном из файловых разделов, при загрузке Linux - ещё до появления графической заставки, на этапе монтирования системы - вы увидите запись вроде "Невозможно автоматически исправить ошибки. Попробуйте запустить e2fsck вручную". В том случае, когда "засбоил" не корневой раздел Linux, можно продолжить загрузку (повреждённый раздел окажется неподмонтированным), а затем приступать к лечению, произведя логин от имени суперпользователя. Если же рухнул именно корневой раздел - лучше всего загрузить систему с компакт-диска установки в режиме recovery, заполучить доступ к root shell, и тогда уже следовать рекомендациям системы.
А суть этих рекомендаций - в том, чтобы воспользоваться резервной копией суперблока. При форматировании каждого раздела этих копий создаётся несколько, и нормально работающая система поддерживает их в актуальном состоянии. Номера блоков, начиная с которых располагаются в разделе резервные суперблоки, кратны определённым степеням двойки: то есть команда

e2fsck -b 8192 /dev/hda6

или

e2fsck -b 32768 /dev/hda6

или

e2fsck -b 655366 /dev/hda6

(если допустить, что сбой произошёл именно на разделе /dev/hda6) обратится к указанному блоку и попытается восстановить работоспособность раздела, основываясь на содержащейся в резервной копии информации. Как правило, так даже серьёзно "посыпавшийся" винчестер можно надеяться на какое-то время реанимировать - и хотя бы перекачать с него данные в более надёжное место.

От восстановления раздела перейдём к реанимации стёртого по неосторожности файла. Стандартных утилит вроде unerase в мире Linux не существует - и всё-таки шанс восстановить только что загубленные данные имеется. "Только что" - ключевое слово. Linux/*NIX относятся к по-настоящему многозадачным системам. В частности, это означает, что на освободившееся после уничтожения файла место каким-то из активных на данный момент процессов может быть произведена запись. Очень хорошо, если неосторожная команда вроде

rm -rf *

была дана в каталоге, допустим, /home, располагающемся на отдельном логическом разделе. Тогда есть гарантия, что по крайней мере никакие временные служебные файлы никакими активными процессами туда записываться не будут - на то существуют разделы /var и /tmp. Если мы ведём речь о домашнем компьютере, то скорее всего, кроме вас на данный момент у него нет пользователей. В противном случае необходимо позаботиться об их немедленном (по возможности) отключении - иначе они, действуя в пределах того же самого раздела /home, могут сами того не желая, произвести запись на опрометчиво освобождённые вами участки диска. Предупредить пользователей об отключении и попросить их временно завершить свои сеансы можно, воспользовавшись командой wall. Сообщение, отправленное при помощи этой команды, отобразится в каждой терминальной и графической сессии, открытой на данном компьютере, в том числе и на удалённых терминалах.



Удостоверившись, что в системе вы остались в гордом одиночестве (команда ps aux (см. man ps для пояснений; в первом столбце вывода отображаются владельцы активных процессов), можно приступать к реанимации. Реанимация потребует специальных инструментов... Прежде всего, войдите в систему как root - это лучше сделать, не прерывая текущего сеанса, воспользовавшись командой su -. Затем... "Хороший тон" системного администрирования требует затем произвести определённое количество нетривиальных действий. А именно - отыскать достаточно свободного места на одном из разделов для того, чтобы можно было скопировать туда (целиком, в виде файла) подлежащий восстановлению утерянной информации раздел. Весь раздел, ведь удалённый файл мог быть сильно фрагментирован. И потом уже искать нужную информацию в полученном файле. Смысл данной операции - в том, чтобы на каждом шаге иметь возможность безнаказанно совершать ошибки. В крайнем случае, всегда можно создать ещё одну копию раздела, и приступить к поискам с учётом этих самых ошибок.

Но! Для наших тренировочных целей, вообще говоря, сгодится и более простой путь. А именно - восстановление файла "по живому". Типичный пример: вам приходит некое письмо, вы просматриваете его одним глазком - и без долгих размышлений "грохаете". То есть насовсем, а не в папку "Удалённые", - допустим, вы используете для беглого просмотра почты из командной строки текстовый клиент вроде pine или elm. Приходящая почта в Linux (если за её приём отвечает программа sendmail) накапливается в каталоге /var/spool/mail в файле с названием, соответствующем логину каждого из пользователей, на имя которых поступают письма. Итак, условия задачи: восстановить уничтоженный в разделе /var текстовый файл письма, зная, какая информация там содержится. "Зная" - значит, что точно может быть воспроизведена хотя бы небольшая последовательность символов, уникальная для данного файла. Чем она длиннее, тем меньше времени займёт поиск.


А сам поиск мы осуществим посредством полезнейшей утилиты grep, непременно присутствующей в каждой инкарнации Linux/*NIX. Эта утилита осуществляет поиск текстовых строк по заданному шаблону, причём не только в файле (файлах), но и на всём пространстве указанного дискового раздела. В том числе, как нетрудно догадаться, в поиск включаются и формально удалённые файлы, если их информация ещё не погребена под более поздними наслоениями. Так что если искомый файл не был слишком длинным (то есть если он при записи на диск не подвергался фрагментации), есть очень высокая вероятность отыскать его при помощи этой утилиты. Параметры должны задаваться при этом поиске такими:

grep -a -B[размер1] -A[размер2] 'текст' [наименование_раздела]

Здесь размер1 - количество строк, которые нужно выводить на экран, после заданной параметром текст искомой строки, а размер2 - количество строк перед ней. Помните, пожалуйста, что под "текстовой строкой" в Linux подразумевается последовательность символов, завершающаяся символом конца строки. Можно довериться программе и не выводить найденный текст на экран, а сразу перенаправить вывод в файл, чтобы затем уже в спокойной обстановке отрезать от искомой последовательности строк свсё лишнее и заполучить уничтоженное сообщение обратно.


Что же делать, если файл был длинным и оказался фрагментированным? Или вообще не был текстовым?.. Можно, конечно, сильнее углубиться в теоретические основы построения файловой системы ext2. Можно выяснить, каким образом файловые дескрипторы хранят информацию о всех блоках данного файла и как на основе этой информации восстановить любой уничтоженный файл - не только текст, но и изображения, и музыку... Но давайте не будем пока торопиться с активным применением ручного труда. Чуть позже станет ясно, почему.


Одним из наиболее популярных в Linux-сообществе средств автоматического восстановления файлов является утилита с немудрёным именем recover, созданная Томом Пике (http://recover.sourceforge.net/). Распространяется утилита в виде .tar.gz-архива, а значит, проинсталлировать её (точнее, скомпилировать на своей машине) для вдумчивого читателя уже не составит труда. Нужно только распаковать архив в каталоге /usr/local/src, изучить, как положено, файл readme и в соответствии с его рекомендациями выполнить команды

make
make install

Сразу же после этого утилита готова к работе. Наберите в командной строке (от имени root)

recover /dev/hda6

(если утерянные данные вы рассчитываете найти именно на этом дисковом разделе).


Утилита сообщит, что проводится поиск индексных дескрипторов, после чего станет задавать наводящие вопросы. А именно: в каком году был удалён искомый файл? В каком месяце, и - приблизительно - какого числа? В какой час дня, в какую минуту часа? Если вы не помните ответа на один (или не один) из вопросов, ничего страшного, - просто предъявленный затем список потенциально готовых к восстановлению файлов может оказаться очень длинным. Утилита уточнит также возможный размер файла в байтах и вероятный UID (user identifier) его владельца, после чего - если совпадение с указанными вами критериями встретилось ей при просмотре индексных дескрипторов - сообщит о находке. Предпоследним вопросом, заданным вам, будет, куда записать восстановленную информацию; последним - не желаете ли произвести поиск ещё раз. Собственно, всё. Никаких таинственных фокусов recover не проделывает - просто является удобным интерфейсом для стандартных средств реанимации файловой системы ext2.


По духу к ней близок другой программный пакет, e2undel, детище Оливера Дедриха. Адрес этого пакета в Интернете - http://e2undel.sourceforge.net. Полезной и удобной опцией e2undel является то, что она позволяет производить восстановление файла по его имени. Файловая система ext2 устроена так, что имя файла - это, фактически, единственная информация, которая при стирании его стандартными средствами действительно теряется бесследно. Установив полностью пакет e2undel, вы сможете положиться на него в этом вопросе: всем удаляемым файлам будет отныне вестись учёт, и реанимировать их удастся с сохранением оригинального имени.

Внимательный читатель, возможно, уже заметил некоторую нелогичность в моём изложении: хотя подразумевается, что с некоторых пор в данном цикле статей речь идёт об ОС Red Hat Linux 9, устанавливающейся по умолчанию на файловой системе ext3, до сих пор я рассказывал об утилитах, предназначенных для работы с ext2. Обычно с точки зрения пользователя разница между этими файловыми системами не слишком заметна: ext3 является журналируемой версией ext2, - такого пояснения в общем случае достаточно. Однако в том, что касается способности восстанавливать стёртые файлы, между столь близкими родственницами имеется принципиальное несогласие. А именно: уничтожение файла в ext2 означает, в частности, что: а) занимавшиеся им блоки помечаются как свободные (хотя физически не заполняются, допустим, нулями); б) индексный дескриптор файла объявляется свободным, хотя продолжает хранить служебную информацию о файле. Так вот, в ext3 всё далеко не так человечно - информация из индексного дескриптора файла там действительно удаляется. То есть пусть даже физически занимаемые информацией файла блоки остались нетронутыми - неоткуда больше получить указание на то, где именно их искать. Остаётся, конечно, описанный самым первым способ ручной реанимации текстовых файлов, когда путём прямого просмотра всех подряд блоков файлового раздела можно по памятным ключевым словам "вытащить" расположенные в непосредственной их окрестности строки. Но как быть с потерянными прелестями автоматизации? Как восстанавливать музыку и картинки?

"Чаще надо резервные копии делать", - примерно в таком духе высказываются на форумах Linux-гуру, которым растерянные новички задают подобные вопросы. Но помимо резервного копирования (оставлять которое без внимания ни в коем случае нельзя!), можно предложить ещё один рецепт. Срабатывать он будет, правда, лишь для тех файлов, которые вы решите восстанавливать после знакомства с ним. Рецепт заключается в том, чтобы попросту подменить стандартную команду уничтожения файлов rm чуть более интеллектуальной утилитой, которая даже в командной строке позволит создать некий аналог Windows Trash Can. Чтобы удаляемые файлы отправлялись не в небытие, а в "корзину", откуда потом их в случае чего не составит труда извлечь.

И такая утилита уже написана! Поблагодарим некоего MDK aka Dileep Kumar M, который разместил на своём сайте http://www.kumarayil.net/recycled.htm пару небольших bash-скриптов: rm_secure и empty_trash (их также можно взять здесь). Первый из них как раз маскирует стандартный, брутальный rm; второй предназначен для опустошения "корзины" - если вы на сто три процента уверены, что ничего важного в ней не осталось. Инсталлировать скрипты не просто, а очень просто. Поместите их в каталог /usr/loca/bin, а затем измените права доступа, разрешив их исполнение, а также откройте на просмотр и запись для всех и каждого каталог /lost+found - это, по умолчанию, хранилище всевозможного "мусора", который ОС обнаруживает на диске при восстановлении корневой файловой системы после сбоев. Теперь там же будет размещаться и наша "корзина командной строки":

chmod +x /usr/local/bin/rm_secure
chmod +x /usr/local/bin/empty_trash
chmod 777 /lost+found



Далее нужно произвести собственно подмену rm новой утилитой. Проще всего это сделать на уровне каждого индивидуального пользователя (включая root'а), благо на домашнем компьютере у вас их наверняка немного. Файл, содержащий пользовательские настройки оболочки (обычно это .bashrc; хорошим вариантом будет также подправить /etc/skel/.bashrc, чтобы и каждый новый эккаунт снабжался этой функцией), дополните строкой

alias rm='/usr/local/bin/rm_secure'

Вот и всё. Теперь, чтобы пустить в дело старый, "безвозвратный" rm, надо будет выполнять rm с опцией -n, или -nosecure. Если же этот ключ употреблён не был, после опрометчивого удаления файла достаточно выполнить команду

rm --viewtrash

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

rm --restore [имя_файла]

Команда же

rm --emptytrash

очистит "корзину" насовсем. Пользуйтесь ей с осторожностью - но и не затягивайте с применением, так как удаляемые "понарошку" файлы будут занимать на винчестере вполне реальное место. Либо поставьте команду очистки "корзины" в список заданий демона crond - либо вручную контролируйте время от времени текущую ёмкость диска. Реализовать первый способ можно, изучив руководство к команде cron (man cron); второй - регулярно пользуясь утилитами df и du. О каждом из этих программных средств мы будем ещё говорить, однако самые нетерпеливые могут воспринимать их исследование как домашнее задание.


Как прекрасно известно каждому, кто хотя бы мельком знакомился с Рабочим столом Windows, почётное место на нём занимает Корзина. Именно туда отправляются удаляемые в "Проводнике" и прочих утилитах с графическими интерфейсами файлы и каталоги. В любое время - пока Корзина не очищена - оттуда можно извлечь любой файл в полном объёме. А в Linux, стало быть, до такого простого и изящного решения не додумались?


Додумались, на наше с вами счастье. В графической оболочке KDE (и Gnome, конечно, тоже) Корзина наличествует - и после первого старта системы каждый из пользователей может насладиться её успокаивающим видом в левом верхнем углу Рабочего стола. Более того, в меню действий, выпадающем при щелчке правой кнопкой мыши по файлам или каталогам в окне программы Konqueror, KDE-аналоге Проводника Windows, имеются целых две опции удаления: действительно уничтожить файл (этому соответствует клавиатурная комбинация Shift+Del), либо отправить-таки его в Корзину (просто Del).Внешний вид пустой и заполняемой Корзин различается, так что даже беглый взгляд на десктоп позволит вам определить, не пора ли забраться в trash и полюбопытствовать, что за содержимое в нём хранится.


Физически Корзина является одной из папок домашнего каталога пользователя, поэтому доступ к находящимся там файлам имеет исключительно сам пользователь (ну и вездесущий root, конечно). Корзина KDE сберегает информацию о предназначенных к удалению объектах целиком, то есть ликвидируя каталог, вы можете быть уверены, что в Корзину он переместился с полным сохранением своей внутренней структуры, включая, разумеется, права владения и доступа. Так что восстанавливать файлы из этого хранилища-чистилища просто - достаточно мышкой перетащить их в оболочке Konqueror в любую "настоящую" папку, либо просто на Рабочий стол.


Итак, нам всё-таки удалось заставить систему давать нам время от времени последний шанс на восстановление опрометчиво удаляемой информации - и в графическом, и в текстовом режимах работы. А что делать, если данные нужно не сберечь, а именно уничтожить? Навсегда, с гарантией? В Windows для этого применяют не входящие в базовый комплект системы утилиты-шреддеры. В Linux можно ограничиться стандартными средствами, хотя существуют и большие специализированные пакеты - такие, как The Coroner's Toolkit Дэна Фармера, к примеру (http://www.porcupine.org/forensics/tct.html). И всё-таки стандартных средств обыкновенно хватает. Особенно если речь идёт об удалении "под корень" картинок - их-то рассеянные во множестве по файловому разделу блоки собрать вместе не так просто, как обрывки текстовых файлов.

К стандартным средствам относится, во-первых, интенсивное использование данного раздела сразу после удаления чувствительной информации. Чем больше и чаще вы что-то на диск запсываете, тем меньше вероятность, что уже помеченные как свободные блоки прежнего файла останутся нетронутыми. К тому же, процесс можно автоматизировать. Специальная системная утилита dd позволяет побитово перезаписывать информацию из файла в файл; утилита sync форсирует запись информации на диск (в том случае, скажем, если операция была произведена в оперативной памяти, а реальное её воплощение на поверхности винчестера система почему-либо отложила). Комбинируя эти полезные средства, можно поступить следующим образом: заполнить занимаемый приготовленным к уничтожению файлом объём нулями (из особого "устройства" /dev/zero), а затем уже удалить этот, обнулённый, файл. Все операции - синхронизировать. Вот так:

dd if=/dev/zero of=[имя_файла]
sync
rm -n [имя_файла]
sync

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


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