Инвентаризация сервера: как составить список всего, что на нём крутится
Откройте htop на сервере, который живёт больше года, и посчитайте, сколько процессов вы можете назвать по имени и объяснить зачем они нужны. Обычно набирается три-четыре десятка строк, из которых уверенно опознаётся половина. Остальное — тестовый сервис, который «поставили на неделю», старый мониторинг, забытый прокси или процесс, оставшийся от подрядчика, который давно не отвечает на письма. Инвентаризация сервера — это не бюрократия для галочки, а способ вернуть себе контроль: понять, что реально работает, зачем, и кто за это отвечает.
Содержание
- Почему список неизбежно устаревает сам по себе
- Список процессов: с чего начинается любая инвентаризация
- Слушающие порты: что видно снаружи и изнутри
- Установленное ПО и файлы: то, что не обязательно запущено сейчас
- Как соотнести список с реальными бизнес-задачами
- Как задокументировать результат, чтобы он не потерялся снова
- Как не дать инвентаризации протухнуть через месяц
Почему список неизбежно устаревает сам по себе
Ни один сервер не начинает жизнь захламлённым — захламление накапливается постепенно, и в этом главная ловушка: каждое отдельное добавление выглядит оправданным.
Типичный путь одного сервера за пару лет:
- Разработчик поднял тестовый Redis для эксперимента с кэшированием — эксперимент не взлетел, Redis остался слушать порт.
- Подрядчик настроил VPN-туннель для миграции данных — миграция закончилась, туннель не закрыли, потому что «а вдруг ещё понадобится».
- Админ поставил Netdata для разовой диагностики нагрузки — диагностика прошла, агент продолжает жрать память и слать метрики в никуда.
- Кто-то развернул staging-копию сайта для демо клиенту — демо было полгода назад, копия открыта наружу с тестовыми паролями.
- Уволившийся сотрудник оставил cron-задачу, синхронизирующую данные с сервисом, доступ к которому закрыли ещё в прошлом квартале.
По отдельности каждое из этих действий было разумным в момент, когда его делали. Проблема в том, что решение «убрать после того как станет не нужно» никогда не имеет владельца и дедлайна — и поэтому не выполняется. Через два-три года смены команды на сервере скапливается наследие, о происхождении которого не помнит никто, включая тех, кто это ставил.
Инвентаризация решает конкретную и узкую задачу: составить актуальный список того, что реально запущено, сверить его с тем, что реально нужно, и явно решить судьбу расхождения — либо задокументировать назначение, либо выключить.
Список процессов: с чего начинается любая инвентаризация
Первый слой — что вообще выполняется на машине прямо сейчас. Начните с полного списка процессов, отсортированного по потреблению ресурсов, — так сразу видно не только «что запущено», но и «что заметно ест CPU или память»:
ps aux --sort=-%cpu | head -40
ps aux --sort=-%mem | head -40
Для systemd-систем полезнее смотреть не на процессы напрямую, а на управляемые сервисы — так вы сразу видите логическую единицу, а не PID:
systemctl list-units --type=service --state=running
systemctl list-unit-files --type=service --state=enabled
Второе включает в себя и то, что сейчас не запущено, но включится при следующей перезагрузке, — это отдельная категория риска: сервис может быть выключен вручную «на время», но остаться в автозагрузке и ожить после планового ребута сервера.
Если на сервере используется Docker, процессы контейнеров не всегда видны в обычном ps так, чтобы было понятно, что это и зачем:
docker ps
docker ps -a
docker compose ls
docker ps -a отдельно важен: он покажет и остановленные контейнеры, которые продолжают занимать диск образами и volume'ами, даже не потребляя CPU.
Отдельно проверьте, что запускается по расписанию — это тот же вид работы, что и постоянно висящий процесс, просто с отложенным эффектом:
crontab -l
for u in $(cut -f1 -d: /etc/passwd); do
echo "=== $u ==="; crontab -u "$u" -l 2>/dev/null
done
ls -la /etc/cron.d/ /etc/cron.daily/ /etc/cron.hourly/ /etc/cron.weekly/
systemctl list-timers --all
Цикл по всем пользователям системы принципиален: crontab -l без параметров покажет только задачи текущего пользователя, а забытая задача чаще всего лежит у сервисного или давно неиспользуемого аккаунта. Если тема с ревизией самих cron-заданий вам откликается отдельно от общей инвентаризации, это соседняя, более узкая задача — она заслуживает отдельного разбора.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверСлушающие порты: что видно снаружи и изнутри
Список процессов отвечает на вопрос «что работает», список портов — на вопрос «что доступно по сети» и, что важнее, «откуда». Основной современный инструмент — ss:
ss -tulpn
Флаги: -t TCP, -u UDP, -l только слушающие сокеты, -p показать процесс, -n не резолвить имена (быстрее и честнее). На старых системах тот же результат даёт netstat, если он ещё установлен:
netstat -tulpn
Отдельно обратите внимание на адрес, на котором слушает порт, — это половина всей пользы от команды. 127.0.0.1:6379 означает, что Redis доступен только локально, это нормально. 0.0.0.0:6379 — что он слушает все интерфейсы и потенциально доступен снаружи, если фаервол не режет трафик. Именно так чаще всего и утекают базы данных, поднятые «для теста»: дефолтный конфиг слушает все интерфейсы, а про фаервол забывают.
Список локально слушающих портов не равен списку того, что реально видно из интернета, — между ними стоит фаервол, NAT, security group у провайдера. Поэтому вторым шагом стоит проверить порты снаружи, с другой машины:
nmap -sT -p- your-server-ip
Полное сканирование всех 65535 портов (-p-) медленнее сканирования top-1000 по умолчанию, но именно оно ловит нестандартные порты, на которые кто-то посадил панель администрирования или тестовый сервис. Конкретные шаги по закрытию лишнего разобраны в статье про проверку и закрытие открытых портов на сервере, а взгляд именно со стороны внешнего периметра — в материале про инвентаризацию портов, видимых снаружи.
Полезно дополнительно посмотреть, кто держит соединения прямо сейчас, — это косвенный признак реальной нагрузки на сервис:
ss -tn state established
lsof -i -P -n | grep LISTEN
lsof -i даёт ту же информацию, что ss, но иногда удобнее для быстрого визуального просмотра и почти всегда установлен на серверах с долгой историей.
Установленное ПО и файлы: то, что не обязательно запущено сейчас
Список процессов и портов покрывает «что работает прямо сейчас», но не покрывает установленный, но временно неактивный софт — а это тоже часть поверхности, за которую вы отвечаете: неиспользуемый пакет с уязвимостью так же опасен, как и запущенный сервис.
dpkg -l | less # Debian/Ubuntu
rpm -qa | sort # RHEL/CentOS/AlmaLinux
apt list --installed # Debian/Ubuntu, альтернативный вывод
Смотрите отдельно на конфиги веб-серверов — часто там остаются виртуальные хосты на давно закрытые проекты:
ls -la /etc/nginx/sites-enabled/
ls -la /etc/apache2/sites-enabled/
Символическая ссылка в sites-enabled на конфиг, который никто не открывал полгода, — почти всегда кандидат на удаление или как минимум на выяснение судьбы.
И последний слой — кто вообще имеет доступ к серверу. Это формально отдельная задача от инвентаризации сервисов, но обе задачи об одном и том же — о накоплении того, о чём забыли:
who
last -a | head -30
lastlog
cat /etc/passwd | grep -E '/bin/(ba)?sh$'
Если этот срез вам актуален отдельно и глубже, чем в рамках общего списка сервисов, у нас есть отдельный разбор именно по квартальной ревизии доступов на сервере.
Как соотнести список с реальными бизнес-задачами
Список процессов и портов — это только сырые данные. Самая трудоёмкая часть инвентаризации не техническая, а организационная: понять, зачем каждая строчка списка вообще существует.
Практический порядок работы с каждой найденной позицией:
- Проверьте активность. Если сервис пишет логи — посмотрите, есть ли в них что-то за последнюю неделю:
journalctl -u имя-сервиса --since "7 days ago". Тишина в логах при живом процессе — сильный сигнал, что им никто не пользуется. - Проверьте сетевую активность.
ss -tn state establishedи логи фаервола покажут, приходят ли вообще соединения на этот порт извне или изнутри сети. Порт, к которому за месяц никто не подключился, кроме сканеров ботов, скорее всего не нужен. - Сверьте с DNS и внешними ссылками. Если на сервисе висит поддомен — проверьте, используется ли он:
dig +short poddomen.example.com, затем откройте адрес в браузере. Заброшенный поддомен, который резолвится на живой IP, — ещё и риск захвата поддомена (subdomain takeover), если вы вдруг решите сервис выключить, не убрав DNS-запись. - Спросите команду напрямую. Формальная проверка технических признаков не заменяет вопрос живым людям: «кто-нибудь пользуется вот этим сервисом на порту 8081?» в общем чате часто закрывает вопрос быстрее любого лога. Дайте команде разумный срок на ответ — неделю, — и если тишина, переходите к следующему шагу.
- Если неясно — не выключайте сразу, а изолируйте. Закройте порт фаерволом, оставив процесс работающим, и подождите две-три недели. Если за это время никто не пожаловался и мониторинг не поднял алерт — это подтверждение, что сервис можно останавливать полностью.
Цель инвентаризации — не «выключить как можно больше», а получить достоверное знание. Часть находок окажется важной инфраструктурой, которую просто плохо задокументировали, — и тогда результат не удаление, а появление документации там, где её не было.
Как задокументировать результат, чтобы он не потерялся снова
Список, который лежит в голове одного человека или в закрытой переписке, обречён устареть тем же образом, каким устарел исходный беспорядок. Формат документа должен быть таким, чтобы его было легко поддерживать в актуальном состоянии — иначе он просто станет ещё одним артефактом, за который никто не отвечает.
Минимальный рабочий формат — таблица, которую держат в git-репозитории рядом с остальной инфраструктурной документацией (а не в отдельном файле на чьём-то рабочем столе):
| Сервис / порт | Что делает | Кто отвечает | Последняя проверка активности | Статус |
|---|---|---|---|---|
| nginx : 80, 443 | Основной сайт и API | команда бэкенда | ежедневно, живой трафик | нужен |
| redis : 127.0.0.1:6379 | Кэш сессий приложения | команда бэкенда | активные подключения | нужен |
| postgres-test : 5433 | Тестовая БД для стейджинга | не установлен | логи пустые 3 месяца | под вопросом, на удаление |
| openvpn : 1194/udp | VPN для миграции 2025 года | миграция закрыта | подключений нет | к удалению |
| netdata : 19999 | Разовая диагностика нагрузки | не установлен | не открывался полгода | к удалению |
Почему именно таблица, а не описательный текст: она заставляет явно закрыть каждую колонку, включая неудобную «кто отвечает» — а именно отсутствие ответственного чаще всего и превращает сервис в забытый.
Статус «под вопросом» — обязательная промежуточная категория, а не компромисс для ленивых. Не всё удаётся классифицировать за один проход: важно, чтобы у «под вопросом» была дата, до которой он должен закрыться, иначе категория станет новой версией того же захламления.
Как не дать инвентаризации протухнуть через месяц
Разовая инвентаризация даёт снимок на конкретный день. Без механизма поддержки актуальности этот снимок устареет тем же путём, каким устарело исходное знание о сервере, — просто медленнее. Несколько практик, которые реально работают на серверах, за которыми давно наблюдаю:
Автоматический снимок состояния. Простой скрипт по cron, который раз в неделю сохраняет текущий список процессов, портов и unit-файлов в git-репозиторий рядом с ручной таблицей:
#!/bin/bash
OUT=/var/log/server-inventory/$(date +%F).txt
mkdir -p /var/log/server-inventory
{
echo "=== LISTENING PORTS ==="
ss -tulpn
echo "=== RUNNING SERVICES ==="
systemctl list-units --type=service --state=running --no-pager
echo "=== DOCKER ==="
docker ps 2>/dev/null
} > "$OUT"
Сам по себе снимок не заменяет ручную работу по соотнесению с бизнес-задачами, но даёт возможность быстро увидеть diff: что появилось новое с прошлой недели, чего не было в предыдущем снимке. Новая строка в diff'е — повод спросить «а это откуда» пока событие ещё свежо в памяти команды, а не через год.
Привязка к регламенту, а не к энтузиазму. Разовая инициатива «давайте наведём порядок» без даты следующего раза повторяет судьбу исходного бардака. Рабочая практика — квартальный или полугодовой обзор, зафиксированный как повторяющаяся задача в календаре или таск-трекере, а не как разовая акция.
Правило «один порт — один ответственный». При любом новом деплое сервис сразу попадает в таблицу инвентаризации с указанием, кто отвечает и зачем он нужен. Это дешевле, чем восстанавливать эту информацию постфактум через полгода, когда автор уже забыл детали или сменил работу.
Явный дедлайн для временного. Если сервис поднимается «на неделю для теста» — сразу ставьте в календаре напоминание на дату, когда его нужно либо продлить осознанно, либо выключить. Именно отсутствие дедлайна превращает временное в постоянное практически всегда.
Ни одна из этих практик не требует сложных инструментов — работает обычный cron, git и календарь. Сложность инвентаризации не в технологии сбора данных, а в дисциплине регулярного повторения.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Сколько времени занимает полная инвентаризация сервера?
Технический сбор данных (списки процессов, портов, unit-файлов) — минуты, это можно сделать за один присест командами из статьи. Соотнесение с бизнес-задачами и выяснение владельцев занимает значительно дольше — от нескольких дней до пары недель на средний сервер с историей, в основном за счёт ожидания ответов от команды.
Можно ли просто выключить всё, что не опознано, и посмотреть, что сломается?
На проде — плохая идея: даже если ничего не сломается сразу, некоторые зависимости проявляются с задержкой (например, ежемесячный отчётный скрипт). Более безопасный путь — сначала заблокировать доступ фаерволом, оставив процесс живым, подождать несколько недель и только потом останавливать сам сервис.
Нужно ли инвентаризировать выделенный сервер иначе, чем VPS?
Принципиальной разницы в методике нет — команды ss, ps, systemctl работают одинаково. Разница практическая: на выделенном сервере чаще накапливается больше legacy, потому что миграция на новое железо происходит реже, чем пересоздание VPS, — а значит, инвентаризацию стоит проводить чаще, а не реже.
Как быть с процессами, которые не опознаёт даже владелец сервера, а найти в интернете описание не получается?
Изолируйте: остановите автозапуск, но не удаляйте бинарники и данные сразу, сохраните конфиг и снимок диска или хотя бы архив рабочей директории. Понаблюдайте пару недель за поведением системы. Если ничего не сломалось — это подтверждение, что можно удалять; если процесс действительно оказался нужным, у вас останется, из чего его восстановить.
Стоит ли автоматизировать соотнесение с бизнес-задачами, а не только сбор данных?
Полностью автоматизировать эту часть не получится — она требует контекста, которого нет ни в одной технической метрике: истории проекта, договорённостей с клиентами, планов на квартал вперёд. Автоматизировать стоит только рутинный сбор данных и обнаружение изменений (diff между снимками), а решение о судьбе каждого сервиса должно оставаться за человеком.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →