[Из песочницы] Пользовательские правила iptables для docker на примере zabbix
Задача: Закрыть все входящие соединение, кроме определенных ip адресов.
Имеется тестовая среда, состоящий из linux и трех windows c статическими ip адресами. На linux установлен docker образами zabbix, redmine. А на двух windows машинах установлены и настроены агенты от zabbix, в одном только просмотр zabbix. Нужно ограничить пользователей от zabbix сервера.
Все команды выполняются от имени root.
В официальной документации говорится о правиле iptables DOCKER-USER. Следует только это правило менять. Сперва смотрим какие правила есть, акцентируем внимание только на некоторых правилах.
Видно, что в правиле FORWARD первым стоит правило с target DOCKER-USER. Поэтому следует только его изменить.
iptables -L FORWARD -n -v
Chain FORWARD (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
421K 169M DOCKER-USER all -- * * 0.0.0.0/0 0.0.0.0/0
419K 167M DOCKER-ISOLATION-STAGE-1 all -- * * 0.0.0.0/0 0.0.0.0/0
Из таблицы правил DOCKER можно увидеть какие порты и открыты и внутренние ip адреса контейнеров.
iptables -L DOCKER -n -v
Chain DOCKER (4 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT tcp -- !docker_redmine docker_redmine 0.0.0.0/0 172.16.237.2 tcp dpt:3000
0 0 ACCEPT udp -- !br-c56432fe07cc br-c56432fe07cc 0.0.0.0/0 172.16.238.2 udp dpt:162
0 0 ACCEPT tcp -- !br-c56432fe07cc br-c56432fe07cc 0.0.0.0/0 172.16.238.3 tcp dpt:10051
0 0 ACCEPT tcp -- !br-c56432fe07cc br-c56432fe07cc 0.0.0.0/0 172.16.238.4 tcp dpt:443
5 248 ACCEPT tcp -- !br-c56432fe07cc br-c56432fe07cc 0.0.0.0/0 172.16.238.4 tcp dpt:80
В правиле DOCKER-USER нет особенных правил, все соединение пропускает через себя.
iptables -L DOCKER-USER -n -v
Chain DOCKER-USER (1 references)
pkts bytes target prot opt in out source destination
4180 1634K RETURN all -- * * 0.0.0.0/0 0.0.0.0/0
Первую очередь разберемся с сетью zabbix, а именно установим постоянную имя сети. Чтоб при пересоздании docker-compose имя не сменился. Из нынешнего состояния сети zabbix имеет сеть под именем br-c56432fe07cc, что не очень хорошо, трудно запомнить. В файле *.yaml добавим одну строку отвечающее за имя сети zbx_net_frontend: «com.docker.network.bridge.name: «docker_zabbix».
Часть конфигурации:
networks:
zbx_net_frontend:
driver: bridge
driver_opts:
com.docker.network.enable_ipv6: "false"
com.docker.network.bridge.name: "docker_zabbix"
После пересоздаем сеть. Следует заменить на вашу *.yaml.
docker-compose -f docker-compose_v3_ubuntu_mysql_latest.yaml down
docker-compose -f docker-compose_v3_ubuntu_mysql_latest.yaml up -d
Cмотрим правило DOCKER.
iptables -L DOCKER -n -v
Chain DOCKER (4 references)
pkts bytes target prot opt in out source destination
0 0 ACCEPT tcp -- !docker_redmine docker_redmine 0.0.0.0/0 172.16.237.2 tcp dpt:3000
0 0 ACCEPT udp -- !docker_zabbix docker_zabbix 0.0.0.0/0 172.16.238.2 udp dpt:162
0 0 ACCEPT tcp -- !docker_zabbix docker_zabbix 0.0.0.0/0 172.16.238.3 tcp dpt:10051
0 0 ACCEPT tcp -- !docker_zabbix docker_zabbix 0.0.0.0/0 172.16.238.4 tcp dpt:443
5 252 ACCEPT tcp -- !docker_zabbix docker_zabbix 0.0.0.0/0 172.16.238.4 tcp dpt:80
Осталось добавить правило в таблицу DOCKER-USER. Первом делом ведем правило DROP для всех подключений в сеть docker_zabbix из внешнего интерфейса (у меня eth0).
iptables -I DOCKER-USER -i eth0 -o docker_zabbix -j DROP
Сейчас все соединение запрещены в сеть docker_zabbix. Разрешим соединение для одного ip адреса, точнее сказать пакет может продолжить путь дальше по FORWARD.
iptables -I DOCKER-USER -i eth0 -s 192.168.43.55 -j RETURN
Здесь явным образом не указали сеть docker_zabbix. Проверяем доступность zabbix от хоста 192.168.43.55 с помощью powershell.
tnc 192.168.43.136 -port 8081
ComputerName : 192.168.43.136
RemoteAddress : 192.168.43.136
RemotePort : 8081
InterfaceAlias : vEthernet (Swich_in)
SourceAddress : 192.168.43.55
TcpTestSucceeded : True
8081 порт открыт для zabbix docker. Чтоб удостовериться в том, что zabbix принадлежит 8081 порт.
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c047f18a4445 zabbix/zabbix-web-nginx-mysql:ubuntu-4.2-latest "docker-entrypoint.sh" About an hour ago Up About an hour (healthy) 0.0.0.0:8081->80/tcp, 127.0.0.1:8443->443/tcp zabbix_zabbix-web-nginx-mysql_1
Но следует учесть, что в правилах надо указывать порт 80, а не 8081. Если указать порт 8081, то не откроется доступ к zabbix. Для второго хоста команда.
iptables -I DOCKER-USER -i eth0 -p tcp --dport 80 -s 192.168.43.10 -j RETURN
Для треьего хоста откроем только порт 10051, на этом хосте используется активный агент.
iptables -I DOCKER-USER -i eth0 -p tcp --dport 10051 -s 192.168.43.13 -j RETURN
Еще одна проблема, не можем из контейнеров выйти в внешний мир. Не работают скрипты оповещение и не может проверить доступность сайтов. Осталось еще одна команда для разрешение уже имеющих соединений.
iptables -I DOCKER-USER -i eth0 -o docker_zabbix -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
Не забываем, что после перезагрузки сервера созданные правило стираются.