Восстановление повреждённых файлов

Данную статью взял из журнала Хакер. Она рассказывает о том, как в пакетных дистрибутивах восстановить повреждённые файлы. Имеем сервер, у которого побились файлы. Далее текст идёт от имени автора

Что я сделал? Ввел всего одну строку в баше, применив лишь знания средств операционной системы, а именно менеджера пакетов. Ежедневно устанавливая массу пакетов в свой любимый дистрибутив, многие забывают, что они содержат список контрольных сумм файлов, позволяющих проверить их целостность Для демонстрации данного функционала в системах, построенных на deb-пакетах, мы попросим помощи у debsums:

# арt-get install -у debsums

Нагнетая обстановку, специально для тебя я поломал бинарник нашего любимого Nmap :). Пусть утилита пробежится по всем известным ей пакетам и проверит, не повреждены ли какие-то установленные файлы:

# debsums -с
...
/usr/bin/nmap

Вот и нашелся наш мученик! Дальше нужно выяснить, какому пакету принадлежит измененный файл. В этом нам поможет флаг ‘-S’ программы dpkg:

$ dpkg -S /usr/bin/nmap
...
nmap: /usr/bin/nmap

Фактически, получив имя пакета, в данном случае «nmap», ты уже можешь его переустановить, используя ключ ‘—reinstall’ утилиты арt-get. Но мы сведем все операции в одну команду, которая, помимо всего, выудит из «dkpg -S» через разделитель : имя пакета с помощью «сut -d : f1» и переустановит его:

# арt-gеt install -у --reinstall $(dpkg -S $(debsums -с) | cut -d : -f1 | uniq -u)

Поскольку RPM-bases серверов уж точно не меньше дебиановских, то я буду проклят, если не рассмотрю спасение и околокрасношапочных систем. Для проверки целостности файлов воспользуемся ключами ‘-V’ (проверить) и ‘-а’ (все пакеты):

# rpm -Va
...
.М....... с /etc/cups/subscriptions.conf
S.5....Т. /usr/bin/nmap

Есть результат! Но что это за букв начале? Первые восемь символов — флаги, обозначающие, что аномального случилось с файлом:

• S — изменился изначальный размер файла;
• М — изменились права доступа или режим;
• 5 — отличается контрольная сумма MD5;
• D — отличается старший/младший номер файла устройства;
• L — изменился путь ссылки;
• U — отличается владелец (пользователь) файла;
• G — изменился владелец группы;
• Т — отличается время изменения

Из приведенного выше примера мы можем сделать вывод о том, что у /usr/bin/nmap изменился размер, обнаружилась не-верная MD5-сумма и отличается время модификации.

Помимо этих флагов, следует два пробела и символ, характеризующий тип файла. Буква «с» означает конфигурационный файл, также значения могут быть.

• d — файл документации;
• g — файлы, изначально отсутствующие в пакете;
• l — файл лицензии;
• r — файл readme.

Как видишь, нет специального флага для того, чтобы отдельно выделить бинарные файлы, вместо этого там стоит пробел. Поэтому напишем регулярное выражение, с помощью которого мы выведем только строки, начинающиеся с флага «^S» (размер файла изменился). Последующие во-семь символов нас не интересуют «.{8}», ведь на основании предыдущего утверждения мы уже можем сделать вывод о необходимости переустановки пакета. Далее (для бинарных файлов) следуют четыре пробела « {4}». А последующий путь может быть произвольной длины и состоять из произвольных символов «.*».

Как итог, получим изменившиеся бинарные файлы с помощью версии grep, полностью поддерживающей расширенные регулярные выражения, — egrep:

#rpm -Va | egrep "^S.{8} {4}.*"
...
5.5....Т. /usr/bin/nmap

Достаем через разделитель ‘ ‘ пятый аргумент — путь к изменившемуся файлу:

#rpm -Va | egrep "^S.{8} {4}.*" | cut -d ' ' -f5
...
/usr/bin/nmap

Осталось узнать, какому пакету принадлежит повреждённый файл. Для этого у RPM есть ключи ‘-qf’:

#rpm -qf $(rpm -Va | egrep "^S.{8} {4}.*" | cut -d ' ' -f5) | uniq -u
...
nmap-6.25.1-fc18.x86-64

И завершающим аккордом добавляем к предыдущим командам переустановку всех пакетов с поврежденными бинарниками с помощью yum reinstall:

#yum reinstall -y $(rpm -qf $(rpm -Va | egrep "^S.{8} {4}.*" | cut -d ' ' -f5) | uniq -u)

Вуаля, рабочая система готова продолжать служить тебе и дальше.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *