LXD and Docker Firewall Redux - How to deal with FORWARD policy set to drop

I really hate iptables so I use nftables wherever possible. However I found this gist.

Not happy with Docker modifying your precious firewall rules?

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.