MAATRIX / Блог / Как понять, что вообще крутится на чужом сервере: карта за вечер

Как понять, что вообще крутится на чужом сервере: карта за вечер

MAATRIX

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

Что именно нужно узнать за вечер, а что — нет

Легко увязнуть: начинаете смотреть процессы — находите подозрительный cron — переходите к проверке SSH-ключей — оказываетесь в теме безопасности, хотя цель была просто понять, что на сервере есть. Стоит сразу разграничить задачи.

Эта статья — только про техническую карту: какие процессы выполняются, какие порты открыты, какие сайты обслуживает веб-сервер, какие базы данных установлены и что запускается по расписанию. Результат — таблица на одну страницу, которую можно показать коллеге за пять минут.

Если задача шире — нужно понять, можно ли доверять машине, откуда взялись доступы прежних администраторов, есть ли рабочие бэкапы и как вести себя первые дни, чтобы ничего не сломать, — это отдельная и более объёмная методология, которая разобрана в статье «Достался чужой сервер без документации: с чего начинать разбор». Она про порядок действий и осторожность в целом. Эта статья — конкретно про то, как за вечер получить список «что тут крутится», без которого дальнейший разбор превращается в гадание.

Держите под рукой текстовый файл или markdown-таблицу — записывайте находки сразу, а не «запомню и потом занесу». Через пару часов копания в конфигах вы забудете половину деталей, которые сейчас кажутся очевидными.

Процессы: что вообще выполняется прямо сейчас

Начните с самого прямого вопроса — что запущено в системе:

ps auxf

Флаг f строит дерево процессов — сразу видно, что порождено systemd (родитель — PID 1 через промежуточные юниты), а что запущено вручную из shell-сессии или живёт в screen/tmux/nohup. Процессы без родителя-systemd — кандидаты на «кто-то запустил руками и забыл», их стоит пометить отдельно в карте.

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

systemctl list-units --type=service --state=running
systemctl list-unit-files --type=service | grep enabled

Второй список важнее: он покажет то, что должно стартовать при перезагрузке, включая упавшее и никем не замеченное.

Если на сервере стоит Docker, часть процессов вообще не будет видна в обычном ps на хосте — они изолированы в своих неймспейсах:

docker ps -a
docker compose ls
docker network ls

Стоит поискать docker-compose.yml не только в /opt и /srv, но и в домашних каталогах: find / -maxdepth 6 -iname "docker-compose*.yml" 2>/dev/null. Отдельный частый случай — Docker-контейнер держит собственный веб-сервер и базу внутри, и на карте сервера это должна быть отдельная строка «контейнер X — что внутри», а не единая безымянная запись «docker».

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Порты: что слушает и куда смотрит наружу

Список процессов не отвечает на вопрос «а с чем можно связаться снаружи». Для этого нужны открытые порты:

ss -tulpn
# если ss недоступен
netstat -tulpn

Колонка Local Address:Port показывает, на каком интерфейсе слушает служба: 127.0.0.1:5432 доступен только с самой машины, а 0.0.0.0:5432 или [::]:5432 — снаружи, если не отрезано файрволом. Именно вторая категория заслуживает отдельной пометки в карте — не потому что это обязательно проблема, а потому что дальше кто-то должен явно решить, нужен ли этот порт наружу.

Флаг -p в выводе ss/netstat даёт PID и имя процесса — сопоставьте его со списком из ps auxf, чтобы за каждым портом стояло не голое число, а конкретный сервис.

Если сервер за NAT или использует Docker с проброшенными портами, то, что видно изнутри через ss, не всегда совпадает с тем, что доступно снаружи — Docker добавляет собственные правила в iptables в обход стандартного вывода ufw status. Быстрая проверка снаружи со своей машины:

nmap -Pn -p- ваш.ip.адрес.сервера

Для чисто инвентаризационной задачи достаточно сверить пару десятков «интересных» портов (веб, база, панель управления), не обязательно сканировать все 65535 — это скорее шаг для последующей проверки безопасности, а не для карты сервисов. Если после составления карты обнаружатся порты без понятного назначения, дальнейшие шаги — в статье «Открытые порты на сервере: как проверить и закрыть».

Сайты: что обслуживает веб-сервер

Если на порту 80 или 443 что-то слушает, следующий вопрос — какие именно сайты за этим стоят. Ответ почти всегда лежит в конфигах веб-сервера.

Для nginx:

ls -la /etc/nginx/sites-enabled/
grep -rl "server_name" /etc/nginx/sites-enabled/
grep -A2 "server_name\|root\|proxy_pass" /etc/nginx/sites-enabled/*

Если конфиги не разложены по sites-available/sites-enabled, а свалены прямо в /etc/nginx/conf.d/ — тоже нормальная практика, просто ищите там же.

Для Apache — аналогично, но каталоги называются иначе:

ls -la /etc/apache2/sites-enabled/
apache2ctl -S    # покажет активные VirtualHost со всеми алиасами сразу

Каждый найденный server_name/ServerName — это отдельная строка в карте: домен, каталог с файлами (root или DocumentRoot), и куда идёт трафик — в статические файлы, в PHP-FPM (proxy_pass на unix-сокет или fastcgi_pass), или дальше на бэкенд-приложение (proxy_pass http://127.0.0.1:PORT). Именно связка proxy_pass с портом чаще всего помогает понять, что за процесс из списка ps auxf на самом деле обслуживает конкретный сайт.

Список выпущенных SSL-сертификатов заодно подскажет реальные домены, даже если конфиг веб-сервера успел устареть:

certbot certificates

Для PHP-проектов проверьте пулы PHP-FPM — по ним видно, сколько отдельных PHP-приложений живёт на сервере, даже если в nginx они не разграничены по отдельным файлам конфига:

ls /etc/php/*/fpm/pool.d/

Если сайтов набирается много и хочется зафиксировать их одним взглядом, удобно сразу строить таблицу вида «домен — каталог — технология — куда проксирует».

Базы данных: что внутри и сколько там весит

Отдельный слой карты — СУБД. Начните с того, что вообще установлено и слушает порт (это уже видно из ss -tulpn — типичные порты 3306/5432/6379/27017), а дальше зайдите внутрь и посмотрите, что там за данные.

MySQL/MariaDB:

SHOW DATABASES;
SELECT table_schema AS db, ROUND(SUM(data_length + index_length) / 1024 / 1024, 1) AS size_mb
FROM information_schema.tables GROUP BY table_schema;
SELECT user, host FROM mysql.user;

PostgreSQL:

\l+
SELECT datname, pg_size_pretty(pg_database_size(datname)) FROM pg_database;
\du

MongoDB:

show dbs
db.getSiblingDB('имя_базы').stats()

Redis — тут не «базы» в привычном смысле, а логические индексы (0-15 по умолчанию) и ключи внутри:

redis-cli INFO keyspace
redis-cli --scan --pattern '*' | head -50   # осторожно на больших инстансах, лучше COUNT и SCAN итеративно

Важный нюанс: доступ к самой СУБД ещё нужно получить — если пароль не в истории команд и не в переменных окружения, поищите его в конфигах приложений рядом с сайтами (.env, config.php, settings.py, systemd unit-файлы через systemctl show <service> -p Environment). Один и тот же пароль от базы нередко используется сразу несколькими сайтами на сервере — это тоже стоит отметить в карте, потому что влияет на то, что сломается, если базу придётся переносить или менять пароль.

Если баз много и непонятно, какая к какому сайту относится, самый надёжный способ связать их — посмотреть в конфиге приложения (.env/config) рядом с каждым сайтом из предыдущего шага: там обычно прописаны хост, имя базы и пользователь.

Cron и таймеры: что происходит по расписанию

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

Минимальный проход:

# crontab каждого пользователя, не только текущего
for u in $(cut -f1 -d: /etc/passwd); do echo "== $u =="; crontab -u "$u" -l 2>/dev/null; done

# системные каталоги
cat /etc/crontab
ls -la /etc/cron.d/ /etc/cron.daily/ /etc/cron.hourly/

# systemd-таймеры — их отдельно от cron часто забывают
systemctl list-timers --all

Если внутри сервера крутится Docker, не забудьте, что планировщик может быть встроен прямо в образ приложения — снаружи хоста такая задача вообще не видна ни в crontab, ни в systemctl list-timers. Тема настолько объёмная, что заслуживает отдельного разбора — подробно, где ещё искать чужие расписанные задачи кроме стандартного crontab -l, смотрите в статье «Чужая задача в cron: где ещё смотреть, кроме crontab». Для целей вечерней карты достаточно зафиксировать сам факт наличия задачи, её расписание и предполагаемое назначение — глубокий разбор каждой можно отложить.

Собираем карту: таблица, которая переживёт вечер

Всё, что вы нашли на предыдущих шагах, стоит свести в одну таблицу — она и есть конечная цель вечера. Формат можно упростить под себя, но набор колонок обычно такой:

ЧтоПорт/адресДомен или назначениеЧем управляетсяУверенность
nginx80, 4433 домена (см. sites-enabled)systemdточно
приложение (Node, PID 4821)127.0.0.1:3001обслуживает shop.example.com через proxy_passpm2, вручнуюточно
MySQL127.0.0.1:33064 базы, у трёх свежие данныеsystemdточно
редис127.0.0.1:6379кеш сессий (предположительно)dockerпредполагаю
скрипт sync.shcron, каждые 15 минут, шлёт данные на внешний APIcrontab rootне знаю, зачем

Колонка «уверенность» — не формальность. Разница между «точно», «предполагаю» и «не знаю» показывает, где нужно копать дальше, а где можно остановиться. Строки со статусом «не знаю» — это и есть главный результат вечера: конкретный список того, что требует выяснения, а не смутное ощущение «тут что-то непонятное».

Если карта нужна не только вам, а команде или следующему человеку, который окажется на этом сервере, есть смысл сразу оформить её в постоянном месте, а не оставлять текстовым файлом на рабочем столе. Что именно стоит фиксировать в документации сервера на регулярной основе — отдельно разобрано в статье «Документация сервера: что нужно вести»; карту сервисов удобно взять оттуда как первый раздел.

Отдельно стоит зафиксировать не только то, что вы нашли, но и то, чего не оказалось: если на сервере нет ни одной базы данных, хотя сайт явно работает с формами и личными кабинетами, — это повод поискать внешнюю базу (другой сервер, managed-сервис), а не считать задачу закрытой.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Хватит ли одного вечера на сервер с десятком сайтов и несколькими базами?

На саму инвентаризацию — обычно да, три-пять часов на то, чтобы пройти по всем шагам и свести таблицу. Разбираться в назначении каждой непонятной находки («не знаю, зачем» из таблицы) может занять уже не один вечер — это нормально, карта как раз и нужна, чтобы превратить смутную задачу в конкретный список пунктов.

Нужно ли сразу проверять, не взломан ли сервер?

Для чисто технической карты — нет, это отдельная задача с другим набором проверок (SSH-ключи, история входов, индикаторы компрометации). Если в процессе инвентаризации попадается что-то откровенно подозрительное — обфусцированная cron-задача, процесс с удалённым бинарником в /proc/*/exe — зафиксируйте находку в карте и переходите к отдельному разбору безопасности, не пытаясь закрыть обе задачи одним проходом.

Что делать, если ss и netstat не установлены и в целом окружение урезано?

В минимальных образах (некоторые Docker-контейнеры, часть Alpine-based систем) сетевых утилит может не быть вовсе. Проверьте cat /proc/net/tcp и /proc/net/tcp6 как запасной вариант — это тот же источник данных, из которого ss берёт информацию, просто в сыром виде с портами в hex, либо поставьте ss из пакета (apt install iproute2 / apk add iproute2) на время работы.

Как быть, если веб-сервер вообще не nginx и не Apache, а что-то менее типичное?

Принцип не меняется — ищите конфиг того ПО, что слушает 80/443 по данным ss -tulpn (Caddy, traefik, встроенный сервер приложения) и смотрите его собственный формат конфигурации на предмет доменов и маршрутизации. У Caddy это Caddyfile, у traefik — динамическая конфигурация в файлах или в лейблах Docker-контейнеров.

Стоит ли сразу удалять то, что не попало ни в один сайт и ни в одну базу?

Нет — карта за вечер отвечает на вопрос «что есть», а не «что можно убрать». Между инвентаризацией и удалением должен быть период наблюдения (логи, реальный трафик за несколько дней), иначе есть риск выключить что-то, что казалось лишним, но на деле обслуживало партнёрскую интеграцию или health-check внешнего мониторинга.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →