Найти тему
Timeweb Cloud

Как повысить безопасность Docker-контейнеров: лучшие практики

📜 Читайте также: Как удалить образы, контейнеры и тома Docker

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

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

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

Основы безопасности при работе с Docker-контейнерами

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

  • Минимизация поверхности атаки

Контроль компонентов и служб — важный аспект безопасности контейнеров. Чем меньше поверхность атаки, тем сложнее злоумышленникам проникнуть в систему через уязвимости в приложениях или компонентах.

  • Обновления

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

Рекомендации по сборке образа

Чтобы дополнительно минимизировать поверхность атак и уменьшить последствия от атак на цепочки поставок, рекомендуется пользоваться образами только из проверенных источников. Одним из таких является Docker Hub.

При выборе дистрибутива обратите внимание на Alpine Linux. Он ориентирован на безопасность и достаточно прост в использовании, что является его главными преимуществами перед остальными дистрибутивами.

Также, при сборке образа старайтесь указывать в теге стабильную версию, нежели последнюю (latest).

Ограничение полномочий пользователя

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

Для того чтобы у пользователя были ограниченные права в Docker-контейнере, можно воспользоваться следующими рекомендациями:

1. Создание пользователя и группы с ограниченными полномочиями:

FROM <base_image>

RUN groupadd -r <group_name> && useradd -r -g <group_name> <user_name>

RUN chown -R <user_name>:<group_name> /app

USER <user_name>

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

2. Запуск контейнера от имени определенного пользователя:

docker run --user <user_name> <base_image>

3. Запуск контейнера от произвольного пользователя:

docker run -u <random_ID_user> <base_image>

Здесь <random_ID_user> — это произвольный ID некого пользователя, который отсутствует в запущенном контейнере.

Редактирование привилегий контейнера

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

docker run --security-opt=no-new-privileges <base_image>

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

Чтобы ограничить capabilities в контейнере, вы можете использовать опцию --cap-drop при запуске контейнера, указав конкретные capabilities для их исключения:

docker run --cap-drop=CAPABILITY1,CAPABILITY2 <image>

Использование контрольных групп

Контрольные группы — это механизм Linux для ограничения доступа процессов к ресурсам системы: это CPU, память или сеть.

В Docker возможно использовать контрольные группы для ограничения доступа к ресурсам внутри контейнера. Например, вы можете ограничить использование CPU или объема памяти, выделенных контейнеру, с помощью добавления при запуске опций --cpu-shares и --memory соответственно:

docker run --cpu-shares=512 --memory=1g <image>

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

Единственное важно уточнение — не используйте опцию --cgroup-parent, так как она позволяет задать родительскую контрольную группу для контейнера и может подвергнуть ресурсы хоста риску сторонней атаки.

Подробнее о ресурсах системы и контрольных группах можно прочитать в официальном руководстве Docker.

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

Настройка доступа к файловой системе контейнера может значительно повысить безопасность. Рекомендуется устанавливать режим только для чтения. Тогда файлы в контейнере не могут быть изменены или перезаписаны в процессе его работы. Сделать это можно следующим способом:

docker run --read-only <base_image>

Также дополнительно обезопасить файловую систему можно, создав временное хранилище для данных и файлов, которые не требуется сохранять после остановки контейнера.

Tmpfs предоставляет файловую систему в памяти, которая автоматически уничтожается при остановке контейнера.

Настройка временного хранилища происходит с использованием опции --tmpfs при запуске контейнера:

docker run --tmpfs /tmpfs:rw,noexec,nosuid,size=1g <base_image>

Представленной командой создается временное хранилище размером 1 гигабайт. Также здесь указаны 3 опции:

  • rw — позволяет читать и записывать данные в хранилище;
  • noexec — запрещает выполнение исполняемых файлов из хранилища;
  • nosuid — отвечает за игнорирование флага suid.

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

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

Для повышения безопасности рекомендуется использовать опцию --bridge=none при запуске Docker, чтобы отключить использование встроенного сетевого моста. А затем вы можете создать и запустить свою собственную сеть с помощью следующих команд:

docker network create <network_name>

docker run --network=<network_name> <base_image>

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

Как мы уже говорили в 3 главе настоящей статьи, используйте только проверенные источники. Это же касается и реестров.

Если вы решили загрузить Docker-образ из внешних реестров, обязательно убедитесь, что вы используете проверенный источник. Лучше всего для этих целей использовать Docker Hub.

Систематическое сканирование

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

Контроль доступа к UNIX-сокету

По умолчанию, Docker демон прослушивает UNIX-сокет /var/run/docker.sock, который позволяет контейнерам взаимодействовать с ним и выполнять операции с другими контейнерами и образами. Важно убедиться, что доступ к этому сокету ограничен и доступен узкому кругу пользователей или групп. Иначе сторонний пользователь может получить неограниченный доступ к хосту с привилегиями суперпользователя.

Работа с секретами в Docker

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

Для безопасной передачи секретов в контейнеры существует опция --secret, а для их хранения необходимо воспользоваться Docker BuildKit.


Кстати, в
официальном канале Timeweb Cloud собрали комьюнити из специалистов, которые говорят про IT-тренды, делятся полезными инструкциями и даже приглашают к себе работать.💥