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.