Откуда в контуре Directum RX образы и пакеты: свой реестр, подписи, SBOM и что делать с отчётом сканера
Цепочка поставок ПО для инсталляции Directum RX на Linux. Из каких источников приходят образы, пакеты и чарты, зачем свой реестр, как проверять подписи и контрольные суммы, что такое SBOM и как разбирать отчёт сканера уязвимостей, чтобы не утонуть в сотнях находок.
Коротко. Разделите источники: что исправляете вы, что вендор. Ставьте всё из своего реестра по дайджесту, проверяйте подписи и суммы до установки, храните SBOM каждого образа и сканируйте по расписанию. Исключения заводите с причиной и сроком, а находки в продукте вендора передавайте вендору.
Служба ИБ присылает отчёт сканера по образам Directum RX: четыреста уязвимостей, из них тридцать критических, просьба устранить до конца месяца. Администратор открывает отчёт и видит, что половина находок в пакетах базового образа, которые никто не ставил, четверть в библиотеках вендора, а у остальных «исправления нет». Разговор быстро сводится к «мы тут ничего не можем». Сделать можно многое, если знать, откуда в контуре берётся каждый компонент и что из этого под вашим контролем.
Симптом
- Отчёт сканера на сотни строк, и непонятно, что из него делать в первую очередь.
- На вопрос «откуда взялся этот образ и кто его проверял» ответа нет: его когда-то скачали с Docker Hub.
- Установка на новый сервер перестаёт работать в один день, потому что образ или пакет удалили из внешнего источника.
- На тестовом и продуктивном контуре под одним тегом разное содержимое.
- В договоре с заказчиком или в требованиях регулятора появилось слово «SBOM», и никто не знает, где его взять.
Почему так
В инсталляции RX на Linux компоненты приходят из нескольких источников, и у каждого свой владелец.
| Компонент | Откуда приходит | Кто может исправить уязвимость |
|---|---|---|
| Образы сервисов RX | дистрибутив вендора | вендор; базовый слой иногда можно пересобрать самим |
| PostgreSQL, RabbitMQ, Elasticsearch, nginx | пакеты ОС или публичные образы | вы, обновлением версии |
| Пакеты ОС на серверах | репозитории дистрибутива | вы, обновлением |
| Helm-чарты, роли Ansible, коллекции | публичные репозитории, свои репозитории | вы |
| Инструменты администратора (сканеры, утилиты, скрипты) | что угодно, часто curl \| bash |
вы |
Отчёт сканера смешивает всё это в одну таблицу. Пока источники не разделены, каждая находка выглядит одинаково срочной, и работа по отчёту не начинается.
Вторая причина в том, что внешние источники ненадёжны как хранилище. Публичный реестр может удалить образ, перенести его в архивный каталог или перевесить тег на другое содержимое. Подробно про теги и дайджесты рассказано в заметке про дайджест образа.
Диагностика
Что вообще стоит в контуре
Первый шаг это список. Для контейнеров он снимается за минуту.
# Docker на сервере: образы работающих контейнеров с дайджестами
docker ps --format '{{.Image}}' | sort -u | xargs -n1 docker inspect --format '{{index .RepoDigests 0}}'
# Kubernetes: все образы во всех пространствах имён
kubectl get pods -A -o jsonpath='{range .items[*]}{range .spec.containers[*]}{.image}{"\n"}{end}{end}' | sort -u
Если в списке есть образы, которые скачиваются напрямую с docker.io, quay.io или ghcr.io, это первое,
что стоит исправить.
Для пакетов ОС полезно убедиться, что все подключённые репозитории проверяются подписью:
grep -rn "trusted=yes" /etc/apt/sources.list /etc/apt/sources.list.d/ 2>/dev/null
grep -rn "gpgcheck=0" /etc/yum.repos.d/ 2>/dev/null
Каждая найденная строка означает, что пакеты из этого репозитория ставятся без проверки подписи.
Из чего состоит образ: SBOM
SBOM (Software Bill of Materials) это опись компонентов образа или приложения: пакеты ОС, библиотеки, их версии и лицензии. Два распространённых формата: CycloneDX и SPDX. Снимать опись умеют свободные инструменты.
syft registry.example.local/rx/webserver:25.2 -o cyclonedx-json > webserver.cdx.json
trivy image --format cyclonedx --output webserver.cdx.json registry.example.local/rx/webserver:25.2
Опись нужна не для галочки. С ней можно через полгода ответить на вопрос «есть ли у нас уязвимая версия библиотеки X», не сканируя всё заново: достаточно поискать по сохранённым описям.
trivy sbom webserver.cdx.json
grype sbom:./webserver.cdx.json
Сканирование и разбор отчёта
trivy image --severity HIGH,CRITICAL registry.example.local/rx/webserver:25.2
Отчёт удобнее читать, разложив по слоям.
- Пакеты базовой ОС образа. Лечатся пересборкой на свежем базовом образе. Для своих образов это ваша работа. Для образов вендора смотрите, описана ли в документации сборка на своей базе: в справке RX для компаний со строгими требованиями к безопасности такой путь есть.
- Среда выполнения (.NET, Java, Python). Обычно обновляется вместе с версией продукта.
- Библиотеки приложения. Для своего кода это ваша работа. Для продукта вендора ваше действие одно: передать вендору список находок с идентификаторами CVE и версией продукта и спросить, в какой версии исправлено.
- Компоненты рядом с RX (PostgreSQL, RabbitMQ, Elasticsearch, nginx). Обновляются вами в рамках поддерживаемых вендором версий. Перед обновлением сверьтесь с матрицей совместимости.
Флаг --ignore-unfixed убирает из отчёта находки, для которых исправления не существует. Их не стоит забывать
совсем, но и в план работ на этот месяц они не входят.
Что сделать
1. Свой реестр и зеркало
Все образы, чарты и пакеты ставятся из своего хранилища: Harbor, Nexus, реестр GitLab или аналог. Внешние источники подключаются к нему как зеркало или прокси-кэш, серверы контура ходят только в своё хранилище.
При переносе образа в зеркало важно сохранить дайджест. skopeo копирует образ со всеми платформами без
перепаковки:
skopeo copy --all docker://docker.io/library/nginx:1.27.5 docker://registry.example.local/mirror/nginx:1.27.5
После копирования дайджест в своём реестре должен совпасть с исходным. Если не совпал, образ пересобрали или перепаковали по дороге, и он больше не тот, что публиковал автор.
2. Проверка подлинности до установки
- Файлы и дистрибутивы сверяются по опубликованным контрольным суммам:
sha256sum -c. - Пакеты ОС проверяются подписью репозитория. Ключ подключается через
signed-byдля конкретного репозитория, а не в общий список доверенных ключей. - Образы проверяются подписью, если автор их подписывает. Многие открытые проекты подписывают образы через Sigstore cosign:
cosign verify registry.example.local/mirror/app@sha256:... \
--certificate-identity-regexp 'https://github.com/project/.*' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
Свои образы стоит подписывать своим ключом в сборочном конвейере, а опись прикладывать к образу как аттестацию. Тогда и образ, и его опись лежат рядом в реестре.
cosign sign --key cosign.key registry.example.local/own/tool@sha256:...
cosign attest --key cosign.key --type cyclonedx --predicate tool.cdx.json registry.example.local/own/tool@sha256:...
3. Ставить по дайджесту
В конфигурации установки образ указывается вместе с дайджестом: nginx:1.27.5@sha256:.... Тег остаётся для
человека, дайджест определяет, что будет скачано. Дайджест каждой установленной версии записывается в журнал
изменений.
4. Не пускать в кластер чужое
В Kubernetes правило «только из своего реестра» можно закрепить политикой допуска (Kyverno, OPA Gatekeeper): под с образом из другого реестра просто не создастся. Как вводить такие политики без остановки RX, рассказано в статье про политики в кластере.
5. Сканирование по расписанию
Новые уязвимости публикуют каждый день, поэтому образ, чистый в понедельник, через месяц уже нет. Сканирование по сохранённым описям раз в сутки дешевле, чем повторное скачивание образов. Результат удобно сводить в одну метрику по числу критических находок на образ и следить за её ростом.
Сканер запускается на отдельной машине или в сборочном конвейере. На узлах управления кластером ему не место: он активно пишет на диск и может отнять дисковую очередь у etcd.
6. Исключения с причиной и сроком
Находка, которую нельзя или не нужно исправлять, вносится в список исключений (.trivyignore или формат VEX)
с причиной и датой пересмотра. Например: «уязвимость в модуле, который в образе не вызывается, пересмотреть
при обновлении до следующей версии». Исключение без причины через год никто не сможет объяснить.
Что из этого спросит проверяющий
Методика ФСТЭК об уровне зрелости, которую мы разбирали отдельно, и требования к безопасной разработке сводятся к нескольким вопросам. Откуда пришёл компонент? Проверена ли его подлинность? Есть ли опись? Как вы узнаёте о новых уязвимостях и как решаете, что с ними делать? Если пункты выше сделаны, ответ на каждый вопрос это ссылка на реестр, журнал или конвейер.
Свои роли Ansible и Helm-чарты читаются на ревью быстрее, когда модуль, параметры и шаблоны окрашены по смыслу. Настройка VS Code для этого описана в статье про подсветку Ansible.
Чего не делать
- Не скачивать образы и пакеты на продуктивный контур напрямую из интернета. Внешний источник может исчезнуть или поменять содержимое.
- Не отключать проверку подписи (
trusted=yes,gpgcheck=0), чтобы «быстро поставить». - Не требовать ноль уязвимостей. Такая цель приводит к массовым исключениям без причины. Цель реалистичнее: нет критических находок с доступным исправлением старше оговорённого срока.
- Не пересобирать образы вендора своими силами без описанной вендором процедуры. Поддержка вправе отказаться разбирать проблему на изменённом образе.
- Не выкладывать отчёты сканера по чужому продукту в открытый доступ. Находки передаются вендору, а не публикуются.
Похожая картина у вас?
Разберём ваш контур за 30 минут бесплатного созвона: версия RX, состав сервисов, что болит сильнее всего.
Написать