Netfilter & The Docker situation

Ok, so you have Docker in place. There are two courses of action.

Solution I

Let Docker maintain its own rules in the DOCKER chain (opening the mapped ports to the world). For that, you need to tweak your rules so it does not interfere with the DOCKER, DOCKER-ISOLATION chains nor the nat table (and possibly mangle?) maintained by the Docker daemon, and keep a reference of those chains into the FORWARD chain.

Note. We have to avoid wiping out the entire table because the iptables-restore command will conflict with the Docker daemon: you would have to restart it after you apply your own firewall rules, with the unpleasant effect of stopping all the containers.

The main table automatically maintained by Docker

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
DOCKER-ISOLATION  all  --  anywhere             anywhere
DOCKER     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere             ctstate RELATED,ESTABLISHED
ACCEPT     all  --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain DOCKER (1 references)
target     prot opt source               destination

Chain DOCKER-ISOLATION (1 references)
target     prot opt source               destination
RETURN     all  --  anywhere             anywhere

The nat table automatically maintained by Docker

Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination
DOCKER     all  --  anywhere             anywhere             ADDRTYPE match dst-type LOCAL

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination
DOCKER     all  --  anywhere            !127.0.0.0/8          ADDRTYPE match dst-type LOCAL

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination
MASQUERADE  all  --  172.17.0.0/16        anywhere

Chain DOCKER (2 references)
target     prot opt source               destination
RETURN     all  --  anywhere             anywhere

The workaround

# let Docker do its job
iptables -A FORWARD -j DOCKER-ISOLATION
iptables -A FORWARD -o docker0 -j DOCKER
iptables -A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

iptables -A FORWARD -i docker0 -j ACCEPT
#iptables -A FORWARD -i docker0 ! -o docker0 -j ACCEPT
#iptables -A FORWARD -i docker0 -o docker0 -j ACCEPT

Solution II

I read about) preventing it from managing its rules and take over the shit

vi /etc/default/docker

DOCKER_OPTS=--iptables=false

ps auxww | grep dockerd
service restart docker
ps auxww | grep dockerd

so you can now play with your own rules but you need to take care of the Docker needs yourself e.g.

-A FORWARD -i docker0 -o INTERFACE -j ACCEPT
-A FORWARD -i INTERFACE -o docker0 -j ACCEPT

-A FORWARD -p tcp -m state --state NEW --dport 80 -j ACCEPT
-A FORWARD -p tcp -m state --state NEW --dport 443 -j ACCEPT

preferably open only the ports you’ve reverse-proxied

Containers' NAT

draft

Also allow the containers to access internet using NAT

sysctl net.ipv4.conf.all.forwarding
sysctl net.ipv4.conf.all.forwarding=1
vi /etc/iptables.rules

*nat

__TODO__

COMMIT

Wipe-out rules

To clean up your rules (esp. in the DOCKER chain that we do not want to flush),

iptables -L DOCKER -n | grep ^REJECT | awk '{print $4}' | uniq
for ip in `iptables -L DOCKER -n | grep ^REJECT | awk '{print $4}' | uniq`; do echo -n $ip...; iptables -D DOCKER -s $ip -j REJECT && echo done; done; unset ip
iptables -L DOCKER -n | grep ^REJECT | awk '{print $4}' | uniq

iptables -L DOCKER -n | grep ^RETURN | awk '{print $4}' | uniq
for ip in `iptables -L DOCKER -n | grep ^RETURN | awk '{print $4}' | uniq`; do echo -n $ip...; iptables -D DOCKER -s $ip -j RETURN && echo done; done; unset ip
iptables -L DOCKER -n | grep ^RETURN | awk '{print $4}' | uniq

iptables -L DOCKER -n | grep ^DROP | awk '{print $4}' | uniq
for ip in `iptables -L DOCKER -n | grep ^DROP | awk '{print $4}' | uniq`; do echo -n $ip...; iptables -D DOCKER -s $ip -j DROP && echo done; done
iptables -L DOCKER -n | grep ^DROP | awk '{print $4}' | uniq

So in the end if you got only one container running with e.g. ports 25 143 597 up,

Chain DOCKER (1 references)
target     prot opt source               destination         
ACCEPT     tcp  --  0.0.0.0/0            172.17.0.X           tcp dpt:587
ACCEPT     tcp  --  0.0.0.0/0            172.17.0.X           tcp dpt:143
ACCEPT     tcp  --  0.0.0.0/0            172.17.0.X           tcp dpt:25

Resources

Understanding Docker Networking Drivers and their use cases https://blog.docker.com/2016/12/understanding-docker-networking-drivers-use-cases/


HOME | GUIDES | BENCHMARKS | html