Безопасность Docker

Docker

Docker — отличная вещь, которая может сэкономить силы и времени. В данной статье мы поговорим о том, как защитить инфраструктуру Docker и отлавливать потенциальные угрозы заранее. Также вы найдете здесь готовые решения, команды и тулзы, которые легко использовать в своем проекте.

Контейнерная виртуализация на базе Docker очень популярна среди DevOps-админов. Она позволяет быстро развернуть инструменты разработки и тестирования программного обеспечения или целые проекты из многих компонентов. И все это хорошо, если бы не целый класс реальных угроз безопасности. Это и возможность побега из контейнера в хостовую систему, и шатдаун инстанса в результате «отказа в обслуживании», и различные кейсы с эксплуатацией уязвимостей ядра операционной системы, и подкидывание заранее скомпрометированных эталонных образов в репозиторий, и прочие атаки.

В этой статье мы с помощью админской смекалки, прямых рук, трезвого ума и всех доступных штатных средств Linux будет настраивать максимально безопасное и контролируемое DevOps-окружение на основе контейнеризации Docker. Мы будем смотреть на Докер глазами специалиста по безопасности (хакера).

Что такое Docker и как он работает

Docker — это инструмент для автоматизации развертывания приложений и управления ими в средах с поддержкой контейнеризации. ПО позволяет упаковывать любое приложение со всем его окружением и зависимостями в специальный контейнер, который можно запустить в любом дистрибутиве Linux.

Таким образом, каждый созданный нами контейнер уже включает в себя все необходимое для работы приложения — библиотеки, системные инструменты, код и среду исполнения. Благодаря Docker DevOps-админы и разрабы могут моментально развернуть, масштабировать и запустить свои приложения в любой среде и быть при этом уверенными, что написанный код будет прекрасно работать.

Docker имеет многи интересных фишек, которые есть у систем традиционной виртуализации. К примеру:

  • независимость — контейнер можно переместить на любую операционную систему с предварительно поднятой службой Docker и запустить одной командой;
  • самодостаточность — контейнер будет выполнять все заданные ему функции в любом месте, где бы его ни запустили, без доп. настройки и обслуживания.

Но в отличие от традиционной виртуализации, где образ мы, как правило, формируем сами, Docker работает с готовыми образами, взятыми из репозиториев. Существуют публичные и приватные хранилища официальных и неофициальных образов. В документации они называются docker registry. А самый популярный на сегодняшний день и часто используемый репозиторий — это Docker Hub.

Безопасность Docker. Сравнение Docker и VM
Безопасность Docker. Сравнение Docker и VM.

Docker image — это последовательный набор программных слоев. Каждый слой — результат работы команды в конфигурационном файле Dockerfile. То есть образ — это шаблон, на основе которого мы запускаем контейнер. А вот все, что запускается на основе этого образа, и есть сам контейнер (инстанс). В итоге у Docker появляется очень полезная фишка которая позволяет из одного заранее подготовленного образа запускать несколько одинаковых копий этого образа, то есть контейнеров.

Проблемы безопасности Docker

Давайте пройдемся по типовым кейсам, связанным с безопасностью инфраструктуры Docker.

Безопасность хостовой системы

Один из самых простых и в то же время ключевых вопросов безопасности Docker — это защита хостовой машины, в частности ядра ОС. Ведь в уже скомпрометированной системе изоляция и прочие механизмы безопасности контейнеров, которые мы могли бы использовать, нам вряд ли помогут. И это потому, что Docker спроектирован таким образом, что все запущенные контейнеры используют ядро хоста. Поэтому в качестве хоста должен быть пропатченный, обновленный дистрибутив Linux без известных уязвимостей и признаков инфицирования вредоносом.

Классический пример такого кейса — это побег из контейнера Docker. В официальной документации этот баг называется «выходом за пределы контейнера» (container breakout) и описывает ситуацию, при которой программе, запущенной внутри контейнера, удается преодолеть механизмы изоляции и получить рут-привилегии или доступ к важным данным, хранящимся на хосте. Типичный пример данного бага — уязвимость DirtyCow (CVE-2016-5195).

РЕКОМЕНДУЕМ:
Как с помощью Docker упаковать приложение ASP.NET Core

Для реализации защиты от таких ситуаций используется правило уменьшения количества привилегий для контейнера, выдаваемых ему по умолчанию. Так, если демон Docker выполняется под рутом, то мы должны создать для него пользовательское пространство имен (user-level namespace) с минимальными количеством привилегий.

Исчерпание ресурсов, или DDoS на контейнер

Если сравнивать контейнеры с виртуальными машинами, то первые на много легковесны. Даже на старом и слабом железе можно запустить несколько контейнеров. Но ошибки в конфигурации демонов, сетевого стека, недостатки проектирования архитектуры и атаки хакеров могут приводить к состояниям типа «отказ в обслуживании» (Denial of Service).

К примеру, некий контейнер или целый пул контейнеров может пожрать все процессорное время хоста и просадить его производительность. Подобная ситуация может произойти и с сетевыми интерфейсами, когда количество генерируемых пакетов превысит нормальную пропускную способность сети. Но выход в такой ситуации есть, и он довольно простой: правильно настроить лимиты ресурсов для контейнера.

Скомпрометированные образы для Docker

Docker распространяется с открытым исходным кодом, и образы для создания собственных контейнеров тоже находятся в публичном бесплатном доступе. А это значит, что хакеры с помощью социальной инженерии, фишинга и могут попробовать манипулировать действиями пользователей хранилищ Docker Image, чтобы заставить их скачать заранее скомпрометированный образ с вредоносной программой или бэкдорами.

Например, в апреле этого года много шума наделала новость о том, как хакеры получили доступ к базе данных крупнейшей в мире библиотеки образов для контейнеров Docker Hub. В результате были скомпрометированы имена пользователей, хеши паролей, а также токены для репозиториев GitHub и Bitbucket, используемых для автоматизированных сборок Docker. Или взять новость лета 2018 года, когда из официального реестра Docker Hub были удалены одновременно 17 образов контейнеров, содержавших опасные бэкдоры. Как позже выяснили эксперты, через них на серверы пользователей проникало вредоносное ПО в виде криптомайнеров и использовались обратные шеллы.

Перед всеми операциями по конфигурированию системы не забывайте сделать бэкап! Документируйте все изменения, чтобы потом не бегать в муках терзания и выдергивать волосы на голово, когда вы забудите, что и в какой последовательности изменяли. И конечно же проверяйте изменения на тестовом стенде перед переносом в их продакшен-среду!

Улучшаем безопасность Docker

Итак, как нам укрепить и защитить Docker? Сначала мы разберем рекомендации, а после рассмотрим конкретные примеры конфигурирования правил и политик безопасности для контейнерного пула.

Использование достоверных образов

Начнем, пожалуй, с банальной для репозиториев Docker проблемы — достоверности образа. Чтобы избежать проблем с поддельными образами, используйте приватные (private) или строго доверенные репозитории (trusted repositories) вроде Docker Hub. В отличие от других подобных репозиториев, образы, которые там лежат, всегда сканирует и просматривает специальный сканер безопасности Docker’s Security Scanning Service.

Безопасность Docker. Docker’s Security Scanning Service
Безопасность Docker. Результат проверки образа в Docker Hub с помощью Docker’s Security Scanning Service

Верифицируем образы через сервис Docker Content Trust

Еще один полезный и доступный всем инструмент, который стоит использовать, — Docker Content Trust. Это новая функция, доступная с версии Docker Engine 1.8. Она позволяет верифицировать владельца образа. Таким образом этот сервис защищает вас от фейков и подделок, атак повторного воспроизведения и компрометации ключей.

Проверка хоста и контейнера с помощью Docker Bench Security

Очень полезный инструмент, которым я сам не раз пользовался, — это Docker Bench Security (см. также документацию к нему). По сути, это большая подборка рекомендаций, советов и практик по развертыванию контейнеров в продакшене. Инструмент основывается на рекомендациях из документа The CIS Docker 1.13 Benchmark (PDF) и применяется в следующих областях:

  • конфигурация хоста (ядро, процессы, разрешения);
  • конфигурация демона Docker (сеть, выделение RAM, CPU);
  • файлы конфигурации демона Docker;
  • образы контейнеров и build-файлы;
  • Runtime контейнера;
  • опции «по умолчанию» Docker security.

Чтобы установить этот скрипт проверки, клонируйте репозиторий следующей командой в терминале:

После этого запускайте скрипт:

и используйте такую вот длинную команду:

Выполнив перечисленные шаги, вы соберете все контейнеры и запустите скрипт, который проверит безопасность хост-машины (kernel OS) и ее контейнеров. И это займет каких-то несколько минут!

Безопасность Docker. Запуск скрипта Docker Bench Security
Безопасность Docker. Запуск скрипта Docker Bench Security

Использование нативных опций безопасности на хостовых ОС

Для улучшения безопасности вы можете воспользоваться штатными инструментами Linux. Среди них — AppArmor, SELinux, grsecurity и Seccomp.

Проще всего было бы скачать дефолтный профиль Seccomp для Docker. Чтобы обеспечить самый банальный уровень защиты, достаточно скорректировать белый список системных вызовов в районе строки 52 — то есть просто удалить из него рисковые команды chmod, fchmod и fchmodat.

Но тонкая настройка этих механизмов безопасности выходит далеко за рамки этой статьи. Если вы еще ни разу их не конфигурировали, обращайтесь к официальной документации.

Подробное руководство по бронированию Docker, а также примеры бенчмарков опций безопасности и контрольный чек-лист проверки вы найдете в документе The CIS Docker 1.13 Benchmark.

Настройка опций улучшения безопасности Docker

Вот мы наконец и добрались до консоли! Сейчас будем ручками выстраивать безопасность для Docker. Готовы? Погнали!

Ограничения Docker Engine

Вспомним, что Docker Engine — это своего рода API, который прослушивает все входящие запросы и взаимодействует с базовым ядром хоста. Docker Engine поддерживает связь на трех сокетах: unix, tcp и fd.

Безопасное состояние по умолчанию — это прослушивание сокета unix. Для активации этой опции введите в терминале

Готово, больше ничего не требуется!

Выставляем ограничение на привилегии выполнения

По возможности запускайте контейнеры как обычный пользователь без root-прав:

Чтобы максимально уменьшить площадь потенциальной атаки, подумайте над следующими вопросами:

  • Какое сетевое подключение требуется для работы приложения и вообще требуется ли оно?
  • Нужен ли приложению прямой доступ к сокету?
  • Требуется ли приложению отправлять и получать UDP-запросы?

Для настройки ограничений будем использовать команды --cap-drop and и --cap-add.

Предположим, приложению абсолютно не требуется изменять системные процессы или биндить привилегированные порты, но при этом нужно загружать и выгружать модули ядра. Соответствующие возможности можно удалить и добавить следующим образом:

Также следует следить за случаями монтирования потенциально опасных ресурсов хоста (к примеру, таких, как /proc, /dev, /var/run/docker.sock). Несмотря на то что эти ресурсы нужны для работы контейнеров, все же стоит задуматься о необходимости ограничить доступ процессов к ним. К примеру, будет достаточно лишь установить к ним режим доступа «только чтение».

Для обеспечения безопасности сетевого взаимодействия можно настроить правила iptables, реализованные в Docker. Например, указать диапазон IP-адресов для источника пакетов, чтобы ограничить трафик на контейнер. Это поможет предотвратить обращение глубоко изолированного контейнера во внешнюю сеть. Включить эту функцию можно двумя командами:

Ограничиваем потребление системных ресурсов

Чтобы откалибровать пул ресурсов, выделяемых для контейнера (CPU, RAM, SWAP, I/O), нужно задать пороговые значения следующими командами:

  • -m, --memory — установить лимит выделения оперативной памяти (hard);
  • --memory-reservation — установить мягкий лимит памяти (soft);
  • --kernel-memory — установить лимит памяти ядра (kernel OS);
  • --cpus — ограничить количество используемых CPU;
  • --device-read-bps — ограничить пропускную способность чтения для конкретного устройства.

Также не забывайте использовать специальную фичу под названием cgroups. Контрольные группы (cgroups) — это предоставляемый ядром Linux штатный инструмент, который дает возможность ограничить доступ процессов и контейнеров к системным ресурсам. Некоторые лимиты можно контролировать прямо из командной строки Docker, например:

Этой командой мы выделяем для работы контейнера 4 Гбайт оперативной памяти и 1 Гбайт для кеширования в своп.

Мониторим активность работы контейнеров

Мониторинг, обнаружение аномального, подозрительного поведения контейнера и оповещение о нем — это один из ключевых инструментов анализа и своевременного реагирования на инциденты. Для этих целей можно использовать open sourse инструмент Sysdig Falco.

Безопасность Docker. Сервис Sysdig Falco
Безопасность Docker. Сервис Sysdig Falco

Sysdig Falco работает как система обнаружения вторжений и в особенности полезна при использовании Docker, поскольку в процессе создания правил поддерживает специфический для контейнеров контекст, такой как container.id, container.image, ресурсы Kubernetes или пространства имен.

Да, кстати, еще одна вещь из стандартного набора контроля и аудита ОС — это логирование событий. Для этого запускаем контейнер с ключом, ответственным за журналирование:

Палим CVE-уязвимости в контейнерах

Контейнеры Docker — это, по сути, изолированные черные ящики, которые крутятся на родительском хосте. Однако все может отлично работать, но при этом внутри оказывается уязвимое ПО. Причем в апстриме уязвимости могут быть давно пропатчены, но не в вашем локальном образе! И если не принять меры, такие проблемы могут долго оставаться незамеченными.

Многие реестры образов Docker предлагают услугу сканирования этих самых образов. Например, сервис CoreOS Quay использует сканер безопасности образов Docker с открытым исходным кодом под названием Clair. Clair — это приложение, написанное на Go, которое реализует набор HTTP API для выгрузки, загрузки и анализа образов. Данные об уязвимостях загружаются из разных источников, таких как Debian Security Tracker или Red Hat Security Data. В таком случае движок Clair работает по принципу статического анализатора без запуска контейнера на выполнение.

Безопасность Docker. Сервис CoreOS Quay для Docker
Безопасность Docker. Сервис CoreOS Quay для Docker

Ну и если вы начинающий админ или руководство адски зажимает денег, где-то на просторах Сети, говорят, есть аналогичные сервисы с теми же возможностями, но при этом совершенно бесплатные! Правда, я таких пока не встречал. Поэтому, если уж совсем нет выбора, можно использовать старый добрый OpenVAS либо аналогичный сканер безопасности, который вы будете запускать ручками по расписанию внутри своей корпоративной сетки.

Несколько интересных практических гайдов, руководств и сборников рецептов, как улучшить безопасность Docker, для самостоятельного изучения:

Mitigating Docker Security Issues — гайд, рассматривающий основные риски и угрозы безопасности Docker. Там же вы найдете практические примеры настроек безопасности для решения этих проблем;

Docker Secure Deployment Guidelines — небольшая страница на GitHub с описанием рекомендаций и основных настроек безопасности для Docker;

10+ top open-source tools for Docker security — обзор нескольких полезных инструментов для контроля над безопасностью исходных образов и запущенных контейнеров.

Заключение

Поздравляю! Сегодня мы прокачали ваши админские скиллы в защите систем контейнеризации на базе Docker. Теперь вы знаете об основных угрозах для DevOps-окружения и понимаете, чем можно поплатиться за беспечность, если халатно относится к безопасности. Также мы собрали неплохой набор инструментов для обеспечения безопасности Docker. Надеюсь, он поможет вам максимально защитить свои информационные активы без внушительных вложений денег и времени.

Понравилась статья? Поделиться с друзьями:
Добавить комментарий