Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!
Привет! Меня зовут Михаил Черешнев, я работаю в компании Swordfish Security, где плотно занимаюсь вопросами внедрения DevSecOps. В этой статье мы рассмотрим процесс безопасной разработки контейнеризированных приложений от IaC манифестов до Runtime. А также попробуем определить самые простые и эффективные методы обеспечения защищенности и приземления технологий с минимальными затратами.
Введение
Практики безопасности — это конкретные действия и методы, которые используются для реализации определенных подходов или достижения конкретных целей ИБ. В качестве примеров можно привести регулярное проведение аудиторских проверок безопасности системы или применение многофакторной аутентификации. Практики в свою очередь подкрепляются инструментами, позволяющими реализовывать проверки защищенности.
А что же из себя представляет Container Security? Четкого определения у этого термина нет, поэтому мы постарались сформулировать его сами:
Container Security — это общее понятие, охватывающее набор различных инструментов и методов для защиты контейнеров от возможных угроз и атак. Сюда входят механизмы изоляции контейнеров друг от друга и от хостовой операционной системы, контроль доступа к ресурсам и файлам, мониторинг и логирование действий в контейнерах, шифрование данных и многое другое. Также в рамках Container Security рассматриваются вопросы, связанные с управлением и автоматизацией конфигураций контейнеров от начала сборки до выполнения в среде эксплуатации.
Практики Container Security
Попробуем разложить Container Security на дочерние практики.
SAST/Lint IaC
SAST — это статический анализ безопасности приложений. Практика используется для поиска потенциальных уязвимостей в исходном коде приложения без его запуска. SAST позволяет выявить такие проблемы, как незащищенные точки входа и выхода, возможности переполнения буфера и так далее.
IaC (инфраструктура как код) — это подход к созданию и управлению инфраструктурой через использование кода, например, конфигурационных файлов или скриптов.
Применение статического анализа безопасности приложений в модели «инфраструктура как код» (SAST IaC) позволяет проактивно находить потенциальные уязвимости в конфигурационных файлах и скриптах для автоматизации развертывания и управления системой. При помощи этого подхода можно обнаруживать недостатки безопасности до того, как они будут задействованы в рабочих нагрузках и смогут привести к серьезным последствиям.
От решения к решению артефакт IaC, передаваемый сканеру, может быть разным. Чаще всего, это Dockerfile, Helm Chart, K8S-yaml, Terraform. То, что находит SAST IaC, в значительной степени зависит от конкретного решения и настроенных в нем политик, а также правил обнаружения. Поэтому необходимо подбирать инструмент, который работает с нужными вам IaC файлами. Да и в целом, никто не мешает использовать в процессе сразу несколько механизмов в рамках одной практики.
SCA Image
SCA (Software Composition Analysis) — процесс анализа программного обеспечения на наличие сторонних компонентов и их зависимостей, используемых в приложении.
Image — это файл, который содержит всё необходимое для запуска приложения: код, библиотеки, настройки окружения и т. д. В контексте Docker, Image — это файл, который включает в себя всё необходимое для создания и запуска контейнера.
SCA Image позволяет обнаруживать уязвимости в компонентах, применяемых в Docker-образах, что помогает повысить уровень безопасности приложений, работающих в контейнерах. Например, SCA Image способен находить устаревшие или уязвимые версии библиотек, использование которых может привести к серьезным проблемам безопасности.
От решения к решению качество сканирований может значительно отличаться по разным причинам. Среди основных:
разница в источниках информации по уязвимостям;
поддержка/НЕподдержка различных ОС в составе образа;
поддержка/НЕподдержка различных пакетных менеджеров ОС;
поддержка/НЕподдержка различных пакетных менеджеров для ЯП.
Signing Image
Signing (подписание) в процессе DevSecOps означает добавление цифровой подписи к коду, бинарным файлам или другим артефактам, чтобы подтвердить их подлинность и целостность.
Это необходимо для обеспечения безопасности и защиты от нежелательных изменений или вмешательств злоумышленников. Благодаря подписи можно доказать, что код был создан конкретным разработчиком, а бинарный файл или артефакт находится в ожидаемом состоянии.
Проверка подписи может осуществляться на разных этапах процесса разработки: например, в ходе Continuous Integration (CI) или при деплое через Continuous Deployment (CD). В CI/CD системах поставок, таких как Jenkins, можно использовать соответствующие плагины и убедиться в том, что все артефакты прошли проверку подписи и являются оригинальными и не были изменены.
Admission Controlling
Admission Controlling — это процесс автоматической проверки ресурсов, генерируемых в Kubernetes, перед их созданием. Он позволяет администраторам контролировать доступ к кластеру и управлять им до того, как приложения начнут работу на узлах кластера.
Администраторы могут использовать Admission Controllers для определения правил доступа к кластеру, например, проверять наличие необходимых метаданных или сертификатов, ограничивать доступ по IP-адресу, предотвращать создание объектов с незаданными параметрами и т.д.
Admission Controller бывает как дефолтным, так и пользовательским. Каждый Admission Controller имеет определенную функциональность и может быть сконфигурирован под конкретное приложение и его требования. Admission Controller запускается после создания запроса API, но перед сохранением в etcd, базу данных, используемую Kubernetes. Если проверка завершается успешно, объект сохраняется.
Container Runtime Audit
Container Runtime Audit — это процесс записи аудитов событий и операций, выполняемых внутри контейнера. В рамках него предоставляется журнал всех операций на уровне ядра ОС, запущенных с использованием runC или другим контейнерным движком.
Container Runtime Control
Container Runtime Control — это способ обеспечения безопасности контейнеров через ограничение доступа к ресурсам системы, таким как CPU, память и сеть. Он представляет собой механизм, позволяющий контейнеру контролировать выполнение определенных операций, включая чтение и запись файлов, доступ к сетевым интерфейсам, создание новых процессов и т.д.
Host Runtime Audit
Host Runtime Audit — это процесс аудита и регистрации всех событий безопасности на хосте, на котором работает контейнер. Он позволяет отслеживать, какие задачи выполнялись на хосте во время работы контейнера, какие файлы были изменены и т.д.
Host Runtime Control
Host Runtime Control — набор инструментов, предназначенный для ограничения возможностей контейнера при выполнении операционных действий на хосте. Его основная роль заключается в том, чтобы более точно определять поведение контейнера и предотвращать проникновение злоумышленников в систему через уязвимости, найденные в контейнеризованных приложениях.
С помощью Host Runtime Audit и Host Runtime Control можно повысить уровень безопасности контейнерной платформы в целом.
Cluster Audit
Cluster Audit — это анализ конфигурации и действий в Kubernetes-кластере для выявления потенциальных уязвимостей и ошибок настроек. Он позволяет обнаруживать нарушения безопасности, которые могут привести к компрометации кластера, и принимать меры по их исправлению.
Cluster Security Benchmarking
Cluster Security Benchmarking — оценка безопасности Kubernetes-кластера, которая проводится при помощи определенного стандарта, набора проверок или сравнения с рекомендованными практиками безопасности. Этот процесс помогает определить, соответствует ли кластер заданному уровню безопасности, и предоставляет рекомендации по повышению уровня защищенности.
Observability
Observability в контексте безопасности контейнеров — это способность получать информацию о работе и поведении контейнеров, а также о состоянии инфраструктуры через сбор метрик, логов и трейсинга. Этот инструмент позволяет оперативно выявлять нарушения безопасности, идентифицировать уязвимости и проблемы в работе приложений и инфраструктуры. Например, с помощью observability можно обнаружить подозрительную активность или атаку на контейнерную среду, снизить время реагирования на инциденты и оптимизировать ресурсы на предприятии.
Процесс разработки контейнеризированных приложений
В качестве примера процесса разработки контейнерезированных приложений рассмотрим крайне упрощенную схему движения артефактов по этапам:
Где:
Dev workstation — локальная машина разработки;
Repository — репозиторий кода;
CI Runner — сборочный агент;
Registry — реестр образов;
CD Runner — агент деплоя;
K8S — кластер Kubernetes;
Процесс безопасной разработки контейнеризированных приложений
А теперь рассмотрим процесс, в рамках которого применяются практики CS — тоже на упрощенной схеме:
Где:
Dev workstation — локальная машина разработки;
Repository — репозиторий кода;
CI Runner — сборочный агент;
Registry — реестр образов;
CD Runner — агент деплоя;
K8S — кластер Kubernetes;
Оценка пользы практик безопасности
Определить ценность внедрения той или иной практики безопасности бывает довольно сложно. Во-первых, значение каждой практики может зависеть от контекста и конкретных потребностей организации. Во-вторых, результаты могут быть крайне субъективными и не всегда выражаются в числах.
Однако при определении ценности можно учитывать следующие факторы:
Риск угрозы: наличие известных уязвимостей и угроз для приложений и инфраструктуры организации может быть хорошим показателем того, какую защиту нужно использовать.
Затраты: во сколько обойдется внедрение и поддержка практики безопасности. Чем больше затраты, тем выше должна быть ценность.
Степень соответствия стандартам безопасности: многие правительства и отраслевые организации устанавливают требования по безопасности, которые предполагают использование определенных практик. Выполнение этих требований повышает ценность.
Влияние на время и скорость разработки: некоторые практики безопасности могут замедлять процесс разработки, что приводит к увеличению времени выхода продуктов в продакшн.
Уменьшение количества инцидентов безопасности — это может быть хорошим показателем эффективности определенной практики.
В конечном итоге ценность внедрения инструментов и практик безопасности будет зависеть от потребностей компании и её бизнес-моделей. Однако всегда можно провести обзор инструментов и решений, доступных на рынке, а также обратиться к экспертам по безопасности для получения советов и рекомендаций.
Container Security: с чего начать?
По опыту нашей работы я могу выделить самые простые практики с точки зрения их эффективности и возможностей встраивания в процесс разработки.
Начните с себя:
Безусловно, это не обязательный и не для всех возможный подход в силу разных причин, но он позволяет снизить количество фейлов в пайплайне по политикам сканнеров, что значительно повышает скорость выкатывания новых версий.
SAST/Lint IaC и SCA Image вполне реально установить на собственной машине разработки, что позволит наглядно видеть проблемы в разрабатываемых артефактах перед стартом всего последующего пайплайна. Существуют решения, которые позволяют встроить эти инструменты в качестве плагина в IDE.
Встройте практики в CI процесс:
Это, наверное, один из важнейших этапов в процессе разработки.
Преимущества:
SAST/Lint IaC выступает в качестве Quality Gate для Dockerfile, что позволяет контролировать целевое качество Dockerfile перед сборкой самого образа;
SCA Image является также Quality Gate для собранного образа, что дает возможность контролировать целевое качество образа перед его публикацией;
Signing выступает в качестве «нотариуса», который подтверждает, что образ выпущен конкретно вашей организацией/командой. Наличие подписи у образа часто требует конечный потребитель, который может быть как системой (например кластером Kubernetes), так и организацией.
Встройте SCA Image в ваш Image Registry:
Большинство решений SCA Image позволяет интегрироваться с реестром образов для регулярного сканирования, что дает возможность отслеживать уязвимости в образах в реальном времени как для тех артефактов, что собираются в ваших пайплайнах, так и для тех, которые вы вносите в собственный контур из внешних источников (например, системные образы для мониторинга, сборок, инструментов и т. д.). Также некоторые реестры позволяют ретегировать образы после сканирования.
Встройте SAST/Lint IaC в CD процесс:
SAST/Lint IaC в процессе CD является Quality Gate для манифестов K8S, который позволяет контролировать их перед тем, как задеплоить в кластер. Идеальным вариантом является отказ на переход к деплою при несоответствии требованиям безопасности.
Встройте Admission Controller в кластер:
Наверное, не самый простой этап, если говорить про тонкую настройку политик под общий compliance, однако начать можно с базовых вещей:
Разрешить к деплою образы только из ваших внутренних реестров образов;
Разрешить к деплою образы только с подписью;
Разрешить к деплою манифесты деплойментов только с нормальными привелегиями
Верно настроенные политики на Admission Controller’е позволят контролировать весь процесс эксплуатации кластеров для запуска рабочих нагрузок, исключить возможность деплоя в кластер неизвестных артефактов и заставить команды придерживаться принятого в организации процесса деплоя в кластеры.
Встройте Observability:
Можно назвать ее одной из сложнейших практик, т. к. в контексте всего процесса безопасной разработки достаточно непросто приземлить решения на каждый этап от сборки до runtime, формализовать потребности в детальной «обозреваемости» каждого процесса и, самое главное — сделать так, чтобы все работало, было понятно и наглядно. Эта практика очень важна, однако на первых порах в Container Security необходимо сначала нарастить экспертизу на предыдущих этапах, особенно в части, касающейся безопасности в CI/CD и Admission Controlling’е, что отвечает требованиям парадигмы Shift Left. Как только вы закончите со встраиванием перечисленных в начале практик, имеет смысл обзавестись системой Observability для кластеров Kubernetes. Ведь приземлить инструменты Observability гораздо проще на готовый процесс безопасной разработки.
Общие рекомендации по построению процесса безопасной разработки контейнеризированных приложений
Выберите решение, максимально удовлетворяющее вас в удобстве использования, интеграции и гибкости.
На этапе внедрения решений, настройте их в режим dry run, чтобы не фейлить пайплайны разработки.
Если все инструменты встроены в процесс, стабильно работают и отдают отчеты, начните понемногу «закручивать гайки» по принципу слева направо, начиная с CI, заканчивая Admission Controller’ом. Это позволит постепенно вводить всех в тему безопасности контейнеров.
И помните, что инструмент — это не самое главное. Главное — люди. Чаще проводите встречи с командами для обсуждения возможности применения той или иной политики (бывает, что некоторые компоненты систем не могут быть покрыты политикой, поэтому требуются мнения со стороны команд и разработки, и эксплуатации).
Все инструменты в каждой практике максимально схожи по своей функциональности, поэтому их можно менять без необходимости полного перестраивания процесса.