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.