Хакер - Обороняем порт. Как защитить инфраструктуру на Docker минимальными силами

Хакер - Обороняем порт. Как защитить инфраструктуру на Docker минимальными силами

hacker_frei

https://t.me/hacker_frei

Иван Пискунов

Содержание статьи

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

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

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


 


Глазами безопасника

Мы уже не раз рассказывали о самой системе контейнеризации, публиковали большой FAQ по ней, раскрывали малоизвестные трюки и фишки и на пальцах объясняли, как сделать свою песочницу. Однако вопрос настройки опций безопасности для контейнеров все это время оставался в стороне. Сейчас мы посмотрим на Docker глазами спеца по безопасности (или хакера, если уж мы всерьез подняли эту тему).

 

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

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

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

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

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

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

Сравнение Docker и VM

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

INFO

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

 

Типовые проблемы безопасности, связанные с Docker

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

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

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

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

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

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

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

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

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

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

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

WARNING

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

Усиливаем безопасность Docker

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

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

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

Результат проверки образа в 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.

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

$ git clone git@github.com:docker/docker-bench-security.git

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

$ cd docker-bench-secutity 

и юзаем такую вот длинную команду:

$ docker run -it --net host --pid host --cap-add audit_control \
  -e DOCKER_CONTENT_TRUST=$DOCKER_CONTENT_TRUST \
  -v /var/lib:/var/lib \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /etc:/etc --label docker_bench_security \
  docker/docker-bench-security

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

Запуск скрипта Docker Bench Security

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

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

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

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

WWW

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

 

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

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

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

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

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

$ dockerd -H "unix:///var/run/docker.sock"

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

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

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

$ docker run -d -u 1000 debian sleep infinity
$ ps aux | grep sleep
1000 ... sleep infinity

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

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

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

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

$ docker run \
  --cap-drop SETPCAP \
  --cap-drop NET_BIND_SERVICE \
  --cap-add SYS_MODULE \
  -ti /bin/sh

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

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

$ iptables -t filter -A FORWARD -s
<source_ip_range> -j REJECT --reject-with
icmp-admin-prohibited

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

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

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

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

$ docker run -it --memory=4G --memory-swap=1G debian bash

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

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

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

Сервис Sysdig Falco

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

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

$ docker run -v /dev/log:/dev/log
<container_name> /bin/sh

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

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

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

Сервис CoreOS Quay для Docker

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

WWW

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

  • Mitigating Docker Security Issues — гайд, рассматривающий основные риски и угрозы безопасности Docker. Там же ты найдешь практические примеры настроек безопасности для решения этих проблем;
  • Docker Secure Deployment Guidelines — небольшая страница на GitHub с описанием рекомендаций и основных настроек безопасности для Docker;
  • 10+ top open-source tools for Docker security — обзор нескольких полезных инструментов для контроля над безопасностью исходных образов и запущенных контейнеров.

Заключение

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

Читайте ещё больше платных статей бесплатно: https://t.me/hacker_frei

Report Page