Категория: Веб-сервер и инфраструктураОбновлено 2026-10-18

Docker socket proxy (прокси сокета Docker)

Прокси сокета Docker (Docker socket proxy) это небольшой сервис между инструментом и /var/run/docker.sock, который пересылает только явно разрешённые запросы к API Docker и отклоняет остальные. Мониторинг, обратный прокси или CI получают нужные данные, но не полный контроль уровня root, который даёт сам сокет.

Какую проблему решает прокси сокета Docker

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

Тем не менее многим инструментам сокет нужен, обычно чтобы получать список контейнеров или следить за событиями. Прокси убирает выбор «всё или ничего». Инструмент обращается к прокси, прокси обращается к сокету, и каждый запрос сначала сверяется со списком разрешённого. Инструмент, которому нужно лишь находить контейнеры, не сможет запускать, останавливать или создавать их, даже если он скомпрометирован или работает с ошибкой. Это принцип наименьших привилегий, применённый к API.

Как работает Tecnativa docker-socket-proxy

Согласно README проекта, это небольшая конфигурация HAProxy на официальном образе HAProxy на базе Alpine, которая отвечает на опасные запросы кодом HTTP 403 Forbidden. Разделы API включаются и отключаются переменными окружения: 1 разрешает, 0 запрещает. По умолчанию разрешены EVENTS, PING и VERSION, а такие разделы, как CONTAINERS, IMAGES, EXEC, VOLUMES и SERVICES, запрещены; AUTH, SECRETS и POST названы критичными для безопасности. При выключенном POST проходят только запросы GET и HEAD.

Пример для compose, адаптированный из команды docker run в README:

services:
  socket-proxy:
    image: tecnativa/docker-socket-proxy
    privileged: true
    environment:
      CONTAINERS: 1
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    networks: [socket_net]
networks:
  socket_net:
    internal: true

Подключите клиента к socket_net и задайте DOCKER_HOST=tcp://socket-proxy:2375. В README сказано, что --privileged нужен из-за особенностей соединения с сокетом.

От чего прокси сокета не защищает

Прокси сужает доступ, но не устраняет риск. Важны три ограничения.

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

Во-вторых, сам контейнер прокси монтирует настоящий сокет, поэтому уязвимость в нём или в окружении хоста по-прежнему путь к root.

В-третьих, значение имеет то, что вы включили. Правила прокси, судя по опубликованной конфигурации HAProxy, опираются на метод HTTP и путь URL, поэтому он не отличит безобидный вызов контейнеров от опасного на том же эндпоинте. Включив POST вместе с CONTAINERS, вы позволяете клиенту создавать контейнеры, а это эквивалент root на хосте, как объясняет руководство по безопасности хоста Docker. Даже чтение раскрывает данные: осмотр контейнера показывает его переменные окружения, где часто лежат секреты. Включайте минимум разделов и считайте EXEC, POST, BUILD и SERVICES потенциально равными root.

Альтернативы выдаче сокета

Лучший вариант вообще не давать инструменту сокет. Если его можно настроить статически или передать ему сведения о контейнерах иначе, сделайте так. Для собственного администрирования используйте контекст Docker поверх SSH вместо TCP-слушателя; документация Docker отмечает, что пользователю SSH всё равно нужно право на сокет, а у любого, кто владеет ключами демона, открытого по TLS, есть root на хосте.

Rootless-режим решает задачу с другой стороны. По документации rootless-режима, он нужен, чтобы смягчить последствия потенциальных уязвимостей демона и среды выполнения контейнеров, а сокет при этом лежит в каталоге пользователя, например /run/user/1000/docker.sock. OWASP добавляет, что режим не защищает от повышения привилегий на хосте через уязвимости ядра. Подходы решают разные задачи, поэтому сочетайте их с проверками хоста из руководства по Docker и правилами доступа из статьи про UID 0.

Связанные термины: Сокет Docker, Наименьшие привилегии, UID 0, Файрвол.

Часто задаваемые вопросы

Что такое прокси сокета Docker?

Это фильтр перед /var/run/docker.sock, который пересылает только разрешённые запросы к API Docker, а на остальные отвечает ошибкой, например HTTP 403. Инструменты получают ограниченный доступ вместо полного управления демоном.

Какие разделы API разрешает Tecnativa docker-socket-proxy по умолчанию?

Согласно README, по умолчанию разрешены EVENTS, PING и VERSION. AUTH, SECRETS, POST и такие разделы, как CONTAINERS, IMAGES и EXEC, запрещены, пока вы не установите соответствующую переменную в 1.

Достаточно ли смонтировать docker.sock только для чтения вместо прокси?

Нет. OWASP указывает, что монтирование сокета только для чтения не делает API Docker доступным только для чтения, и контейнер по-прежнему может отправлять мощные команды. Прокси фильтрует сами запросы.

Делает ли прокси скомпрометированный инструмент безвредным?

Нет. Он ограничивает вызовы, но всё включённое остаётся доступным, а POST вместе с CONTAINERS позволяет создавать контейнеры, что равно root. Разрешайте минимум и держите прокси в приватной сети.

Шифрует ли прокси соединения и проверяет ли клиентов?

По README, поддержки TLS нет, используется обычный HTTP, а аутентификация клиентов не описана. Ограничивайте доступ к порту средствами сетей Docker и никогда не открывайте его публично.

Хотите увидеть, в каком состоянии ваш сервер?

Запустите бесплатную read-only проверку сервера или откройте Security Lab и посмотрите цикл обнаружение, сдерживание, восстановление, проверка в действии.

Получить бесплатную проверку сервераОткрыть Security Lab