Привет, Хабр, я Вера Орлова — отвечаю за безопасность контейнеров и маркетплейс аддонов в Kubernetes в компании Cloud.ru. В статье расскажу, какие основные проблемы при работе с контейнерами существуют и какие вызовы встают перед разработчиками платформ контейнерной безопасности. Поделюсь, на какие аспекты защиты обращаем внимание в первую очередь мы, а также расскажу про наш подход к профилактике потенциальных уязвимостей и реальных проблем безопасности.
Надеюсь, тем, кто только начинает погружаться в эту область, мой рассказ поможет разобраться в теме и составить собственный список с мерами и необходимыми для безопасности сервисами.
Почему мы «топим» за безопасность контейнеров
Давайте посмотрим на цикл зрелости технологий от Gartner. На графике видно, что технология контейнерной безопасности уже вышла на «склон просвещения», т. е. становится все более удобной и популярной, ее аудитория растет. Но при этом безопасность Kubernetes всё еще находится на стыке «Пик завышенных ожиданий» и «Пропасть разочарования».
Получается, что технология развивается и востребована, но далеко не все понимают, как ее правильно использовать. Пользователи еще не научились защищать свои решения на базе Kubernetes настолько, чтобы митигировать хотя бы 60% уязвимостей.
Например, по данным CNews Analytics (2020) в России среди топ-500 РБК компаний 56% используют контейнеры в разработке, а по данным RedHat Datalog — 93% компаний сталкиваются минимум с одним инцидентом в среде Kubernetes в течение года. О каких инцидентах идет речь и к чему они могут привести?
Основные киберриски
NIST (The National Institute of Standards and Technology) одним из первых систематизировал все киберриски и выделил пять основных компонентов системы контейнеризации, которые им подвержены:
Образы контейнеров.
Реестр образов.
Оркестратор.
Контейнеры.
OC хоста.
Оригинальный обзор киберрисков есть в NIST Special Publication 800-190 в документе Application Container Security Guide. Также на TAdviser выходил упрощенный вариант обзора. Для удобства мы собрали основные угрозы инфраструктуры, которые встречаются на практике, в таблицу:
Как можно сократить киберриски и повысить показатели безопасности? Как минимум — соблюдать требования к безопасности контейнерной среды, в которых содержатся рекомендации и детальные инструкции, как обезопасить ваш кластер.
Требования и стандарты регуляторов
Рекомендаций и стандартов много, но все они имеют единые точки соприкосновения. Мы в первую очередь обращаем внимание на известных регуляторов, например:
Требования по безопасности информации к средствам контейнеризации Российского регулятора ФСТЭК — (от 2022 года).
Kubernetes CIS Benchmark — международный стандарт от Center for Internet Security.
Расскажу, какие инструменты и решения помогают нам их соблюдать.
Как митигировать риски: решения, которые мы используем
Поделимся правилами, которые помогают нам поддерживать безопасность контейнеров на всех уровнях.
Рекомендации для образов контейнеров
Устанавливаем строгие критерии отбора базовых образов. Например, чтобы не было много строчек кода, так как поверхность атаки увеличивается. Для минимизации поверхности атаки в качестве базовых образов стараемся брать тонкие образы по типу Distroless, где кроме вашего приложения ничего не будет. Таким образом, даже если ваше приложение будет уязвимым и не запаченым, самому атакующему будет сложно извлечь пользу, так как он не сможет ни за что закрепиться.
Выбираем часто обновляемые базовые образы из доверенных источников. Можно идентифицировать доверенные образы с помощью криптографических подписей.
Не храним в образах лишнего. Не тащим инструменты для дебага или секреты и пароли в образ для продакшна. Секреты и приватные ключи храним отдельно, в специальном инструменте для хранения ключей. Например, можно использовать Secret Manager.
Сканируем выбранный образ на соответствие политикам компании и лучшим практикам. Решений для сканирования множество, можно выбрать то, которое больше подходит. Примеры сканеров:
Trivy. У него довольно широкий спектр задач, но особенность в том, что он выявляет уязвимости и программные зависимости из Docker-образов.
JFrog. Может глубоко детализировать, что именно сканируется внутри бинарного кода, но только в своем репозитории Artifactory.
Рекомендации для реестра образов
Каких правил мы придерживаемся на этом этапе:
Запрещаем доступ к реестрам и ограничиваем права на редактирование или запись образов без аутентификации и авторизации. Также минимизируем привилегии, связанные с доступом к логированию и аудиту событий в реестре.
Подключения к реестрам разрешаем только по зашифрованным каналам, а также проверяем аутентификацию при установке связи с конечными точками.
Регулярно чистим реестры от старых образов.
Также важно анализировать не только базовый образ, но и другие слои. Отслеживать безопасность на всех этапах жизненного цикла контейнера, начиная от загрузки образа и заканчивая запуском контейнера.
Рекомендации для контейнеров
Выстраиваем процесс по обеспечению безопасности сборки. Требуется проверять все этапы своего рода, проводить инвентаризацию контейнера.
Первое, о чем задумываемся после запуска приложения в новом кластере — как обезопасить сетку. Важно сосредоточиться на выявлении аномалий, учитывая не только внешний трафик в интернете, но и межконтейнерный. К первому применимы стандартные средства защиты. А для межконтйнерной сети требуется специализированная система контейнерной безопасности, которая позволяет динамически или регулярно анализировать настройки на соответствие политикам компании и лучшим практикам, таким как CIS Benchmark.
Примеры продуктов, которые помогут на данном этапе выявления уязвимостей:
• Для выявления проблем с сетью можно взять Тетрагон. С Kubernetes он работает слабовато, зато Network policy — его конек.
• Falco — низкоуровневый сборщик событий, по типу audit событий, только вообще всех активностей. Он сам по себе ничего не enforce`ит, обычно на его базе уже строят свои системы. Он также разбирает системные вызовы на хосте и отправляет алерты при нарушении правил.
Рекомендации для оркестратора
Мониторим активности оркестратора — это позволяет обнаружить нежелательные операции.
Распределяем контейнеры по разным нодам: под каждую сущность свой кластер.
Для митигации риска выделяем специальные сети, чтобы передать информацию разного уровня конфиденциальности и разного назначения, т. к. разграничения сетевого межконтейнерного трафика недостаточно.
Применяем модель разграничения доступа, предоставляемого оркестратором.
Рекомендации для ОС хоста
Не держим контейнеризованные приложения на одном хосте.
Придерживаемся принципа наименьших привилегий: выдаем пользователю только те права, которые ему действительно нужны.
Управляем и регулярно обновляем компоненты хостовой ОС.
ОС хоста затрагивают (именно затрагивают) только некоторые сервисы, такие как:
• Платформа безопасности StackRox Kubernetes — анализирует риски среды контейнера, терминирует соединение, оповещает, но не блокирует. Интегрируется с каждым этапом жизненного цикла контейнера.
• Ну и на закуску, open source платформа по безопасности контейнеров by Neuvector. Она понравилась нам чуть больше и вот чем:
- функциональность шире, чем у других платформ;
- нативно понятный интерфейс;
- большая часть кода (порядка 74%) написана на Go;
- простая архитектура.
В итоге ее мы выбрали и ввели на нашей платформе Cloud.ru Evolution в качестве плагина. Но перед этим хорошенько протестировали, чтобы выявить возможные слабые места. Расскажем об этом подробнее.
Разбор архитектуры Neuvector, тестирование и наши доработки
Рассмотрим подробнее основные компоненты архитектуры Neuvector:
Admission Controller. Основной компонент, который отвечает за действия других компонентов и управляет ими. Он предоставляет REST API для управления сущностями Neuvector.
Enforcer. Занимается отслеживанием сети. Разворачивается в виде сущности DaemonSet, что позволяет ему размещаться на каждом узле кластера Kubernetes. Задача агента Enforcer состоит в том, чтобы отслеживать потоки сетевого трафика, процессы и файловые системы контейнеров и применять установленные политики безопасности.
Scanner. Занимается сканированием образов контейнеров, используя встроенную базу уязвимостей (CVE).
Manager. Отвечает за веб-интерфейс управления сущностями Neuvector и взаимодействует с контроллером через REST API.
Updater. С помощью CronJob запускает процесс обновления базы CVE и поочередно перезапускает все сканеры.
Prometheus Exporter. Компонент для сборки метрик со всех компонентов Neuvector.
Registry Adapter. Адаптер для внешних хранилищ образов, который помогает сканировать образы по базе CVE Neuvector.
Особенности платформы
Если вы захотите попробовать Neuvector, то должны иметь в виду его особенности. Когда мы установили решение и начали прорабатывать его глубже, то столкнулись со следующим:
Он жрет много памяти. На скриншоте работа контроллера, почти пустой кластер, где около пяти приложений. Все стараются оптимизировать работу систем безопасности, но с таким тяжеловесом это будет сложно сделать. Даже в системных требованиях прописано, что нужно не меньше 8 ГБ памяти под четыре компонента продукта (по два на каждый): контроллер, энфорсер, сканер и менеджер.
А связано это с его архитектурой, ведь он держит весь конфиг в памяти. К тому же консул у него поднимается не сайдкаром, а внутри контейнера вторым процессом, что дополнительно его утяжеляет.
Некорректная блокировка процессов. Как пример: мы подняли контейнер и развернули NGINX, попытались выполнить в контейнере самую простую команду LS.
Пробуем выполнить команду сразу пять раз — начинает блочить. Но будет ли так, если отправить запрос 100 раз? Не факт.
Теперь пробуем еще раз, но модифицируем команду:
Используем все то, что на скриншоте ниже:
а затем вводим команду:
ls for i in {1..5}; do kubectl exec nginx-pod-78f7dbcc9b-pzp2s -n demo echo 1 && ls; done
В итоге отработало в пяти из пяти случаев, чего явно быть не должно, ведь мы запрещаем выполнение ls. Получается, он пропарсил команду echo 1 (видит, что разрешено, а что дальше через два амперсанд идет LS и она запрещена — не всегда понимает)
Наш пример показывает, что у продукта кривой парсинг SMD-шки.Команды из двух частей, которую мы объединили в одну, он рутовой считает команду эхо. Так как эхо не заблокировано, то легитимное действие он видит и дает добро. По-хорошему, нужно ее распарсить и она будет состоять из двух компонентов, одна из под команд должна быть заблокирована. С первого взгляда выглядит, что все нормально, но при тщательном тестировании понимаешь, что злоумышленник точно так же может посылать запросы из нескольких команд.
Аналогичные проблемы наблюдаются и с файлами, и с Port forvording.
И похожую проблему мы наблюдали уже с сетью. Соединение прервалось, а потом восстановилось и продолжило работать. Т. е. мы запретили проход во вне: workload ingress deny. И в этом случае он также отрабатывал через раз.
Как итог, для себя мы поняли, что нет ничего идеального, и просто так доверять решениям open source не стоит — любое из них требует тщательной проверки и доработки. Кто захочет бесплатно протестировать продукт у нас на платформе Cloud.ru Evolution — не переживайте, все проблемы с блокировками мы поправили?.
Вместо заключения
Надеюсь, этот материал поможет тем, кто только начинает разбираться с темой контейнерной безопасности. А тем, кто уже в танке, позвольте дать небольшое напутствие: пускай безопасность ваших контейнеров начинается с архитектуры и не забывайте, что пока еще не изобрели чудесную пилюлю в виде open source, которая избавит вас от всех уязвимостей на всех уровнях жизненного цикла атак.
А в комментариях делитесь — у вас есть свои правила для поддержания безопасности? И какие средства защиты контейнеров используете вы?