Docker & Shorewall

I'm using Shorewall on my server as simple standalone firewall and would like to use Docker as well.

By using a Docker container and its port redirection docker sets up its own iptables rules/chains which will be killed if shorewall is restarted. So the container will become unreachable.

Does anyone managed to save/restore the docker rules upon a shorewall restart or does anyone have another workaround?

See also:

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.

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

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.

One possible option is to run Docker with --net=host option, to allow containerized application access host network without ip forwarding and NAT.

The docker service can be restarted without impacting the running containers, and can be run after a Shorewall restart to reload the docker specific rules. There will obviously be a short time where networking to the container(s) is disrupted.

This is true at least on my few Archlinux installs.

The refresh action do not purgate the iptable so this if you just want to refresh rules or policies, you just may run refresh instead of restart :

sudo shorewall refresh

Obviously, the problem still remains if you really need to restart shorewall. Then, you have to restart docker and re-up your containers.