12

I am running Gentoo host with Ubuntu container in Docker. They communicate via bridge automatically created by Docker. I would like to drop all traffic for 192.168.0.0/16 that may come out of container.

$sudo iptables -S
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-A FORWARD -d 172.17.0.2/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 443 -j ACCEPT
-A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i docker0 ! -o docker0 -j ACCEPT
-A FORWARD -i docker0 -o docker0 -j ACCEPT
$sudo iptables -t nat -S
-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P OUTPUT ACCEPT
-P POSTROUTING ACCEPT
-N DOCKER
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 443 -j DNAT --to-destination 172.17.0.2:443

Please let me know if I need to provide extra information

i.petruk
  • 1,276
  • 1
  • 13
  • 18

3 Answers3

10

One option would be to run docker with --icc=false, preventing any container to communicate with other containers, you could then let containers communicate with each other by linking them with --link=container_name:alias. This will not block the container from communicating with the host at this time though.

You could also operate with iptables with a rule like:

iptables -A INPUT -i docker0 -d 192.168.0.0/16 -j DROP

keep in mind that a host doesn't see dropped packet coming back by icmp error, so maybe REJECT is more appropriate in most cases.

edit: correcting the rule to block the forward to other hosts:

iptables -I FORWARD -i docker0 -d 192.168.0.0/16 -j DROP
brthornbury
  • 3,518
  • 1
  • 22
  • 21
DRC
  • 4,898
  • 2
  • 21
  • 35
  • 3
    iptables has no effect (assuming -o docker0). --icc=false as I understand prevents intercontainer communications, but not with host. Anyway, I continue to get successful pings from within docker exec -t -i cont1 /bin/bash – i.petruk Nov 29 '14 at 22:04
  • Thanks, nice effect. I cannot ping the host, but I can ping other physical machines in the net. I presume forwarding is working – i.petruk Nov 29 '14 at 22:27
  • 1
    Cool, everything seems working. I should read more man pages. I tried sudo iptables -A FORWARD -d 192.168.0.0/16 -i docker0 -j DROP and it didn't help, which is not the same. – i.petruk Nov 29 '14 at 22:37
  • 1
    that is because other rules that allow the forwarding match first, -A appends , -I instead... I let you discover in the manpage :) – DRC Nov 29 '14 at 22:38
  • Typo: `-I` is _insert_ – Bryan Nov 30 '14 at 08:32
  • `--icc=false` does not block container to host communication. See: https://github.com/moby/moby/issues/21990 – brthornbury Feb 20 '18 at 08:22
1

As @DRC said, use

iptables -I FORWARD -i docker0 -d 192.168.0.0/16 -j DROP

Nevertheless, this rule will block traffic from your local network to your container (the connection will be established but your container won't be able to respond)

To allow connections from your local network to your container, you have to add also

iptables -I FORWARD -i docker0 -d 192.168.0.0/16 -m state --state ESTABLISHED,RELATED -j ACCEPT
1

fwiw, https://docs.docker.com/network/iptables/ says that rules inserted for DOCKER-USER are applied prior to any others, so I found that the following worked like a charm for preventing containers from accessing other machines on my home network:

iptables -I DOCKER-USER -d <net>/16 -j DROP

where

<net> refers to your local network (e.g. 10.1.10.0, 192.168.0.0).

I didn't need to restart any service for this to take effect; curl and ping stopped working immediately from within contains.