Лучшие практики защиты цепочки поставок для контейнерных workloads
Введение
С ростом числа атак, направленных на открытые компоненты, защита цепочки поставок становится обязательной частью процесса доставки контейнерных приложений. В этой статье собраны практические рекомендации, которые помогут командам, работающим с Docker на Linux‑серверах или VPS, построить повторяемый и проверяемый процесс от выбора базового образа до мониторинга работы в продакшене.
1. Начинайте с доверенного контента
Образ, полученный от базового слоя, наследует его уязвимости и лишние компоненты. Поэтому первым шагом является выбор минимальных, постоянно обновляемых образов с подтверждённой provenance.
- Ищите образы, которые поставляются вместе с SBOM, подписью и attestation уровня SLSA Build 3.
- Предпочитайте «закреплённые» (hardened) образы, собранные из исходного кода в изолированной среде – они уже содержат минимальный набор пакетов и не включают оболочки или менеджеры пакетов, которые редко нужны в production.
- Если вы используете собственный Dockerfile, фиксируйте ссылки на базовый образ по SHA256‑дагесту, а не по тегу. Это предотвращает незаметное изменение upstream‑слоя.
2. Защищайте процесс сборки
Даже идеальный образ может быть скомпрометирован, если среда CI/CD не доверена. Необходимо обеспечить целостность сборки и ограничить доступ к секретам.
- Настройте CI‑систему генерировать подписанные provenance‑attestations (формат in‑toto) для каждого артефакта и привязывать их к коммиту, конфигурации сборки и идентификатору сборщика.
- Изолируйте задачи сборки: каждый job запускайте в свежем efemерном контейнере без остаточного состояния от предыдущих запусков.
- Ограничьте набор секретов, доступных сборке, только тем, что действительно необходимо для данного шага.
- Фиксируйте версии используемых действий и плагинов (например, GitHub Actions) по полному SHA коммита, а не по изменяемому тегу.
- Включите защиту веток: требуйте код‑ревью и прохождения всех статус‑проверок перед слиянием в релиз‑ветку.
3. Проверяйте перед развёртыванием
SBOM и provenance работают вместе: первый показывает «что внутри», второй – «как и где собрано». Их совместное использование даёт возможность быстро реагировать на новые уязвимости.
- Генерируйте SBOM при каждой сборке и прикрепляйте его к образу в виде attestation. Инструменты вроде
syftилиdocker scout sbomпозволяют это сделать автоматически. - Подписывайте SBOM и образ (например, с помощью
cosign) и проверяйте подписи в политиках допуска (admission controller) перед запуском в кластере. - Дополняйте SBOM данными VEX (Vulnerability Exploitability eXchange), чтобы отмечать, какие уязвимости действительно эксплуатируются в вашем конкретном образе. Это снижает шум и фокусирует усилия по исправлению.
- Интегрируйте сканирование уязвимостей в_inner loop_ разработки: показывайте результаты в pull‑request‑ах и локальном терминале, а не только в еженедельных отчётах.
# Пример сборки с фиксированным дагестом и генерацией SBOM
# 1. Выбираем базовый образ по дагесту
BASE_IMAGE=docker.io/library/python@sha256:a62f8b8c1e5c1d5e9f7a3b4c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e
# 2. Сборка
DOCKER_BUILDKIT=1 docker build --build-arg BASE_IMAGE=$BASE_IMAGE -t myapp:latest .
# 3. Формируем SBOM и подписываем образ
syft myapp:latest -o json > sbom.json
cosign sign --key cosign.key --yes myapp:latest
# 4. Прикрепляем SBOM как attestation (пример с cosign)
cosign attest --predicate sbom.json --type application/vnd.in-toto+json myapp:latest
4. Управляйте доступом и enforce политики
Реестр контейнеров – точка распространения всех артефактов. Ограничьте, какие образы могут быть использованы в production, и проверяйте их подлинность перед запуском.
- Настройте политики доступа к реестру: разрешайте pull только из доверенных пространств имён или из внутренних сборок, требующих подпись.
- Требуюйте проверку подписи (cosign, Notary v2) перед тем, как образ будет допущен к запуску.
- Применяйте принцип наименьших привилегий ко всем токенам и сервисным аккаунтам в CI/CD: каждый credential получает только те права, которые необходимы для своей задачи.
- Разделяйте права: учётные записи сборки не должны иметь возможности push в production‑реестр, а токены деплоя не должны изменять конфигурацию сборки.
- Включите MFA, устойчивое к фишингу, для всех учётных записей разработчиков и CI‑систем.
5. Мониторьте, реагируйте и улучшайте
Статический анализ не ловит всё, что может произойти в рантайме. Необходимо добавить слой наблюдения за поведением работающих контейнеров.
- Сформируйте базовый профиль поведения (сетевые подключения, файловая система, запущенные процессы) для каждого образа в стабильной среде.
- Настройте оповещение об отклонении от этого профиля: новые исходящие соединения, изменение файлов в read‑only слое, нетипичные запуски процессов.
- Интегрируйте такие данные в систему реагирования: при обнаружении аномалии быстро определяйте по provenance и SBOM, какие образы и сборки могли быть затронуты, отзывайте compromised credentials, пересобирайте образы из проверенных источников и уведомляйте downstream‑потребителей.
- Проводите регулярные тренировки по сценариям компрометации базового образа, утечки секретов в CI или атаки на сборочную инфраструктуру – это сокращает время реакции с дней до часов.
Заключение
Защита цепочки поставок – это не разовая проверка, а инженерная дисциплина, которая строится на слоях: доверенный контент → проверяемая сборка → прозрачные артефакты → контролируемый доступ → непрерывный мониторинг. Начиная с фиксации базовых образов по дагесту и генерации SBOM при каждой сборке, вы сразу уменьшаете поверхность атаки. Постепенно добавляя подписи, политики доступа и runtime‑анализ, получаете систему, способную обнаруживать и нейтрализовать даже те угрозы, которые прошли стадийные проверки.