7

The docker manual (http://docs.docker.com/installation/ubuntulinux/#docker-and-ufw) states that it's nescessary to set UFWs DEFAULT_FORWARD_POLICY to "ACCEPT" so docker containers can reach each other.

  1. What's the security implication of doing so on a server with publicly accessible network interfaces?

  2. What should be done to secure such a docker host?

  • 1
    Yeah I don't know why it says this. And it says this without any disclaimers too.. – Jonathan Jun 20 '15 at 16:16
  • It's been some time since @Jadawin offered the community what seems to be a perfectly good answer. Can you accept it by checking the green mark under its point counter, so others may take advantage of it ? (Users go preferentially to accepted answers.) Cheers. – Cbhihe May 19 '17 at 9:03
  • It doesn't answer the first question, what are the implications of DEFAULT_FORWARD_POLICY – jakethedog May 26 '17 at 22:36
5

They seem to have solved this part of the problem, at least in the latest version 1.4.1. My FORWARD policy is to drop packets and inter-container communication works without problems.

Those are the standard rules in the FORWARD chain created by docker:

$ iptables -vnL FORWARD
Chain FORWARD (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in      out      source               destination         
 6902   96M ACCEPT     all  --  *       docker0  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
 6151  482K ACCEPT     all  --  docker0 !docker0 0.0.0.0/0            0.0.0.0/0           
    3   180 ACCEPT     all  --  docker0 docker0  0.0.0.0/0            0.0.0.0/0           

From bottom up:

  • The third rule is docker->docker communication, which is accepted without restrictions.
  • The second rule is docker->anywhere(but not docker), which is also accepted without restrictions.
  • The first rule is anywhere->docker, only "answer" packets get accepted.

No problems here. (Unless you want outgoing filters)

You can happily set FORWARD + INPUT policy to DROP/REJECT.

Now, you may want to provide a service on the internet. E.g. a simple webserver:

$ docker run -d -p 80:80 dockerfile/nginx

OK, now go to yourserver.com. You will see the default nginx page. Why? Docker added some special rules in iptables for you.

$ iptables -vn -t nat -L # NAT table, truncated for clarity
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
  189 11900 DOCKER     all  --  *      *       0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type LOCAL

Chain DOCKER (2 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DNAT       tcp  --  !docker0 *       0.0.0.0/0            0.0.0.0/0            tcp dpt:80 to:172.17.0.15:80

$ iptables -vnL FORWARD
Chain FORWARD (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 ACCEPT     tcp  --  !docker0 docker0  0.0.0.0/0            172.17.0.15          tcp dpt:80
 6903   96M ACCEPT     all  --  *      docker0  0.0.0.0/0            0.0.0.0/0            ctstate RELATED,ESTABLISHED
 6159  483K ACCEPT     all  --  docker0 !docker0  0.0.0.0/0            0.0.0.0/0           
    3   180 ACCEPT     all  --  docker0 docker0  0.0.0.0/0            0.0.0.0/0           

Those rules circumvent all of the ufw rules if there's a container listening. ufw does nothing in the nat table and Docker sets it's rules at the first place in the FORWARD chain. So it's not possible for you to block an IP address or do rate limiting of any kind.

Possible solutions:

  • Start Docker with --iptables=false and do everything manually. Painstaking solution, because everytime you restart a container, it gets a new IP (for now, they plan to change that).
  • Bind all ports on localhost with -p 127.0.0.1:30080:80 and create your own iptables rules to get there.
  • Modify ufw somehow?
  • Don't use any firewall framework. I do this for now. All my rules are saved in a separate script as iptables commands. This script is executed after reboots and every service docker start. Altough a bit hacky it works...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.