SSD Nodes Learn Hosting plans →
Руководства Matt ConnorАвтор: Matt Connor · Обновлено 2026-09-11

Как проверить сервер Debian или Ubuntu на наличие CVE

Узнайте, какие уязвимости затрагивают ваш сервер с помощью утилит debsecan и debvulns. Мы покажем, как отфильтровать отчеты и выявить критические угрозы, требующие перезагрузки.

Какие известные CVE затрагивают этот сервер прямо сейчас

Чтобы узнать, какие известные CVE затрагивают ваш сервер в данный момент, сравните версии установленных пакетов с опубликованным списком уязвимостей. CVE (Common Vulnerabilities and Exposures) — это система публичных идентификаторов для известных ошибок безопасности. В Debian для такого сравнения используется debsecan или debvulns. В Ubuntu используется pro cves, так как Ubuntu ведет собственный трекер, а инструменты Debian считывают неверные данные.

Установка обновлений и понимание того, каким угрозам вы подвержены — это две разные задачи. apt upgrade отвечает на один вопрос: доступен ли более новый пакет. Он не сообщает, какие CVE остаются открытыми на этой машине, и не указывает, какие из них никогда не будут исправлены в вашем релизе. Для второй задачи требуется сканер, а при работе со сканером необходимо точно понимать, с чем именно он сравнивает текущее состояние системы.

Как на самом деле работает сканер пакетов

Механизм достаточно прост для понимания. Сканер считывает список установленных пакетов из базы данных dpkg. Он сопоставляет каждый бинарный пакет с исходным кодом, из которого тот был собран, поскольку данные об уязвимостях фиксируются для каждого исходного пакета. Сканер загружает ленту данных, в которой для каждого CVE и каждого исходного пакета указано, в какой версии был исправлен дефект для конкретного дистрибутива. Затем он сравнивает вашу установленную версию с версией, содержащей исправление, используя тот же алгоритм сортировки версий, что и dpkg --compare-versions.

CVE-сканер в Debian или Ubuntu — это просто сравнение версий с кэшированной лентой данных. Ни больше, ни меньше.

Сопоставление бинарного пакета с исходным — это этап, который часто упускают, и это приводит к пропуску уязвимостей. Исходный пакет openssl собирается в бинарный пакет libssl3t64 в Debian 13 и Ubuntu 24.04. CVE, зарегистрированный для openssl, не будет найден при простом поиске по именам ваших бинарных пакетов. Именно поэтому debvulns запрашивает python3-apt: кэш APT содержит это соответствие, а без него инструмент переключается на dpkg-query и может пропустить проблемы, где имя исходного пакета отличается от имени бинарного.

Лента данных также содержит статус для каждого релиза, который не сводится к простому «да» или «нет». Откройте страницу отслеживания для исходного пакета, например запись openssl в системе отслеживания безопасности Debian, и в каждом столбце релиза вы увидите vulnerable, fixed, no DSA или postponed. Статус no DSA означает, что команда безопасности изучила проблему и решила, что она не требует обновления стабильной версии, поэтому исправление не будет выпущено для вашего релиза. Ваш сканер будет сообщать об этом CVE при каждом запуске на протяжении всего жизненного цикла этого релиза, и никакие действия с apt upgrade не помогут его устранить. Это самая частая причина, по которой пользователи отказываются от подобных инструментов, хотя это не является ошибкой в работе самого инструмента.

Сканирование сервера Debian с помощью debsecan

debsecan находится в архиве Debian и не требует подключения внешних репозиториев.

sudo apt update && sudo apt install -y debsecan
debsecan --suite trixie

Каждая строка вывода соответствует одной уязвимости CVE для установленного бинарного пакета:

CVE-2016-2776 bind9-host (remotely exploitable, high urgency)
CVE-2016-8864 libdns-export100 (fixed, remotely exploitable, medium urgency)

Уровень срочности и маркер remotely exploitable берутся напрямую из трекера Debian. Слово fixed означает, что исправленная версия уже есть в архиве, поэтому обновление устранит эту запись. Строку без fixed закрыть невозможно.

Обязательно передавайте --suite, иначе половина вывода будет неверной. debsecan использует этот параметр только для определения наличия исправленного пакета и проверки устаревания пакетов. Если указать неверный suite, список CVE останется корректным, но маркеры fixed и предупреждения об устаревших пакетах будут неверными. Используйте кодовое имя того релиза, который вы используете: trixie для Debian 13, bookworm для Debian 12.

Два варианта вывода стоит добавить в скрипт:

debsecan --suite trixie --only-fixed --format packages
debsecan --suite trixie --only-fixed --format detail

--format packages выводит только имена бинарных пакетов, по одному в строке — это список, с которым можно работать. --format detail выводит всю информацию, содержащуюся в ленте для каждой проблемы. --only-fixed отбрасывает записи no DSA, описанные выше, что сокращает вывод до задач, которые можно выполнить прямо сейчас.

Для настройки регулярного сканирования отредактируйте /etc/default/debsecan и установите SUITE, MAILTO и REPORT. Пакет содержит debsecan-create-cron, который создает запись в cron, запускающуюся каждый час в случайно выбранную минуту. Ежечасный запуск не означает ежечасное сканирование: debsecan --cron проверяет, были ли данные загружены сегодня, и завершает работу, если это так. Случайная минута нужна для того, чтобы все машины Debian не обращались к трекеру в одну и ту же секунду.

Почему debsecan выдает неверные данные в Ubuntu

debsecan находится в репозитории Ubuntu universe (версия 0.4.20.1 в 24.04). Он устанавливается без ошибок и выводит уверенные отчеты, которым нельзя доверять. Его лента данных основана на трекере безопасности Debian, который не отслеживает пакеты Ubuntu. Проблемы, специфичные для Ubuntu, в нем отсутствуют. Строки версий Ubuntu, такие как 3.0.13-0ubuntu3.4, никогда не совпадают с исправленными версиями Debian, и debsecan сравнивает неизвестные ему версии с Debian unstable. В результате возникают ложные срабатывания по проблемам, которые Canonical исправила несколько месяцев назад, и игнорируются реальные уязвимости. Ошибка в Launchpad под номером #95925 зафиксирована еще в 2007 году.

Ранее существовал мост между системами. Проект ust2dsa преобразовывал данные трекера CVE Ubuntu в формат debsecan и обновлял их каждые шесть часов. Проект был переведен в архив в октябре 2021 года. Если сейчас направить --source на этот источник, вы получите ленту, которая перестала обновляться пять лет назад. Это хуже, чем отсутствие сканера, так как устаревшая лента сообщает об отсутствии проблем.

Список CVE на сервере Ubuntu с помощью pro cves

Ubuntu предоставляет ответ в ubuntu-pro-client. В версии 35 была добавлена команда pro cves, которая выводит список установленных пакетов, затронутых известной уязвимостью CVE.

pro cves
pro cves --fixable
pro cves --unfixable

pro cves

Package         Priority     Origin        Vulnerability
firefox         medium       esm-infra     CVE-2020-6852
openssh         low          standard      CVE-2021-3188
vim             critical     esm-infra     CVE-2011-3374
vim-tiny        high         -             CVE-2011-3380

Сначала изучите столбец Origin, так как он определяет ваши дальнейшие действия. Статус standard означает, что исправление находится в стандартном репозитории безопасности Ubuntu и будет установлено при обычном обновлении. Статусы esm-infra или esm-apps означают, что исправление доступно только в рамках Expanded Security Maintenance, для чего к машине должна быть привязана подписка Ubuntu Pro. Статус - означает, что исправление пока отсутствует, и эта строка является аналогом статуса no DSA в Debian.

Для конкретной уязвимости CVE полную картину дают две команды:

pro cve CVE-2024-5480
pro fix --dry-run CVE-2020-25686

pro cves <CVE-ID>
pro fix <CVE-ID>

Команда pro fix --dry-run ничего не меняет и показывает текущее состояние:

CVE-2020-25686: Dnsmasq vulnerabilities
 - https://ubuntu.com/security/CVE-2020-25686

1 affected package is installed: dnsmasq
(1/1) dnsmasq:
A fix is available in Ubuntu standard updates.
{ apt update && apt install --only-upgrade -y dnsmasq }

✔ CVE-2020-25686 is resolved.

pro fix <CVE-ID> --dry-run

Машина, не подверженная уязвимости, выведет No affected source packages are installed.. Если исправление недоступно, машина выведет строку вида ✘ CVE-2017-9233 is not resolved.. Уберите флаг --dry-run, и та же команда выполнит обновление. pro security-status — это вспомогательный инструмент: он подсчитывает установленные пакеты по репозиториям и сообщает количество ожидающих обновлений безопасности, что важно, так как для Main и Universe действуют разные обязательства по поддержке.

Установка debvulns и фиксация версии

debvulns — это набор инструментов на языке Python, созданный на основе системы отслеживания безопасности Debian. Он предоставляет сканер командной строки и экспортер для Prometheus, работающие с одними и теми же данными. Версия 0.2.2 является актуальной по состоянию на август 2026 года.

Запуск pip install debvulns в Debian 12 или более новых версиях завершается ошибкой error: externally-managed-environment, так как системный Python управляется через dpkg. Выполняйте установку в виртуальное окружение, которое имеет доступ к системному python3-apt:

sudo apt update && sudo apt install -y python3-venv python3-apt
sudo python3 -m venv --system-site-packages /opt/debvulns
sudo /opt/debvulns/bin/pip install debvulns==0.2.2
/opt/debvulns/bin/debvulns --severity high --format json | head -40

--system-site-packages — это важный флаг. Без него виртуальное окружение не сможет импортировать python3-apt, debvulns переключится на dpkg-query, и вы потеряете сопоставление бинарных файлов с исходным кодом без вывода сообщения об ошибке. Также зафиксируйте версию. Сканер, поведение которого меняется произвольным образом, нельзя использовать для сравнения результатов с данными прошлой недели.

Используемые флаги:

  • --severity принимает значения critical, high, medium, low или negligible и фильтрует вывод.
  • --format принимает значения json или csv. JSON используется по умолчанию.
  • --sort-by принимает значения package или cve.
  • --suite переопределяет автоматически определенное кодовое имя Debian.
  • --no-cache пропускает кэшированный канал данных и загружает свежий.
  • -v выводит логи работы инструмента в stderr, включая загруженные URL.

debvulns также загружает оценки EPSS (exploit prediction scoring system) и добавляет их к каждой найденной уязвимости. EPSS — это публикуемая ежедневно оценка вероятности того, что CVE будет использована в течение следующих тридцати дней. Это полезное дополнение к базовой оценке CVSS (common vulnerability scoring system), так как CVSS описывает тяжесть последствий ошибки, а EPSS — вероятность того, что кто-то попытается ее эксплуатировать.

Применяется то же предупреждение, что и для debsecan. Канал данных принадлежит Debian, поэтому запускайте debvulns в Debian. В Ubuntu инструментом, соответствующим вашему архиву, является pro cves.

Экспорт количества CVE в Prometheus

Если вы уже используете систему мониторинга, экспортер преобразует эти данные в числовое значение, по которому можно настроить алерты, вместо того чтобы полагаться на отчеты, которые никто не открывает.

sudo useradd --system --no-create-home --shell /usr/sbin/nologin debvulns

Напишите /etc/systemd/system/debvulns-exporter.service:

[Unit]
Description=debvulns Prometheus exporter
Wants=network-online.target
After=network-online.target

[Service]
Type=simple
User=debvulns
ExecStart=/opt/debvulns/bin/debvulns-exporter --port 9222 --refresh-interval 21600 --cache-dir /var/cache/debvulns-exporter
CacheDirectory=debvulns-exporter
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
Restart=on-failure
RestartSec=30

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now debvulns-exporter
curl -s localhost:9222/-/ready
curl -s localhost:9222/metrics | grep -c debvulns_

CacheDirectory=debvulns-exporter — это то, что делает ProtectSystem=strict работоспособным: systemd создает /var/cache/debvulns-exporter, владельцем которого является пользователь сервиса, и это единственный путь, доступный процессу для записи. /metrics возвращает HTTP 503 до завершения первого сканирования, а /-/ready возвращает 200 только после его окончания. Таким образом экспортер не публикует нулевое значение, которое еще не было измерено. /-/healthy возвращает 200 сразу после запуска процесса, поэтому используйте его для проверки работоспособности (liveness), а /-/ready — для готовности к сбору метрик (readiness).

Метрики, на основе которых стоит создавать правила:

  • debvulns_vulnerabilities_total — совокупное количество, с метками по уровню критичности, наличию исправлений и доступности извне.
  • debvulns_vulnerability_info — один ряд данных на каждый CVE и пакет, содержащий идентификатор CVE в качестве метки.
  • debvulns_vulnerability_epss_score — вероятность EPSS для каждого CVE.
  • debvulns_scan_status — принимает значение 1, если последнее сканирование прошло успешно, и 0, если оно завершилось ошибкой.
  • debvulns_last_scan_timestamp_seconds — фиксирует время выполнения последнего сканирования.

Перед написанием правила проверьте точные значения меток на своем сервере, так как селектор, который ничего не находит, никогда не сработает и будет выглядеть так же, как на исправном сервере:

curl -s localhost:9222/metrics | grep '^debvulns_vulnerabilities_total'

Затем создайте два правила:

groups:
  - name: debvulns
    rules:
      - alert: FixableCriticalCVE
        expr: sum by (instance) (debvulns_vulnerabilities_total{severity="critical", fix_available="true"}) > 0
        for: 6h
        annotations:
          summary: "A critical CVE with an available fix has stayed open for six hours"
      - alert: CVEScanStale
        expr: time() - debvulns_last_scan_timestamp_seconds > 172800
        for: 30m
        annotations:
          summary: "CVE data on this host is more than two days old"

Условие for: 6h обеспечивает достоверность первого алерта. Без него вы будете получать уведомления о CVE, которые были бы закрыты автоматическим обновлением через двадцать минут, а алерт, который разрешается сам собой до того, как вы успели его прочитать, приучает игнорировать последующие оповещения. С этим условием вы будете получать уведомления только о тех проблемах, которые остались после автоматического применения патчей.

Второе правило — это то, о чем часто забывают. Сканер, который перестал работать, сообщает о нулевом количестве уязвимостей, а ноль на дашборде выглядит как признак исправной системы. Настраивайте алерты как на содержимое данных, так и на их актуальность.

Что не видит сканер пакетов

Эта граница проходит резче, чем ожидает большинство пользователей. Подобные инструменты сравнивают версии установленных пакетов с базой данных уязвимостей, и вся их информация поступает из базы данных dpkg. Всё, что не было установлено через менеджер пакетов, остаётся невидимым.

Это исключает:

  • Всё содержимое Docker-образов. Сканер видит пакет docker.io на хосте, но ничего не знает о пользовательском окружении, интерпретаторах или библиотеках внутри ваших контейнеров.
  • Любые зависимости pip, npm, cargo и go, включая те, что были загружены образом во время сборки.
  • Статические бинарные файлы и всё, что было установлено из архивов или через curl ... | sh, так как они не содержат метаданных пакетов.
  • Программное обеспечение, которое вы скомпилировали самостоятельно, даже если его версия совпадает с версией пакета из дистрибутива.

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

Актуальность ответа зависит от кэшированной ленты данных

Все инструменты здесь используют кэширование. debvulns записывает данные в /var/cache/debvulns, если это возможно, или использует ~/.cache/debvulns в противном случае; повторная загрузка выполняется только в том случае, если кэшу более 24 часов. debsecan --cron загружает данные один раз в календарный день. Экспортер по умолчанию использует интервал обновления 24 часа и отклоняет любые значения менее 3600 секунд.

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

/opt/debvulns/bin/debvulns --no-cache --severity critical
ls -l --time-style=long-iso /var/cache/debvulns

Правило CVEScanStale, приведенное выше, выполняет это действие для всех хостов. Это разница между «критических CVE не найдено» и «нет данных с четверга» — на графике они выглядят одинаково, но по сути это совершенно разные ситуации.

Когда CVE требует перезагрузки

Обновленный пакет на диске не означает, что процесс в памяти тоже обновлен. apt upgrade заменяет файл, но долгоживущий процесс продолжает использовать копию, которую он загрузил в память при запуске. needrestart находит такие процессы.

sudo apt install -y needrestart
sudo needrestart -r l
sudo needrestart -b -k

-r l выводит список того, что нужно перезапустить, не внося никаких изменений. -b — это пакетный режим, который выводит машиночитаемые строки вместо диалогового окна:

NEEDRESTART-KCUR: 6.12.48-amd64
NEEDRESTART-KEXP: 6.12.57-amd64
NEEDRESTART-KSTA: 3

KCUR — это ядро, которое вы используете в данный момент. KEXP — это самое новое ядро, установленное на диске. Если они различаются, KSTA возвращает 3, что означает необходимость перезагрузки. needrestart -o выводит те же данные в формате OpenMetrics, если вы предпочитаете собирать их метриками, а не парсить вывод.

Ubuntu также создает /var/run/reboot-required, когда post-installation скрипт пакета сообщает о необходимости перезагрузки, и указывает ответственные пакеты в /var/run/reboot-required.pkgs. Этот путь находится в tmpfs, поэтому он исчезает после каждой перезагрузки по замыслу разработчиков. pro system reboot-required отвечает на тот же вопрос одним словом и отдельно сообщает, если к работающему ядру уже был применен livepatch. В Debian такой файл по умолчанию не создается. Установите reboot-notifier (версия 0.12 в Debian 13) для получения совместимого аналога или используйте needrestart, который работает одинаково в обоих дистрибутивах.

Правило принятия решения в порядке приоритета:

  1. CVE относится к разделяемой библиотеке, исправленный пакет установлен, а needrestart -r l называет сервисы, которые все еще используют старую копию. Перезапустите эти сервисы. Перезагрузка не требуется.
  2. CVE относится к ядру, и KCUR отличается от KEXP. Только перезагрузка позволяет заменить работающее ядро, если вы не используете live kernel patching на VPS, который покрывает подмножество исправлений ядра, применимых к работающей системе.
  3. Для CVE нет исправления в вашем релизе, что отображается как no DSA в Debian или Origin со статусом - в Ubuntu. Перезагрузка ничего не изменит. Зафиксируйте наличие уязвимости или минимизируйте риски, отключив затронутую функцию.
  4. Сканер показывает CVE, но ни один доступный процесс не использует этот пакет. Исправьте его в рамках обычного цикла обновлений. Уязвимость в библиотеке, с которой скомпилирована только ваша локальная команда man, не является инцидентом.

Ритм, который сохраняется в спокойный месяц

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

Запускайте сканирование ежедневно и без участия оператора. В Debian это запись debsecan в cron с установленным REPORT или собственный цикл обновления экспортера. Позвольте unattended upgrades устанавливать исправления безопасности по собственному расписанию, чтобы задача сканера состояла в отчете о том, что автоматика не смогла закрыть, а не в том, чтобы быть вашей единственной защитой.

Настройте оповещение по одному показателю, а не по всему отчету. Исправимые уязвимости критического уровня, сохраняющиеся более шести часов, — это порог, который большинство одиночных серверов преодолевают несколько раз в год. Это происходит достаточно редко, чтобы вы действительно прочитали уведомление, когда оно придет. Все остальное место на дашборде, который вы просматриваете во время ежемесячного обслуживания сервера.

Запишите правило перезагрузки до того, как оно вам понадобится, потому что применять его придется в неудобное время. CVE ядра с отличающимся KEXP означает необходимость планирования перезагрузки. CVE в библиотеке означает перезапуск сервисов, которые перечислены в needrestart. Если исправления нет, зафиксируйте это в журнале и проверьте снова в следующем месяце.

Пересматривайте свои исключения раз в квартал. Список объектов, существующих вне dpkg, только растет: контейнер, который кто-то добавил, или бинарный файл, помещенный в /usr/local/bin. Каждый такой объект — это место, где сканер сообщает об отсутствии проблем, потому что он их не видит. При управлении парком серверов ведите этот реестр вместе с инструментами для администрирования нескольких серверов Linux, чтобы исключения были видны не только вам.

FAQ

Как получить список CVE, затрагивающих мой сервер Debian?

Установите debsecan и выполните debsecan --suite trixie, указав кодовое имя используемого вами релиза. Каждая строка вывода содержит одну запись CVE и один установленный бинарный пакет, а слово fixed в скобках означает, что исправленная версия уже доступна в архиве. Добавьте --only-fixed --format packages, чтобы сократить вывод до списка пакетов, которые можно обновить прямо сейчас. Для получения вывода в формате JSON и оценок EPSS установите debvulns в виртуальное окружение, созданное с помощью --system-site-packages, чтобы обеспечить импорт python3-apt.

Почему сканер продолжает сообщать о CVE, которую apt не может исправить?

Потому что команда безопасности Debian пометила эту проблему как no DSA для вашего релиза. Это означает, что она признана недостаточно критичной для выпуска обновления в стабильной ветке, поэтому исправленный пакет не будет выпущен. Эквивалентом в Ubuntu является статус Origin со значением - в выводе pro cves. Уязвимость CVE действительно присутствует на вашей машине, и сканер корректно продолжает её отображать. Используйте debsecan --only-fixed или pro cves --fixable, чтобы видеть только те уязвимости, которые вы можете устранить, а остальные проверяйте во время планового обслуживания.

Видит ли сканер CVE уязвимости внутри моих Docker-контейнеров?

Нет. Эти инструменты считывают только базу данных dpkg хостовой системы, поэтому они видят пакет docker.io и ничего не знают об операционной системе или библиотеках внутри ваших образов. Та же «слепая зона» касается всех зависимостей pip или npm, а также любого ПО, установленного из архивов tarball. Сканируйте образы контейнеров на этапе сборки с помощью специализированного сканера образов, а зависимости языков программирования рассматривайте как отдельную проблему с иным механизмом устранения.

Когда CVE действительно требует перезагрузки?

Только если исправление затрагивает ядро. Выполните sudo needrestart -b -k и сравните NEEDRESTART-KCUR (текущее запущенное ядро) с NEEDRESTART-KEXP (самой новой установленной версией). Если они различаются, NEEDRESTART-KSTA вернет 3, что означает необходимость перезагрузки. Для CVE в разделяемой библиотеке исправленный файл уже находится на диске, и вам нужно лишь перезапустить процессы, которые всё ещё используют старую копию в памяти; их список покажет sudo needrestart -r l.

Могу ли я запустить debsecan на сервере Ubuntu?

Он устанавливается из репозитория universe, но выдает неверные результаты. debsecan считывает данные из трекера безопасности Debian, который не отслеживает проблемы Ubuntu и не распознает строки версий Ubuntu, такие как 3.0.13-0ubuntu3.4. В результате вы получите ложные срабатывания по проблемам, которые Canonical давно исправила, и отсутствие информации по специфичным для Ubuntu уязвимостям. Мост ust2dsa, который когда-то преобразовывал данные Ubuntu в формат debsecan, был переведен в архив в октябре 2021 года, и его лента обновлений больше не работает. Используйте pro cves в Ubuntu.

#cve#debian#ubuntu#vulnerability-scanning#monitoring#security