[Из песочницы] Восстановление remote сервера после удаления части ОС

В последнее время на Хабре было пару интересных статей (например, раз, два и в ряде корп. блогов коллег), после прочтения которых возникла мысль, а не поделиться ли с сообществом опытом по выходу из интересных ситуаций, с которыми сталкивался работая в аутсорсе.

Сегодня про восстановление доступа к виртуальной машине с linux после удаления части операционной системы.

Если содержание будет интересно аудитории, то попробую написать ряд подобных статей.

ab17bb363b9a48b78b5b7372d4cab74b.png

Постановка задачи


В начале 2012 года потребовалось сделать v2v миграцию нескольких linux виртуальных машин между разными ЦОД-ами. Не помню по какой причине, но выбрали способ через rsync всех разделов (естественно, потом колдовство с настройками ядра/модулями/initrd/grub и пр. стандартные процедуры).

Поскольку сервера были «объемные», данные важные, репликация не возможна, каналы узкие, жёсткие требования downtime, сроки — вчера и т.д. и т.п., то расписали подробный план работ в несколько этапов синхронизаций с последующей досинхронизацией изменений. Важным моментом было отсутствие доступа к консоле виртуальной машины (целевая, откуда мигрировали) ибо она была в приватном облаке. Жёсткие условия диктовал Заказчик (классическое желание все сделать быстро, дешево и качественно), поэтому мы максимально себя обезопасили: о рисках предупредили, бекапы сделали сами и попросили сделать бекап приклада, пользователи сервиса о работах оповещены, весь процесс операции был проработан до мельчайших деталей, «окна» в ночное время оговорены — ничто не предвещало беды.

Начало работ


Далее как по закону Мерфи: если может что-то произойти, то это произойдет.

У нас вмешался человеческий фактор: на этапе досинхронизации администратор перепутал аргументы rsync и случайно поменял местами адреса источника и назначения. От потери данных нас спасло то, что синхронизация была от точки монтирования /usr, а администратор успел заметить и быстро прервал выполнение команды. В итоге под удар попали каталоги /usr/{bin, lib*, sbin} — часть файлов из них были удалены. Основная проблема была в том, что из-за отсутствия многих библиотек нельзя было ни открыть новую сессию, ни запустить rsync, ни восстановить все через пакетный менеджер, в общем осталось только то, что запущено + базовые утилиты без особенных зависимостей. Вечер перестал быть томным…

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

Описание восстановления


Сразу оговорюсь, данный алгоритм не является панацеей и не обязательно оптимальным решением, но у него большой плюс — он быстро и успешно сработал.

Идея в следующем: найти донора, скопировать недостающие данные для запуска rsync, запустить rsync, восстановить все библиотеки/команды, пройтись по системе контролем целостности пакетов/diff-ом с бекапа, затем снять нужные данные.

Тут же были подняты сканы «битого» сервера до работ, найден рабочий сервер с аналогичной ОС, который решили использовать как донора для копирования библиотек и программ с него.

Вопрос с транспортом был открытым — на «битом» сервере ничего не работает. Разве что telnet. Тогда вспомнили что через него можно легко посылать GET запросы. Если можно, значит нужно! Поскольку все в *nix хранится в виде файлов, то можно взять, преобразовать архив с нужными данными в unicode текстовый файл и передать как обычный текст (лучше рабочего способа передать данные относительно консистентными через телнет быстро не нашли).

На проблемном сервере стояла обратная задача, принять данные, сконвертировать в архив, распаковать, привести rsync в рабочее состояние, далее все как по маслу.

На рабочем сервере выполнили ряд действий (условно):

  1. Собираем в архив то, что потребуется:
    tar zcf /tmp/usr.tgz /usr...

  2. Конвертируем из бинарного формата в текстовый:
    cat /tmp/usr.tgz | busybox uuencode -m - > usr.txt

  3. Перемещаем на веб сервер, куда есть доступ с битого сервера:
    mv usr.txt /var/www/html

На сломанном сервере (условно):
  1. Пытаемся скачать файл:
    telnet workserver 80 > usr.txt
        GET /usr.txt

  2. Смотрим сколько строк занимают служебные заголовки head -30 usr.txt (можно сразу через sed отрезать base64, но для подстраховки решили посмотреть руками):
        Trying workserver...
        Connected to workserver.
        Escape character is '^]'.
        HTTP/1.1 200 OK
        Date: Fri, 17 Jan 2013 13:13:50 GMT
        Server: Apache
        Last-Modified: Fri, 17 Jan 2013 13:11:32 GMT
        Accept-Ranges: bytes
        Content-Length: 262635116
        Connection: close
        Content-Type: text/plain; charset=utf-8
    
        begin-base64 644 -
        bmV0LnNoLm1lAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

  3. Удаляем первые http строки командой (удалить строки с 1 по 12 включительно, до строки begin-base64):
    sed -e '1,12d' usr.txt

  4. Конвертируем обратно из текстового формата в бинарный:
    busybox uudecode -o /root/usr.tgz usr.txt

  5. Распаковываем /root/usr.tgz и руками переносим файлы, что удалены;
  6. Проверяем заработал ли rsync, если нет — смотрим чего не хватает, если да — запускаем rsync, синхронизируем с рабочей копией служебные папки;
  7. Ищем что изменилось (условно):
    rpm -Va | tr -s ' ' | sed -e 's/\ d\ /\ /g' | sed -e 's/\ c\ /\ /g' | cut -f2 -d' ' > va2.xt
    rpm -qf $(cat va2.xt) | sort -n | uniq > reinstall.pkg
    yum -y reinstall $(cat reinstall.pkg)

  8. В зависимости от затронутых пакетов может потребоваться ребут (после снятия бекапа изменений, проработки вариантов отката на другой сервер и 3-х кратных проверок, что все загрузится, желательно после переустановки ядра).

Итоги


Мы смогли уложиться в выделенное время. Бизнес проблемы не почувствовал. Тем не менее нами был проведен тщательный анализ ситуации и в будущем подобные ошибки уже не повторялись.
С технической стороны были отмечены следующие моменты:
  • Теперь во всех ситуациях, где хранятся исходные данные, файловые системы перед работами перемонтируются в read only режим;
  • Работы выполняются в screen-е;
  • Все команды администраторы, проводящие работы, копируют только из текстового редактора (vi, notepad, etc) для исключения каких-либо ошибок (в этом случае администратор использовал историю для ввода команд и слегка модифицировал). Штатно никаких уходов от плана. Перед этим все проверяется на тестовых стендах, проверяются опытными администраторами;
  • На особо важных операциях всегда дежурит второй более опытный администратор для анализа происходящего и при необходимости перехватывающий управление;
  • Составлен ряд пакетов/ПО, которые устанавливаются на задействованные машины (после выполнения работ на некоторых удаляются по соображениям безопасности) и используются в случае не штатных ситуаций;
  • Теперь данная задача добавлена в список тренировочных задач при обучении сотрудников восстановлению *nix-подобных систем, т.е. каждый администратор помимо сертификации RHCE должен уметь её решать + интересно давать её на собеседовании linux-админам :)

Комментарии (0)

© Habrahabr.ru