Docker: сети и безопасность контейнеров
Docker по умолчанию удобен, но не безопасен. Открытые порты в обход фаервола, root внутри контейнеров, доступный сокет — типичные дыры. Разберём, как настроить сети и закрыть уязвимости.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Типы сетей Docker
Docker создаёт несколько сетевых драйверов. Понимание их — половина безопасности:
- bridge — сеть по умолчанию, контейнеры общаются внутри хоста
- user-defined bridge — своя сеть с DNS по именам контейнеров, лучшая изоляция
- host — контейнер использует сеть хоста напрямую, без изоляции портов
- none — контейнер вообще без сети
Создаём изолированную сеть и подключаем к ней сервисы:
docker network create backend
docker run -d --name db --network backend postgres:16-alpine
Внутри сети backend приложение обращается к базе просто по имени db — без проброса портов наружу. Это работает благодаря встроенному DNS: в user-defined сети Docker резолвит имена контейнеров в их внутренние адреса автоматически. В дефолтной bridge-сети такого DNS нет — ещё одна причина всегда создавать свои сети.
Посмотреть, кто в какой сети сидит, помогает inspect:
docker network ls
docker network inspect backend
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США и РФ. Оплата картой РФ и по СБП.
Арендовать защищённый VPSИзоляция: не публикуйте лишнего
Главная ошибка новичков — -p 5432:5432 у базы. Это выставляет PostgreSQL в открытый интернет. База должна быть доступна только приложению по внутренней сети, а наружу смотрит лишь веб.
Разделяйте на две сети: фронтовую (публичную) и бэкендовую (закрытую).
docker network create frontend
docker network create backend
# web в обеих, db только в backend
docker network connect frontend web
docker network connect backend web
docker network connect backend db
Если порт нужен только локально, привязывайте его к loopback: -p 127.0.0.1:5432:5432 — тогда порт доступен лишь с самого VPS.
Docker и фаервол: важный нюанс
Ловушка, о которую спотыкаются многие: Docker пишет правила прямо в iptables и обходит ufw. Опубликованный порт может быть открыт всему интернету, даже если ufw говорит deny.
Проверяйте, что реально слушает наружу:
ss -tulpn | grep docker
iptables -L DOCKER -n
Безопасное решение — привязка к 127.0.0.1 (как выше) или пакет ufw-docker, который согласует правила. На root-доступе VPS MAATRIX вы полностью управляете iptables и можете выстроить правила под себя.
Безопасный запуск контейнеров
По умолчанию процессы в контейнере идут от root. Если приложение взломают, злоумышленник получает root внутри — а это плацдарм для атаки на хост. Запускайте от непривилегированного пользователя и урезайте возможности:
docker run -d \
--user 1000:1000 \
--read-only \
--cap-drop ALL \
--security-opt no-new-privileges \
myapp
- --user — процесс не root
- --read-only — файловая система только для чтения, писать можно лишь в явные тома
- --cap-drop ALL — снимаем все Linux-capabilities, добавляем только нужные через --cap-add
- no-new-privileges — запрет повышения прав внутри
Защита docker.sock и гигиена образов
Доступ к /var/run/docker.sock равносилен root на хосте. Никогда не монтируйте его в контейнеры, которым он не нужен, и не выставляйте Docker API в сеть. Если монтируете (Portainer, Traefik) — только для чтения :ro и за фаерволом.
Регулярно проверяйте образы на уязвимости и обновляйте базовые слои:
docker scout cves myapp:latest
docker pull postgres:16-alpine
- Берите образы только из доверенных источников и с фиксированными тегами, а не
latestвслепую - Обновляйте хост и Docker:
apt update && apt upgrade - Держите SSH за ключами, отключите вход по паролю
Безопасность сервера — это слои: изолированные сети, урезанные контейнеры, фаервол и свежие образы. Зарубежный VPS MAATRIX с root-доступом и оплатой из России даёт полную свободу настроить всё это под свой проект.
Отдельно про лимиты ресурсов: контейнер без ограничений может при утечке памяти положить весь хост. Задавайте потолок явно через --memory и --cpus либо секцию deploy.resources в compose — это не только про производительность, но и про устойчивость к атакам вроде исчерпания ресурсов. Взломанный или сбойный контейнер тогда упрётся в свой лимит, а не утащит за собой соседей и систему.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США и РФ. Оплата картой РФ и по СБП.
Арендовать защищённый VPSОбсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Частые вопросы
Почему ufw не блокирует порт Docker-контейнера?
Docker сам добавляет правила в iptables до цепочек ufw. Привязывайте порты к 127.0.0.1 или используйте ufw-docker для согласования.
Обязательно ли запускать контейнер не от root?
Крайне желательно. Root внутри контейнера при уязвимости в приложении облегчает атаку на хост. --user и --cap-drop сильно снижают риск.
Безопасно ли монтировать docker.sock в Portainer?
Только за фаерволом или SSH-туннелем и в режиме :ro. Доступ к сокету равен root на сервере, поэтому наружу его выставлять нельзя.