I’ve been trying to understand the logic in docker containers and networks when it comes to the firewall rules and iptables. In a nutshell my workstation I run iptables with a default DROP/DENY policy for everything for added security. Yes some people can debate the value or effectiveness but that’s not the topic for this post. By doing a default deny/drop that means every port requires an in/out rule such as for 443 (https):
$IPT -A OUTPUT -o $LAN -p tcp --dport 443 -m state --state NEW,ESTABLISHED -j ACCEPT
$IPT -A INPUT -i $LAN -p tcp --sport 443 -m state --state ESTABLISHED -j ACCEPT
When it comes to docker containers I have multiple that are running in the 172.x.0.x/16 networks. Some I have setup with docker-compose.yml and I statically set the 172.20.0.2 or 172.19.0.2 type IP addresses so they don’t move around on me and I can consistently use them.
In this case I am running a postgres:16.1 bound to 172.18.0.2:5432 (port 5432 being postgres service port).
When I look at my iptables chains I see the following:
Chain DOCKER (4 references)
target prot opt source destination
ACCEPT tcp – anywhere 172.19.0.2 tcp dpt:http
ACCEPT tcp – anywhere 172.20.0.2 tcp dpt:http
Chain DOCKER-ISOLATION-STAGE-1 (1 references)
target prot opt source destination
DOCKER-ISOLATION-STAGE-2 all – anywhere anywhere
DOCKER-ISOLATION-STAGE-2 all – anywhere anywhere
DOCKER-ISOLATION-STAGE-2 all – anywhere anywhere
DOCKER-ISOLATION-STAGE-2 all – anywhere anywhere
RETURN all – anywhere anywhere
Chain DOCKER-ISOLATION-STAGE-2 (4 references)
target prot opt source destination
DROP all – anywhere anywhere
DROP all – anywhere anywhere
DROP all – anywhere anywhere
DROP all – anywhere anywhere
RETURN all – anywhere anywhere
Chain DOCKER-USER (1 references)
target prot opt source destination
RETURN all – anywhere anywhere
What I am trying to understand is with this default deny setup I have, what rules would I need to configure in order to reach 172.18.0.2:5432 (as a postgres container)? I get confused on how the DOCKER, DOCKER-ISOLATION-STAGE-1, DOCKER-ISOLATION-STAGE-2, and DOCKER-USER chains function. Naturally if I drop all my iptables rules and revert to ACCEPT|ALLOW everything works. The service for docker seems to maintain the DOCKER* chains causing me grief anytime I modify or reload my iptables scripts. If there is a good source anyone can point me to that clearly articulates the DOCKER* chains AND how to work with them using a default DENY iptables ruleset that would be greatly appreciated.