Custom iptables rules for docker using zabbix as an example

Task: Close all incoming connections, except for specific ip addresses.



There is a test environment consisting of linux and three windows with static ip addresses. On linux, docker is installed with zabbix , redmine images. And on two windows machines agents from zabbix are installed and configured, on the third you need to organize the ability to view zabbix. It is necessary to restrict other users from the zabbix server, but not limiting from redmine.



All commands are executed as root.



The official documentation says the iptables DOCKER-USER rule. It is only necessary to change this rule. First, we look at what rules are, we focus only on some rules.



It can be seen that in the FORWARD rule, the first rule with the target DOCKER-USER is the first. Therefore, you should only change it.



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
      
      





From the DOCKER rule table, you can see which ports are open and the internal ip addresses of the containers.



 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
      
      





There are no special rules in the DOCKER-USER rule; the entire connection passes through itself.



 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
      
      





First of all, we will deal with the zabbix network, namely, we will establish a constant network name. So that when you recreate docker-compose, the network name does not change. From the current state of the network, zabbix has a network called br-c56432fe07cc, which is not very good. In the * .yaml file, add one line responsible for the network name zbx_net_frontend: "com.docker.network.bridge.name:" docker_zabbix ".



Part of configuration:



 networks: zbx_net_frontend: driver: bridge driver_opts: com.docker.network.enable_ipv6: "false" com.docker.network.bridge.name: "docker_zabbix"
      
      





After we recreate the network. Should be replaced with your * .yaml.



 docker-compose -f docker-compose_v3_ubuntu_mysql_latest.yaml down docker-compose -f docker-compose_v3_ubuntu_mysql_latest.yaml up -d
      
      





We look at the DOCKER rule.



 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
      
      





It remains to add the rule to the DOCKER-USER table. First of all, we introduce the DROP rule for all connections to the docker_zabbix network from the external interface (I have eth0 ).



 iptables -I DOCKER-USER -i eth0 -o docker_zabbix -j DROP
      
      





Now all connections are denied to the docker_zabbix network. Let's enable the connection for one ip address, more precisely, the packet can continue on further along FORWARD.



 iptables -I DOCKER-USER -i eth0 -s 192.168.43.55 -j RETURN
      
      





The docker_zabbix network was not explicitly specified here. We check the availability of zabbix from the host 192.168.43.55 using 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 port is open for zabbix docker. To make sure that zabbix belongs to port 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
      
      





But it should be noted that the rules must specify port 80, not 8081. If you specify port 8081, then access to zabbix will not be opened. For the second host, the command.



 iptables -I DOCKER-USER -i eth0 -p tcp --dport 80 -s 192.168.43.10 -j RETURN
      
      





For the third host, we open only port 10051, an active agent is used on this host.



 iptables -I DOCKER-USER -i eth0 -p tcp --dport 10051 -s 192.168.43.13 -j RETURN
      
      





Another problem, we can’t get out of containers into the outside world. Notification scripts do not work and can not check the availability of sites. There is one more command to resolve already existing connections.



 iptables -I DOCKER-USER -i eth0 -o docker_zabbix -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
      
      





Do not forget that after rebooting the server, the created rules are erased.



All Articles