Достался чужой сервер без документации: с чего начинать разбор незнакомой машины
Новый сотрудник получает root на продакшене, в компании купили проект с готовой инфраструктурой, или предыдущий администратор просто исчез — и вот вы сидите перед сервером, о котором не знаете ничего. Ни схемы, ни списка сервисов, ни понимания, что будет, если что-то тронуть. Разбор такой машины — это не про «быстро всё почистить», а про методичную разведку: сначала понять картину целиком, потом действовать. Ниже — порядок, который снижает риск сломать что-то важное в первый же день.
Содержание
- Прежде чем что-то трогать: инвентаризация запущенных сервисов
- Где искать конфигурацию, окружение и cron-задачи
- Бэкапы: есть ли они на самом деле и восстанавливаются ли
- Следы документации: комментарии, README, bash history
- Осторожное наблюдение перед изменениями
- Документация по ходу разбора — не только для себя
Прежде чем что-то трогать: инвентаризация запущенных сервисов
Первое правило разбора чужого сервера — ничего не выключать и не удалять, пока не составлен список того, что вообще работает. Даже процесс с именем old_test_script.py, который выглядит забытым, может быть единственным, что подтверждает лицензию стороннего сервиса или держит открытым туннель к внешней системе.
Начните с трёх срезов: процессы, сеть, установленные пакеты.
# что реально выполняется прямо сейчас
ps auxf
# что слушает порты и куда смотрит наружу
ss -tulpn
# то же самое, если ss недоступен
netstat -tulpn
ps auxf в древовидном виде сразу показывает, какие процессы порождены systemd, а какие запущены вручную из shell (родитель — сама сессия bash, а не PID 1) или держатся на screen/tmux/nohup — такие процессы без родителя-systemd чаще всего запущены «на время» и забыты.
Дальше — что зарегистрировано как сервис:
systemctl list-units --type=service --state=running
systemctl list-unit-files --type=service | grep enabled
Второй список важнее первого: он показывает, что стартует при загрузке, даже если сейчас не работает (возможно, упало и никто не заметил).
Сопоставьте открытые порты из ss -tulpn (колонка Process с флагом -p покажет PID) с процессами — особое внимание портам, слушающим на 0.0.0.0 или ::: они доступны извне, если не отрезаны файрволом.
Установленные пакеты дают представление о технологическом стеке:
# Debian/Ubuntu
dpkg -l | less
# RHEL/AlmaLinux/CentOS
rpm -qa | sort
Если сервер работает через Docker — это отдельный слой инвентаризации, который часто прячет процессы от ps на хосте:
docker ps -a
docker network ls
docker volume ls
docker compose ls # если compose-плагин установлен
Стоит сразу поискать docker-compose.yml не только в очевидных местах вроде /opt и /srv, но и в домашних каталогах пользователей — find / -maxdepth 6 -iname "docker-compose*.yml" 2>/dev/null.
Результат этого шага — простая таблица: сервис, порт, зачем (если понятно), кем управляется (systemd/docker/руками). Без неё дальнейшие шаги превращаются в гадание.
Где искать конфигурацию, окружение и cron-задачи
Конфиги и переменные окружения на унаследованном сервере редко лежат в одном месте — у каждого администратора свои привычки, и если сервером занимались несколько человек за годы, слои накладываются друг на друга.
Проверьте по порядку:
/etc/— системные конфиги и конфиги пакетных менеджеров (nginx, postgresql, ssh и т.д.);/opt/и/srv/— часто место для самописных проектов и их конфигов;- домашние каталоги (
/home/*,/root/) — личные.env, скрипты, алиасы в.bashrc; - systemd unit-файлы (
/etc/systemd/system/*.service) — там часто прописаныEnvironment=иEnvironmentFile=прямо в определении сервиса; - Docker — переменные окружения контейнеров смотрите через
docker inspect <container> | grep -A 30 '"Env"', а не только в.env-файле рядом с compose, потому что значения могли переопределить при запуске вручную.
Переменные окружения, которые нигде «не лежат», а экспортируются при старте оболочки или сервиса, ищите так:
grep -r "export " /etc/profile /etc/profile.d/ /root/.bashrc /root/.profile 2>/dev/null
systemctl show <service> -p Environment
Cron-задачи — отдельная головная боль, потому что мест для них минимум пять, и стандартный crontab -l покажет только задачи текущего пользователя:
# crontab каждого пользователя (не только root)
for u in $(cut -f1 -d: /etc/passwd); do echo "== $u =="; crontab -u "$u" -l 2>/dev/null; done
# системные каталоги
ls -la /etc/cron.d/
ls -la /etc/cron.daily/ /etc/cron.hourly/ /etc/cron.weekly/ /etc/cron.monthly/
cat /etc/crontab
# systemd-таймеры — их часто забывают, ища только cron
systemctl list-timers --all
Если на сервере стоит Docker, не забудьте про cron *внутри* контейнеров — иногда планировщик встроен прямо в образ приложения и снаружи хоста не виден вообще. Если тема оказывается запутанной, отдельно разобрано, где ещё искать чужие задачи, кроме crontab.
Составляя список конфигов и cron-задач, сразу помечайте дублирующие или взаимоисключающие находки (например, два разных скрипта ротации логов для одной директории) — частый след того, что решение переделывали, не убрав старое.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверБэкапы: есть ли они на самом деле и восстанавливаются ли
Этот шаг легко отложить «на потом» — сервер работает, значит с бэкапами наверняка всё в порядке. Ровно так рождаются истории, где резервные копии шли исправно год, но оказались нерабочими в момент, когда внезапно понадобились. Пока вы не проверили лично — считайте, что бэкапов нет, даже если видна папка backups с файлами внутри.
Порядок проверки:
1. Найти, что вообще настроено. Ищите не только очевидные cron-задачи с rsync/tar, но и установленные инструменты резервного копирования:
which restic borgbackup duplicity rclone rdiff-backup 2>/dev/null
systemctl list-timers | grep -i backup
crontab -l | grep -iE "backup|dump|rsync|restic|borg"
Проверьте конфиги популярных инструментов, если они установлены: ~/.config/borg/, restic обычно держит репозиторий и переменные окружения (RESTIC_REPOSITORY, RESTIC_PASSWORD_FILE) в systemd unit или в скрипте-обёртке.
2. Выяснить, куда сохраняются копии. Локальный диск того же сервера — это не бэкап, а его иллюзия: при отказе диска или компрометации сервера копия погибнет вместе с оригиналом. Проверьте, есть ли внешнее хранилище — другой сервер, S3-совместимое хранилище, отдельный провайдер бэкапов. Если копии лежат только локально — фиксируйте это как находку и поднимайте вопрос об исправлении, но не чините в первый день.
3. Проверить дату последнего успешного запуска и лог.
ls -la --time-style=full-iso /path/to/backup/dir | head
journalctl -u <backup-service> --since "-30 days" | grep -iE "error|fail|success"
Наличие свежего файла ещё не значит, что бэкап рабочий — файл мог быть создан пустым или оборваться на середине из-за нехватки места.
4. Попробовать восстановить хотя бы один файл или таблицу в тестовое место. Это единственный способ узнать, что бэкап действительно бэкап, а не набор битых архивов. Не обязательно поднимать полное окружение — для БД достаточно развернуть дамп во временную базу и свериться со счётчиком строк ключевых таблиц; для файлового бэкапа — распаковать архив во временную директорию и проверить структуру.
Если такой проверки не делали ни разу, договоритесь, что восстановление будет тестироваться регулярно, а не только один раз при передаче сервера. Общий принцип разобран в статье как убедиться, что бэкап рабочий — годится как чек-лист для первого прогона.
Следы документации: комментарии, README, bash history
Формальной документации на унаследованном сервере обычно нет — иначе вы бы её уже читали. Но неформальные следы почти всегда есть, просто разбросаны по местам, куда не принято заглядывать в первую очередь.
Комментарии в коде и конфигах. Ищите не только # TODO и # FIXME, но и объяснения решений — часто именно они отвечают на вопрос «а почему так странно сделано»:
grep -rniE "todo|fixme|hack|workaround|важно|осторожно|не трогать" /opt /etc/nginx /etc/systemd/system 2>/dev/null
README и файлы с пояснениями в неожиданных местах. Не ограничивайтесь корнем проекта — иногда единственный README лежит в подкаталоге деплоя, в /root/notes.txt или даже в виде файла ПРОЧИТАТЬ_ПЕРЕД_ИЗМЕНЕНИЯМИ.txt рядом со скриптом:
find / -maxdepth 5 -iname "readme*" -o -iname "*notes*" -o -iname "*важно*" 2>/dev/null
История команд в shell. Это часто самый информативный источник — она показывает не то, что *должно* работать, а то, что предыдущий администратор реально делал, включая ручные патчи «на скорую руку», которые нигде больше не задокументированы:
cat /root/.bash_history
cat /home/*/.bash_history
history # если работаете в той же сессии, где что-то уже выполняли
Учтите ограничения: bash хранит ограниченное число последних команд (переменная HISTSIZE, часто 1000-2000 строк), файл может быть частично перезаписан, а если история отключена (HISTFILE=/dev/null в .bashrc — тоже красноречивый признак), там будет пусто. Проверьте также .zsh_history, если использовался zsh — формат другой, перед каждой командой стоит временная метка.
История git, если код лежит в репозитории на сервере.
git log --oneline -30
git log --all --grep="fix\|hotfix\|revert" -i
git blame <файл> для строк, которые выглядят как «заплатка»
Сообщения коммитов, даже короткие вроде «фикс для клиента X, не убирать», часто объясняют то, что иначе выглядит как ошибка.
Все находки на этом шаге стоит сразу выписывать в единый файл — не для красоты, а потому что через неделю разбора вы забудете половину мелких деталей, которые сейчас кажутся очевидными.
Осторожное наблюдение перед изменениями
Соблазн навести порядок в первый же день велик — особенно когда видно что-то «явно неправильное»: два процесса на одном порту, странное правило firewall, cron-задача, которая выполняется каждую минуту без видимой причины. Это тот момент, где стоит притормозить.
Правило простое: ничего критичного не трогать, пока не собрана полная картина хотя бы по одному циклу — сутки, а лучше неделя наблюдения. За это время многое, выглядевшее бессмысленным, находит объяснение: cron раз в минуту может быть health-check для внешнего мониторинга, «дублирующий» процесс на другом порту — резервный инстанс, странное правило iptables — единственное, что разрешает подключение партнёрской системы раз в месяц.
Практические шаги для безопасного наблюдения:
- Смотрите логи, а не только текущее состояние.
journalctl, логи приложений, access-логи веб-сервера покажут реальный трафик за последние дни — это объясняет назначение сервиса лучше, чем разовый снимок процессов. - Проверяйте связи перед отключением. Прежде чем гасить сервис, который кажется лишним, посмотрите, кто к нему подключается:
ss -tnp | grep <порт>покажет активные соединения, а логи — обращались ли к нему за последние недели. - Меняйте по одному, с возможностью откатить. Если решаете вмешаться (например, закрыть явно опасный порт наружу) — делайте это изолированно, с планом отката и записью, что именно и когда изменено.
- Заведите отдельный лог собственных действий. Простой файл или тикет: дата, что сделали, почему, что ожидали увидеть. Если что-то сломается через два дня, этот журнал сэкономит часы на восстановление хронологии.
Отдельный частый сценарий — сервер достался вместе с активными доступами прежнего администратора или подрядчика. Пока идёт разведка, это не повод сразу всё обрывать (можно потерять единственный работающий канал связи с системой), но повод зафиксировать, кто и как может входить, и готовить план смены доступов после того, как картина прояснится. Если ситуация именно такая — админ ушёл, а доступы остались только у него, — пошаговый план описан в статье «Админ ушёл со всеми паролями».
Документация по ходу разбора — не только для себя
Главный практический совет этого разбора звучит скучно, но именно он экономит недели в будущем: документируйте по мере того, как разбираетесь, а не после того, как «наконец во всём разобрались». Второго момента может не наступить — вы переключитесь на текучку и забудете детали, которые сейчас кажутся очевидными.
Не нужно сразу писать полноценный wiki-раздел. Достаточно минимального набора, который растёт по ходу работы:
- Список сервисов и их назначение — то, что вы уже собрали на первом шаге. Даже в формате «сервис — порт — предположительно для чего — уверенность (точно/предполагаю/не знаю)» это уже огромный шаг вперёд по сравнению с пустотой.
- Карта конфигов и переменных окружения — где что лежит, чтобы следующему (или вам через полгода) не пришлось повторять весь
findиgrepзаново. - Статус бэкапов — что настроено, куда сохраняется, когда в последний раз проверялось восстановление, и дата следующей проверки.
- Список открытых вопросов — то, что вы не поняли: «неясно, зачем этот cron», «непонятно, кто клиент этого API-ключа». Такой список честнее, чем молчание, и подсказывает, куда смотреть дальше.
- Журнал изменений — начиная с момента, когда вы взяли сервер под контроль: что меняли и почему.
Формат не так важен, как факт ведения — подойдёт простой markdown-файл в репозитории, внутренний wiki или текстовый файл на самом сервере (с резервной копией вне сервера). Если хочется закрепить это системно, есть отдельный разбор, что именно стоит фиксировать в документации сервера — можно взять оттуда структуру.
Смысл этой привычки шире, чем «мне будет удобнее». Однажды на ваше место придёт следующий человек — новый коллега, подрядчик, а может быть, вы сами через два года, когда детали забудутся. Минимальная документация, оставленная сейчас, — это ровно то, чего вам самим не хватило в начале разбора.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Сколько времени обычно занимает полный разбор незнакомого сервера?
Зависит от масштаба, но для среднего продакшен-сервера закладывайте от нескольких дней до пары недель, включая наблюдение за поведением хотя бы один полный цикл (сутки-неделя). Точная цифра зависит от количества сервисов, качества (точнее, отсутствия) прежней документации и от того, разбираетесь вы в одиночку или командой.
Что делать, если бэкапов не оказалось вообще?
Зафиксировать это как критичный риск и как можно быстрее настроить хотя бы базовое резервное копирование — лучше простой rsync во внешнее хранилище сегодня, чем идеальная схема через месяц. Разбор остального при этом продолжается параллельно.
Можно ли сразу отключить сервис, который явно не используется?
Если по логам за разумный период (минимум несколько недель) нет обращений и нигде нет упоминаний о его критичности — да, но сначала остановите, а не удаляйте, и подождите, прежде чем убирать файлы и конфиги окончательно. Отменить удаление сложнее, чем повторно запустить остановленный сервис.
Стоит ли сразу менять все пароли и ключи на унаследованном сервере?
Смена доступов до того, как понятна картина интеграций, может оборвать легитимные соединения (мониторинг, партнёрские API), о которых вы ещё не знаете. Логичный порядок — сначала разведка и наблюдение, затем плановая ротация с фиксацией, что и когда менялось.
Как понять, что разбор закончен?
Формального критерия нет, но ориентир такой: список работающих сервисов с понятным назначением собран, вы знаете, где искать конфиги и cron-задачи, бэкапы проверены восстановлением хотя бы раз, а список открытых вопросов сокращается, а не растёт.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →