Page tree
Skip to end of metadata
Go to start of metadata

Общая информация

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

Чтобы полностью контролировать доступ к серверу с приложениями в docker'е, необходимо фильтровать трафик также в цепочке FORWARD, а точнее в ее дочерней цепочке DOCKER-USER.

Пример

Применение приведённых в примере правил без адаптации к конкретному серверу может привести к недоступности сервисов

# DO NOT FORGET TO RESTART DOCKER ENGINE AFTER APPLYING IPTABLES RULES

*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
COMMIT

*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
COMMIT

*filter
:INPUT ACCEPT [0:0]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p icmp -j ACCEPT
# Docker traffic
-A INPUT -i docker0 -j ACCEPT
-A INPUT -i br-+ -j ACCEPT
# Latera GWs
-A INPUT -s 188.120.244.146 -j ACCEPT
-A INPUT -s 5.63.158.193 -j ACCEPT
-A INPUT -j DROP
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:DOCKER-USER - [0:0]
-A DOCKER-USER -m state --state RELATED,ESTABLISHED -j RETURN
# Docker traffic
-A DOCKER-USER -i docker0 -j RETURN
-A DOCKER-USER -i br-+ -j RETURN
# Latera GWs
-A DOCKER-USER -s 188.120.244.146 -j RETURN
-A DOCKER-USER -s 5.63.158.193 -j RETURN
# HTTP(S)
-A DOCKER-USER -p tcp -m conntrack --ctdir ORIGINAL --ctorigdstport 80 -j RETURN
-A DOCKER-USER -p tcp -m conntrack --ctdir ORIGINAL --ctorigdstport 443 -j RETURN
-A DOCKER-USER -j DROP
COMMIT

В данном примере:

  1. Доступ к docker-контейнерам фильтруется в цепочке DOCKER-USER, а доступ к приложениям хост-системы — традиционно в цепочке INPUT.
  2. Для разрешающих правил цепочки DOCKER-USER применяется действие RETURN, потому что трафик дальше продолжает обрабатываться служебными правилами Docker Engine.
  3. Порты назначения в DOCKER-USER определяются с помощью модуля conntrack, поскольку на данном этапе пакеты уже прошли через DNAT и порт назначения изменился на порт внутри контейнера.

Рекомендации

Список правил iptables стоит вести в отдельном файле (например, в /etc/network/iptables.up.rules для Debian или в /etc/sysconfig/iptables для Oracle Linux) и загружать в систему до запуска Docker Engine.

Изменение правил необходимо выполнять в следующем порядке:

  1. Изменить файл с правилами iptables;
  2. Остановить Docker Engine (команда: sudo systemctl stop docker, это приведёт к остановке всех docker-приложений, работающих на сервере);
  3. Применить правила iptables;
  4. Запустить Docker Engine (команда: sudo systemctl start docker)
  5. Проверить работу и доступность docker-приложений (за основу можно взять карту проверок работы биллинга после обновлений).

Остановка Docker Engine для применения правил требуется для переинициализации правил iptables по контейнерам. К сожалению, переинициализировать их без остановки всего Docker Engine невозможно (см. https://github.com/moby/moby/issues/12294).

Применять правила iptables в Debian Linux рекомендуется с использованием утилиты iptables-apply (в случае если эта утилита не получит подтверждения доступа к серверу, изменения в правилах будут отменены). При возникновении ошибок некорректные правила необходимо удалить из файла с правилами iptables, чтобы они не применялись при перезагрузке сервера.

Не рекомендуется

  1. Применять правила iptables «на горячую». Это может привести к расхождению между файлом с правилами и реальным состоянием iptables, которое станет явно заметным после перезагрузки сервера.
  2. Сохранять все правила iptables при выключении сервера и восстанавливать их при включении. Это приводит к восстановлению неактуальных («мусорных») правил docker'а по уже несуществующим экземплярам контейнеров, а также может привести к потере новых правил, если сервер был перезагружен по питанию.
  • No labels