Helping Docker get along with iptables

On the &yet Ops Team, we use Docker for various purposes on some of the servers we run. We also make extensive use of iptables so that we have consistent firewall rules to protect those servers against attacks.

Unfortunately, we recently ran into an issue that prevented us from building Dockerfiles from behind an iptables firewall.

Here's a bit more information about the problem, and how we solved it.

The Problem

When trying to run docker build on a host that provides our default DROP policy-based iptables set, apt-get was unable to resolve repository hosts on Dockerfiles that were FROM Ubuntu or debian.

Any apt-get command would result in something like this:

Step 1 : RUN apt-get update
 ---> Running in 64a37c06d1f4
Err http://http.debian.net wheezy Release.gpg
  Could not resolve 'http.debian.net'
Err http://http.debian.net wheezy-updates Release.gpg
  Could not resolve 'http.debian.net'
Err http://security.debian.org wheezy/updates Release.gpg
  Could not resolve 'security.debian.org'

To figure out what was going wrong, we logged all dropped packets in iptables to syslog like this:

# Log dropped outbound packets
iptables -N LOGGING
iptables -A OUTPUT -j LOGGING
iptables -A INPUT -j LOGGING
iptables -A FORWARD -j LOGGING
iptables -A LOGGING -m limit --limit 2/min -j LOG --log-prefix "IPTables-Dropped: " --log-level 4
iptables -A LOGGING -j DROP

The logs quickly showed that the docker0 interface was trying to FORWARD port 53 to the eth0 interface. In our case, the default FORWARD policy is DROP, so essentially iptables was dropping Docker's requests to forward the DNS port to the public interface and Internet at large.

Since Docker couldn't resolve the domain names where the Dockerfiles were located, it couldn't retrieve the data it needed.

A Solution

Hmm, so we needed to allow forwarding between docker0 and eth0 , eh? That's easy! We just added the following rules to our iptables set:

# Forward chain between docker0 and eth0
iptables -A FORWARD -i docker0 -o eth0 -j ACCEPT
iptables -A FORWARD -i eth0 -o docker0 -j ACCEPT

# IPv6 chain if needed
ip6tables -A FORWARD -i docker0 -o eth0 -j ACCEPT
ip6tables -A FORWARD -i eth0 -o docker0 -j ACCEPT

Add or alter these rules as needed, and you too will be able to build Dockerfiles properly behind an iptables firewall.

You might also enjoy reading:

Blog Archives: