I really hate iptables so I use nftables wherever possible. However I found this gist.
Not happy with Docker modifying your precious firewall rules?
- Docker inserts iptables rules when it’s started by default
- buster uses nftables by default
- let’s make Docker use nftables instead
- PROFIT
Prerequisites
Install Docker CE and nftables:
$ sudo apt-get install nftables $ sudo systemctl --now enable nftables
Installing
Manually (create/modify daemon.json before starting docker.service):
$ sudo systemctl start docker $ sudo systemctl stop docker containerd $ sudo iptables-save > iptables-docker.conf $ sudo iptables-restore-translate -f iptable-docker.conf > docker.nft $ sudo nft flush ruleset $ sudo nft -f docker.nft $ sudo nft -s list ruleset > /etc/nftables-docker.conf
tl;dr
$ curl -fsSLO https://gist.github.com/goll/bdd6b43c2023f82d15729e9b0067de60/raw/nftables-docker.sh $ sudo bash -x nftables-docker.sh
For a persistent config just overwrite /etc/nftables.conf with /etc/nftables-docker.conf
If you prefer manual start/stop you can create an alias for example:
alias dock-on='sudo nft -f /etc/nftables-docker.conf && sudo systemctl start docker' alias dock-off='sudo systemctl stop docker containerd && sudo nft -f /etc/nftables.conf && sudo ip l d docker0'
Then they provide a way to prevent docker from changing firewall settings.
#!/bin/bash systemctl stop docker containerd tee /etc/docker/daemon.json << EOF { "iptables": false } EOF
curl -fsSLO https://gist.github.com/goll/bdd6b43c2023f82d15729e9b0067de60/raw/nftables-docker.conf -o /etc/nftables-docker.conf && nft -f /etc/nftables-docker.conf systemctl start docker
So I did this and combined it with the above rule that @tomp wrote giving a ruleset like this:
table ip nat {
chain PREROUTING {
type nat hook prerouting priority dstnat; policy accept;
fib daddr type local counter jump DOCKER
}
chain INPUT {
type nat hook input priority 100; policy accept;
}
chain OUTPUT {
type nat hook output priority -100; policy accept;
ip daddr != 127.0.0.0/8 fib daddr type local counter jump DOCKER
}
chain POSTROUTING {
type nat hook postrouting priority srcnat; policy accept;
oifname != "docker0" ip saddr 172.17.0.0/16 counter masquerade
}
chain DOCKER {
iifname "docker0" counter return
}
}
table ip filter {
chain INPUT {
type filter hook input priority filter; policy accept;
}
chain FORWARD {
type filter hook forward priority filter; policy drop;
oifname "lxdbr0" counter accept comment "generated for LXD network lxdbr0"
iifname "lxdbr0" counter accept comment "generated for LXD network lxdbr0"
counter jump DOCKER-USER
counter jump DOCKER-ISOLATION-STAGE-1
oifname "docker0" ct state established,related counter accept
oifname "docker0" counter jump DOCKER
iifname "docker0" oifname != "docker0" counter accept
iifname "docker0" oifname "docker0" counter accept
}
chain OUTPUT {
type filter hook output priority filter; policy accept;
}
chain DOCKER {
}
chain DOCKER-ISOLATION-STAGE-1 {
iifname "docker0" oifname != "docker0" counter jump DOCKER-ISOLATION-STAGE-2
counter return
}
chain DOCKER-ISOLATION-STAGE-2 {
oifname "docker0" counter drop
counter return
}
chain DOCKER-USER {
counter return
}
}
Note that the rules @tomp mentions:
are these in nftables syntax:
oifname "lxdbr0" counter accept comment "generated for LXD network lxdbr0"
iifname "lxdbr0" counter accept comment "generated for LXD network lxdbr0"
These rules must be above the JUMP rules in the FORWARD chain.