Контейнерная безопасность: сканирование образов и политики
сен, 11 2026
Знаете, что самое страшное для DevOps-инженера? Не падение сервера в три часа ночи. А то, что продакшн упал из-за уязвимости в образе, который вы собрали полгода назад и с тех пор не трогали. Контейнерная безопасность - это не просто модное слово из презентаций про DevSecOps. Это ежедневная рутина, которая отделяет спокойные выходные от аврала.
Если вы используете Docker или Kubernetes, вы уже создали поверхность атаки. Каждый слой вашего образа - это потенциальная дыра. И да, «мы же используем Alpine Linux, там мало пакетов» - это не защита, а самообман. Давайте разберемся, как реально защитить контейнеры, не превратив CI/CD в бесконечный цикл проверок.
Почему старые методы защиты не работают с контейнерами
Раньше мы ставили антивирус на сервер, настраивали firewall и считали себя в безопасности. С контейнерами эта логика ломается. Образы собираются динамически, живут недолго, их сотни. Вы не можете просканировать каждый запущенный контейнер вручную. К тому же, большинство уязвимостей (CVE) находятся не в вашем коде, а в базовых образах и зависимостях внутри них.
Представьте: вы обновили библиотеку openssl в своем приложении, но забыли обновить базовый образ ubuntu:18.04. В итоге приложение работает, тесты проходят, а в продакшене крутится старый OpenSSL с известной дырой. Сканирование образов решает именно эту проблему - оно заглядывает внутрь каждого слоя и сверяет версии пакетов с базами данных уязвимостей.
Сканирование образов: инструменты и процесс
Самый эффективный способ найти проблемы до деплоя - статический анализ образа. Здесь правят бал несколько инструментов, и выбор зависит от вашего стека и бюджета.
| Инструмент | Тип | Основное преимущество | Недостатки |
|---|---|---|---|
| Trivy | Open Source CLI | Простота установки, поддержка файлов конфигурации, скорость | Меньше интеграций с enterprise-системами по умолчанию |
| Clair | Self-hosted сервис | Глубокая интеграция с реестрами, детальная отчетность | Сложный деплой, требует базы данных PostgreSQL |
| Snyk Container | SaaS / Hybrid | Отличные рекомендации по исправлению, фиксы PR | Дорогой для больших команд, зависимость от вендора |
| Harbor Scanner | Встроенный в Harbor | Работает «из коробки» с реестром Harbor | Ограниченная гибкость настроек |
Для большинства проектов я рекомендую начать с Trivy. Он легкий, не требует сложной инфраструктуры и умеет сканировать не только образы, но и файлы кода, IaC-конфиги (Terraform, Helm). Запустить его в пайплайне можно одной строкой:
- Установите Trivy в сборщик (GitLab CI Runner, Jenkins Agent).
- Добавьте шаг после сборки образа:
trivy image --severity HIGH,CRITICAL my-app:latest. - Настройте выход с ошибкой (
--exit-code 1), если найдены критические уязвимости.
Но помните: сканер найдет уязвимость, он не починит её. Ваша задача - иметь процесс обновления базовых образов. Если сканер ругается на glibc, вам нужно пересобрать образ с более свежим базовым слоем, а не игнорировать предупреждение.
Политики безопасности: от слов к действиям
Сканирование - это половина дела. Вторая половина - контроль того, что вообще попадает в кластер. Тут на сцену выходят политики безопасности. Без них любой разработчик может залить образ с тегом :latest, запустить его от root и открыть порт 22 наружу. И никто ему не запретит.
В мире Kubernetes стандартом де-факто стали политики OPA Gatekeeper или более легковесный Kyverno. Они работают как вебхуки: проверяют манифесты перед тем, как Kubernetes их примет.
Какие политики стоит внедрить в первую очередь?
- Запрет привилегированных контейнеров. Никогда не запускайте поды с флагом
privileged: trueбез крайней необходимости. Это дает контейнеру полный доступ к хосту. - Запрет запуска от root. Требуйте указания
runAsNonRoot: trueв SecurityContext. Это усложняет жизнь злоумышленнику, который получит шелл внутри контейнера. - Обязательные ресурсы. Требуйте указание
requestsиlimitsCPU/RAM. Без этого один жадный под может убить весь узел. - Белый список реестров. Разрешайте тянуть образы только из вашего внутреннего Harbor или ECR. Забудьте про публичный Docker Hub в продакшене.
Если вы используете Kyverno, правило будет выглядеть примерно так:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-non-root-user
spec:
validationFailureAction: enforce
rules:
- name: check-runAsNonRoot
match:
resources:
kinds:
- Pod
validate:
message: "runAsNonRoot must be set to true"
pattern:
spec:
securityContext:
runAsNonRoot: true
Такой подход превращает безопасность из «советов» в жесткое требование платформы. Разработчик просто не сможет задеплоить небезопасный манифест.
RBAC и сетевые политики: кто кому друг
Даже если образ чистый, а манифест правильный, безопасность может быть сломана на уровне доступа. Кто имеет право создавать новые Deployments? Может ли под из namespace frontend обращаться к базе данных в namespace backend?
Начните с Kubernetes RBAC. Уберите права на создание ресурсов у всех, кроме CI/CD систем и администраторов. Разработчики должны работать через GitOps, где изменения мержатся через pull request, а не через kubectl apply напрямую в кластер.
Далее - сетевые политики. По умолчанию в Kubernetes все поды могут общаться друг с другом. Это удобно для разработки, но ужасно для безопасности. Используйте CNI-плагины, поддерживающие NetworkPolicies (Calico, Cilium), чтобы создать сегментацию.
Пример простой политики: разрешаем доступ к бэкенду только от фронтенда.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-backend
namespace: backend
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
Это создает микропериметры. Даже если злоумышленник скомпрометирует один сервис, он не сможет свободно латерально перемещаться по кластеру.
Практические советы: как не сойти с ума
Внедрение безопасности часто буксует из-за шума. Сканеры находят тысячи уязвимостей низкого уровня, которые никто не хочет чинить. Вот несколько эвристик, которые помогают сохранить рассудок:
- Фильтруйте по CVSS Score. Игнорируйте уязвимости с оценкой ниже 7.0, если они не затрагивают внешние интерфейсы. Фокусируйтесь на High и Critical.
- Используйте SBOM. Software Bill of Materials - это инвентарь компонентов вашего образа. Инструменты вроде Syft генерируют SBOM автоматически. Это спасает при аудитах и расследованиях инцидентов.
- Автоматизируйте обновление base images. Настройте Renovate или Dependabot на обновление Dockerfile. Если вы используете
alpine:3.19, пусть робот сам создает PR наalpine:3.20, когда выходит новый релиз. - Секреты в секретах. Никогда не храните пароли в переменных окружения в открытом виде в манифестах. Используйте External Secrets Operator или HashiCorp Vault для инъекции секретов во время запуска пода.
Помните, что безопасность - это процесс, а не состояние. Вы никогда не достигнете «полной безопасности». Но вы можете достичь приемлемого уровня риска, где автоматизация берет на себя рутину, а люди решают сложные архитектурные вопросы.
Нужно ли сканировать каждый коммит в репозитории?
Нет, это избыточно и дорого. Оптимальная стратегия - сканировать образы на этапе сборки артефакта (CI) и повторно сканировать уже развернутые образы в реестре (например, еженедельно), так как новые CVE появляются постоянно. Для веток разработки достаточно сканирования только измененных слоев или использования кэша результатов.
Что делать, если сканер нашел критическую уязвимость, но патча нет?
Проверьте, эксплуатируется ли уязвимость в вашей конфигурации (часто бывает, что библиотека есть, но функция не используется). Если риск подтвержден, попробуйте заменить библиотеку на альтернативную или закрыть сетевой доступ к сервису. Также рассмотрите использование дистрибутивов с долгосрочной поддержкой (LTS), где вендор выпускает патчи быстрее, чем апстрим.
Чем отличается OPA Gatekeeper от Kyverno?
OPA Gatekeeper использует язык Rego, который очень мощный, но сложный для изучения новичками. Kyverno использует YAML и JMESPath, что делает его более понятным для Kubernetes-администраторов. Gatekeeper лучше подходит для сложных, нестандартных политик в крупных энтерпрайзах, а Kyverno идеален для быстрого старта и стандартных требований безопасности.
Как обеспечить безопасность образов при использовании Docker Hub?
Не используйте образы с Docker Hub напрямую в продакшене. Сначала скачивайте их в свой внутренний реестр (Harbor, Artifactory), сканируйте там, и только затем деплойте в кластер. Это защищает вас от изменений удаленного образа и позволяет контролировать целостность через подписи (Cosign/Sigstore).
Стоит ли использовать distroless образы?
Да, если ваше приложение позволяет. Distroless образы содержат только приложение и его зависимости, без shell,包менеджеров и других утилит ОС. Это значительно уменьшает поверхность атаки и размер образа. Однако отладка таких контейнеров сложнее, так как в них нельзя зайти через kubectl exec и получить шелл.