Docker: Ограничение входящего и исходящего трафика с помощью iptables

Вопрос или проблема

У нас есть множество приложений, которые работают на Linux-сервере с использованием Docker.

В качестве примера, предположим, что мое приложение работает на ServerA как контейнер (Docker).

CONTAINER ID        IMAGE                    COMMAND             CREATED             STATUS              PORTS                     NAMES

df68695a00f1        app/myapp:latest   "/run.sh"           2 недели назад         Запущен 2 дня           0.0.0.0:50423->3000/tcp   reallymyapp

Приложение слушает на порту 50423 на хосте (сопоставлено с портом 3000 на контейнере).

DNS (конечная точка), который используется для доступа к приложению, указывает на хост HAProxy (скажем, ServerB), который маршрутизирует трафик на ServerA:50423.

На данный момент все работает хорошо.

Команда безопасности в нашей организации подняла вопрос о том, что все внешние IP-адреса потенциально могут подключаться к таким Docker-хостам (таким как ServerA), и они хотят, чтобы мы ограничили трафик, разрешив только определенному IP (ServerB, который является балансировщиком нагрузки) доступ к контейнерам и наоборот (ServerA к ServerB). Мы тогда будем разрешать подключение только от машин наших пользователей к ServerB/балансировщику нагрузки.

Теперь я следовал документации Docker и пытался вставить следующее правило, используя iptables в цепочку DOCKER-USER:

iptables -I DOCKER-USER -i ekf192 -s 10.1.2.10, 10.1.2.11, 10.1.2.12 -j ACCEPT
iptables -I DOCKER-USER -i ekf192 -j DROP


ACCEPT     all  --  10.1.2.10  anywhere
ACCEPT     all  --  10.1.2.11  anywhere
ACCEPT     all  --  10.1.2.12  anywhere
LOG        all  --  anywhere             anywhere             LOG level info prefix "IPTables Dropped: "
DROP       all  --  anywhere             anywhere
RETURN     all  --  anywhere             anywhere

Обратите внимание, что нам нужен как входящий, так и исходящий трафик от/к этим хостам (10.1.2.10, 10.1.2.11, 10.1.2.12).

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

Входящий трафик работает как ожидается, но исходящий трафик к этим ХОСТАМ отклоняется.

Я ломаю над этим голову и не могу понять, что идет не так… и не говоря уже о том, что я абсолютно плохо понимаю, как работают правила iptables.

Jan 12 16:24:43 sms100394 kernel: IPTables Dropped: IN=docker0 OUT=ekf192 MAC=02:42:09:37:a0:14:02:42:ac:11:00:02:08:00 SRC=172.17.0.2 DST=10.1.2.10 LEN=40 TOS=0x00 PREC=0x00 TTL=63 ID=40235 DF PROTO=TCP SPT=3000 DPT=42579 WINDOW=242 RES=0x00 ACK FIN URGP=0
Jan 12 16:24:44 sms100394 kernel: IPTables Dropped: IN=docker0 OUT=ekf192 MAC=02:42:09:37:a0:14:02:42:ac:11:00:02:08:00 SRC=172.17.0.2 DST=10.1.2.11 LEN=52 TOS=0x00 PREC=0x00 TTL=63 ID=0 DF PROTO=TCP SPT=3000 DPT=45182 WINDOW=29200 RES=0x00 ACK SYN URGP=0
Jan 12 16:24:45 sms100394 kernel: IPTables Dropped: IN=docker0 OUT=ekf192 MAC=02:42:09:37:a0:14:02:42:ac:11:00:02:08:00 SRC=172.17.0.2 DST=10.1.2.12 LEN=52 TOS=0x00 PREC=0x00 TTL=63 ID=0 DF PROTO=TCP SPT=3000 DPT=45182 WINDOW=29200 RES=0x00 ACK SYN URGP=0

iptables по умолчанию не знает о “потоках”, только о отдельных пакетах. Поэтому для исходящих пакетов нужно добавить отдельное правило, что-то вроде:

iptables -I DOCKER-USER -i ekf192 -d 10.1.2.10, 10.1.2.11, 10.1.2.12

Ответ или решение

Ограничение входящего и исходящего трафика в Docker с использованием iptables

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

Исходная ситуация

У вас есть контейнер, который слушает на порту 50423 на хосте, перенаправляя трафик на порт 3000 внутри контейнера. Вы хотите ограничить доступ к этому контейнеру так, чтобы только ServerB (где расположен HAProxy) мог взаимодействовать с ServerA. Ваша команда безопасности хочет обеспечить, чтобы только определенные IP (в вашем случае 10.1.2.10, 10.1.2.11, и 10.1.2.12) имели доступ к вашим контейнерам, а также чтобы контейнеры могли отправлять трафик обратно на эти IP-адреса.

Проблема с правилами iptables

Ваши текущие правила iptables выглядят следующим образом:

iptables -I DOCKER-USER -i ekf192 -s 10.1.2.10,10.1.2.11,10.1.2.12 -j ACCEPT
iptables -I DOCKER-USER -i ekf192 -j DROP

Вы правильно разрешили входящий трафик от указанных IP, но проблема заключается в том, что ваши правила не учитывают исходящий трафик от контейнера к этим IP. В IPTables каждому из направлений (входящие и исходящие) могут быть заданы разные правила.

Согласно вашим логам видно, что исходящий трафик от контейнера 172.17.0.2 на указанные IP адреса (например, 10.1.2.10) блокируется. Это происходит, потому что вы не предоставили соответствующие правила для разрешения исходящего трафика.

Решение проблемы

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

iptables -I DOCKER-USER -o ekf192 -d 10.1.2.10/32 -j ACCEPT
iptables -I DOCKER-USER -o ekf192 -d 10.1.2.11/32 -j ACCEPT
iptables -I DOCKER-USER -o ekf192 -d 10.1.2.12/32 -j ACCEPT

Таким образом, эти правила позволят контейнерам отправлять пакеты на указанные IP-адреса.

Полный набор правил iptables

Полный набор правил iptables для вашей ситуации может выглядеть следующим образом:

# Разрешаем входящий трафик от указанных IP
iptables -I DOCKER-USER -i ekf192 -s 10.1.2.10/32 -j ACCEPT
iptables -I DOCKER-USER -i ekf192 -s 10.1.2.11/32 -j ACCEPT
iptables -I DOCKER-USER -i ekf192 -s 10.1.2.12/32 -j ACCEPT
# Блокируем входящий трафик от всех остальных
iptables -I DOCKER-USER -i ekf192 -j DROP

# Разрешаем исходящий трафик к указанным IP
iptables -I DOCKER-USER -o ekf192 -d 10.1.2.10/32 -j ACCEPT
iptables -I DOCKER-USER -o ekf192 -d 10.1.2.11/32 -j ACCEPT
iptables -I DOCKER-USER -o ekf192 -d 10.1.2.12/32 -j ACCEPT

Подведение итогов

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

Оцените материал
Добавить комментарий

Капча загружается...