Docker & Shorewall

Solution 1:

The following configuration changes should ensure traffic flow between Docker and the Shorewall host. Tested on Shorewall 4.5.21.9 but should apply to most recent versions:

/etc/shorewall/shorewall.conf

Make sure IP forwarding is enabled (most config items are Yes/No, but this one is "On"):

IP_FORWARDING=On

/etc/shorewall/masq

Enable masquerading (NAT) for your private Docker network (if you use a different network, i.e. you launch docker with --bip=#.#.#.#/#, then change accordingly). Change eth0 to any interface on the host machine with external connectivity:

#INTERFACE:DEST         SOURCE
eth0                    172.17.0.0/16

/etc/shorewall/interfaces

Add an interface entry so Shorewall knows which interface the dock zone relates to:

#ZONE           INTERFACE               OPTIONS
dock            docker0

/etc/shorewall/zones

Create a new zone; note, docker is too long and will cause an "invalid zone name" error.

#ZONE   INTERFACE
dock    ipv4

/etc/shorewall/policy

You probably want to allow Docker containers to talk to the host machine and the Internet, so this is a good starting point:

#SOURCE         DEST            POLICY
# ...(other policies)...
dock            all             ACCEPT
# ...(other policies, catch-all)...

You may also need a similar ACCEPT policy for traffic from fw to dock, if you didn't already open it up with fw to all.

You can tighten this up further in the policy or rules files as needed. For example, the above does not explicitly allow outside traffic to reach your Docker containers; check your other zones/policies/rules for that.

Solution 2:

Since Docker introduced its network isolation feature, the other solutions mentioned here are no longer sufficient if you want to use custom networks. Shorewall 5.0.6 introduces support for Docker including Docker networks. This:

  • Allows shorewall and docker to be started/stopped/restarted in any order
  • Avoids the need for maintaining an extension script

Solution 3:

Just figured it out on my box. Make sure /etc/shorewall.conf has:

IP_FORWARDING=Yes

Docker relies on forwarding, and I spaced that 'puppet' sets it to 'No' on all my servers.

Update: You probably also need to masquerade traffic coming from docker out your WAN interface.

Edit /etc/shorewall/masq and you'll need a line similar to:

br0 172.17.0.0/12

In this case, my WAN interface is actually br0 (a bridge), but yours will probably be something like eth0. (Use ifconfig to see your interfaces and their IP addresses). On my machine docker uses 172.17.0.0/24 which is an RFC1918 private address range. This may differ on other systems, but you can see the range by using ifconfig once again to look for the interface docker0.


Solution 4:

You can ensure that the Docker ruleset survives a shorewall restart by creating extension scripts which save the DOCKER chain before the restart, and then restore it again afterwards. I've just put up a post with an example of how to do this, although I'm sure it's far from the only possible method.