dnsmasq answers on the interface, not on the address
The gateway pings from inside the container and its DNS never answers. I got the diagnosis wrong twice, and the second time it was my own test that was lying.
The container needed to send local names and reverse lookups to the UDM’s dnsmasq, and dnsmasq wasn’t answering it.
I got this wrong twice before I got it right, and both wrong answers sounded reasonable at the time.
The first was that dnsmasq receives the query and ignores it.
The second was that UniFi’s zone based firewall drops traffic arriving on br0.mac, which is a macvlan the firewall knows nothing about.
Neither is true.
The DNS drop rules counted zero packets, the LAN local chain ends in ACCEPT, the INPUT policy is ACCEPT, and a plain UDP packet from the container reached the host fine.
The probe was broken
What was actually failing was the test.
I’d written a small UDP DNS probe to check which servers answered from inside the container, and it returned false negatives for every server I pointed it at.
The control that exposed it was pointing the same probe at the Pi, which Technitium was successfully forwarding to at that exact moment. It failed too.
Re-running the same question with a real DNS client, Technitium’s own /api/dnsClient/resolve, showed all three servers answering normally.
So if you write your own probe, test it against a server you know answers before you believe anything it tells you.
Why it didn’t answer
The UDM’s dnsmasq runs with bind-dynamic and a list of interfaces:
interface=br0interface=br2interface=br3interface=br999interface=br1010bind-dynamic binds one socket per device in that list, instead of one socket on the wildcard address, so a query arriving on br0.mac isn’t delivered to any of those sockets no matter which address it was aimed at.
That’s why 10.2.0.1 pings fine from the container and its DNS never answers, and it’s the same for every other gateway address on the box.
So we need to name the shim in that list, and then dnsmasq binds a socket for it like any other device:
cat > /run/dnsmasq.dhcp.conf.d/macvlan.conf <<'EOF'interface=br0.macno-dhcp-interface=br0.macEOFkill -9 "$(cat /run/dnsmasq-main.pid)"ubios-udapi-server respawns dnsmasq, so killing it is the restart, and it interrupts DNS and DHCP for the whole house for a moment.
We need no-dhcp-interface as well, because br0.mac shares a broadcast domain with br0, and without it dnsmasq fields DHCP on the shim too and can answer LAN clients twice.
/run is tmpfs, so the drop-in is gone on every boot, so it lives in the boot script instead of being something I applied once by hand.
What it bought
Now the container can use the shim as a conditional forwarder, and reverse lookups work:
dig +short -x 192.168.178.1 @192.168.178.5dig +short -x 192.168.178.4 @192.168.178.5Before that Technitium answered every PTR with an empty reply while the UDM resolved them fine, and the dashboard showed a bare address for every client on the network.
That leg is also the one thing neither the router nor my laptop can test, because both sit on the other side of the shim, so bind9-dnsutils goes into the container even though I wanted to keep it small.