GitHub ↗

Docker Coexistence

easywall v1 flushed iptables and took Docker’s chains with it. v2 cannot: it owns one table and never looks at another.

easywall creates, flushes and replaces only table inet easywall. It never touches table ip docker or any other table.

An apply flushes and rebuilds table inet easywall. DOCKER, DOCKER-USER and DOCKER-ISOLATION live elsewhere and are not read, written or deleted.

Turning it on

[docker]
enabled               = true   # detect Docker bridge interfaces
allow_bridge_networks = true   # accept traffic from the detected CIDRs
custom_networks       = []     # anything detection misses

Detection reads the interfaces named docker* or br-* and takes the CIDR of each. It runs when rules are applied, not continuously — a network created afterwards needs another apply, or an entry in custom_networks.

Turn off the bogon filter on a container host. Bridge ranges are RFC 1918, which is exactly what that module drops. See firewall filters.

Three ways to run them together

  Setup Container ports reachable from outside Good for
1 enabled = truerecommended yes, Docker publishes them Most hosts
2 Docker with {"iptables": false} only if you add a port rule One firewall, one place to look
3 enabled = false, no published ports no Containers that only need outbound

Option 2 has a sharp edge. With iptables: false in /etc/docker/daemon.json, -p 80:80 no longer opens anything. Every container port you want reachable needs its own port rule. Outbound still works through Docker’s NAT.

Checking it worked

# easywall's table — rebuilt on every apply
sudo nft list table inet easywall

# Docker's — should be untouched
sudo nft list tables | grep -i docker