Учёт установленного ПО и версий на серверах Linux

0
16
Обложка статьи: Учёт установленного ПО и версий на серверах Linux

Инвентаризация сети отвечает на вопрос «что отвечает в сети». Отдельный вопрос — что установлено на каждом конкретном сервере: при выходе уязвимости в конкретной версии пакета нужно быстро узнать, на скольких серверах она есть, без захода на каждый по очереди. Ниже скрипт, который собирает список пакетов и версий с датой установки, и результаты его проверки.

Статья опирается на логику направления «Управление ИТ-активами» из методики зрелости Группы Сбер (источник); это методика для крупных компаний, мы используем её как ориентир и пересказываем своими словами. Проверка выполнена в контейнере Debian 12, после неё всё удалено.

Что должно получиться

Уровень Что это значит на практике
1. Начальный Есть актуальный список установленного ПО по каждому серверу, с версиями, пригодный для сверки при выходе новой уязвимости

Критерии сформулированы нами по мотивам методики, это ориентир, а не оценка соответствия.

Скрипт

#!/usr/bin/env bash
# Учёт установленного ПО и версий на хосте Debian/Ubuntu: пакеты, дата установки, срок поддержки дистрибутива.
set -uo pipefail
OUT="software-$(hostname)-$(date +%Y%m%d).csv"
echo "package,version,install_date" > "$OUT"
# дата установки берётся из лога dpkg (первая запись install для пакета); если лога нет — "unknown"
dpkg-query -W -f='${Package},${Version}\n' | while IFS=, read -r pkg ver; do
  idate=$(zgrep -h " install $pkg:" /var/log/dpkg.log* 2>/dev/null | head -1 | awk '{print $1}')
  echo "$pkg,$ver,${idate:-unknown}"
done >> "$OUT"
echo "готово: $OUT, пакетов: $(($(wc -l < "$OUT") - 1))"

echo "--- поддержка дистрибутива"
if command -v distro-info >/dev/null 2>&1; then
  distro-info --supported 2>/dev/null | tail -1
fi
grep -E "^VERSION=" /etc/os-release

Запуск: ./sw-inventory.sh на каждом сервере (или через оркестратор конфигураций, если он есть). На выходе — CSV с именем пакета, версией и датой установки.

Результат проверки

На тестовом сервере скрипт собрал 110 пакетов. Первая попытка получить дату установки дала unknown для всех пакетов без исключения, хотя пакет был только что установлен. Причина — формат записи в журнале dpkg.log: имя пакета там идёт с архитектурой через двоеточие (install curl:amd64 …), а dpkg-query отдаёт имя без архитектуры (curl). Поиск по шаблону «пакет и пробел» не находил строку, где после имени пакета сразу стоит двоеточие. После исправления шаблона дата install корректно нашлась для пакета, установленного в рамках теста (curl,7.88.1-10+deb12u15,2026-10-14), а 88 из 110 пакетов остались с пометкой unknown — это ожидаемо: они входят в базовый образ и были установлены при его сборке, до создания файла dpkg.log в самом контейнере. На обычном сервере, где система не переустанавливалась с нуля, журнал обычно доступен за весь срок жизни машины, и доля unknown будет намного меньше.

Вторая деталь, на которую стоит обратить внимание при написании подобных скриптов: без обработки ошибки отсутствующий файл журнала (zgrep: /var/log/dpkg.log*: No such file or directory) в сочетании с set -e и pipefail останавливает весь скрипт после первой же строки без explicitного сообщения об ошибке — в текущей версии скрипта это уже учтено флагом set -uo pipefail без -e для основного цикла.

Что делать с результатом

  • При выходе критической уязвимости в конкретном пакете: `grep` по имени пакета во всех собранных CSV сразу показывает, на каких серверах он есть и какой версии, без обхода серверов вручную.
  • Сверяйте со сроком поддержки дистрибутива: строка VERSION из /etc/os-release в конце отчёта показывает, не истёк ли срок поддержки самой системы — для устаревших систем вопрос не в версии пакета, а в переносе на поддерживаемый дистрибутив.
  • Собирайте по расписанию и храните историю: разница между вчерашним и сегодняшним списком показывает, что изменилось без явного изменения в карточке — повод свериться с процессом управления изменениями.
  • Передавайте результат в процесс управления уязвимостями: список пакетов и версий — исходные данные для сопоставления с базами уязвимостей, даже без сканера.

Порядок внедрения

  1. Разверните скрипт на всех серверах через существующий механизм распространения конфигураций или вручную для небольшого парка.
  2. Настройте регулярный запуск и складывайте результаты в одно место (общая папка, внутренний репозиторий).
  3. При выходе критической уязвимости первым делом ищите пакет по собранным спискам, а не идите по серверам вручную.
  4. Сверяйте список с реестром активов: сервер, который не прислал отчёт, — повод проверить, жив ли он и не забыт ли в процессе.
  5. Используйте список вместе с сетевой инвентаризацией: одна показывает, что отвечает в сети, другая — что установлено на каждом хосте.

Диагностика

Симптом Причина и что делать
Дата установки «unknown» почти у всех пакетов На системе давно не ротировался журнал или сервер недавно переустановлен. Ожидаемо для базового образа; на зрелом сервере проверьте, не был ли dpkg.log случайно очищен
Скрипт останавливается на первом пакете без сообщения об ошибке Отсутствующий файл журнала при включённом set -e прерывает скрипт на первой неудачной подстановке. Не используйте set -e вместе с командами, у которых ожидаемо может не быть результата
Пакет не находится по шаблону, хотя установлен недавно В журнале имя пакета записывается с архитектурой через двоеточие (curl:amd64). Ищите по шаблону «имя пакета и двоеточие», а не «имя пакета и пробел»
Нужно то же самое для RPM-дистрибутивов Используйте rpm -qa --last для списка с датой установки; формат и источник данных другие

Ограничения

Скрипт показывает только то, что установлено через менеджер пакетов. Приложения, развёрнутые вручную или в контейнерах со своими зависимостями, в этот список не попадают — для контейнеров нужна отдельная проверка образов: Trivy.

Где это в модели зрелости

Материал относится к направлению «Управление ИТ-активами» (материалы направления, карта зрелости). Начальный уровень требует хотя бы актуального списка ПО с версиями: без него при выходе уязвимости приходится обходить серверы вручную, теряя время на самом критичном этапе.

Как проверить

  1. Список установленного ПО собирается по расписанию со всех серверов, а не только по запросу.
  2. При выходе критической уязвимости в конкретном пакете ответ «на скольких серверах он есть» занимает минуты, а не часы.
  3. Сервер, переставший присылать отчёт, замечен и проверен.
  4. Список используется вместе с реестром активов и процессом управления уязвимостями, а не хранится отдельно без дальнейшего действия.

Источники

  • Методика оценки уровня зрелости кибербезопасности компании, Группа Сбер: sberbank.ru.

Комментарии закрыты.