I recreated the issue.
So on Groovy, installing ufw
and using its default configuration will use the iptables shim to insert nftables rules.
So LXD then uses nftables.
Installing nftables package allows you see both the rules added by UFW and by LXD.
However in its default configuration ufw drops all incoming traffic.
Although LXD has added allow rules for DHCP and DNS, these are still blocked because, as per nftables documentation: Configuring chains - nftables wiki
NOTE : If a packet is accepted and there is another chain, bearing the same hook type and with a later priority, then the packet will subsequently traverse this other chain. Hence, an accept verdict - be it by way of a rule or the default chain policy - isn’t necessarily final. However, the same is not true of packets that are subjected to a drop verdict. Instead, drops take immediate effect, with no further rules or chains being evaluated.
So you can get this working by allowing incoming traffic (which rather defeats the purpose of installing ufw):
ufw default allow incoming
Or you could add rules equivalent to those added in the lxd
chains, to ufw to allow inbound DNS and DHCP.
For more details on using ufw with LXD see