Netfilter & The Docker situation

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

Solution ISolution 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 IISolution II

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
systemctl restart docker
ps auxww | grep dockerd

so you can now play with your own rules but you need to take care of what dockerd needs

-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 already

Containers' NATContainers' 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 rulesWipe-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

ResourcesResources

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


HOME | GUIDES | LECTURES | LAB | SMTP HEALTH | HTML5 | CONTACT
Licensed under MIT