DNS configuration with local resolver/Pi-Hole and such

I would like some classifications regarding DNS configuration on OpenWrt, especially since, IMHO, it is all over the place through uci and LuCI.

If you would like to use a local DNS resolver (whatever the case may be, Pi-Hole w/ unbound or certain professional environments) behind an OpenWrt router, from what I could gather, you need to do the following AFAIK (please correct me if I am wrong or forgot something):

  1. The proper way to do it is to change netmask DHCP option to advertise the local resolver to the clients.
  2. This behavior does not disable the DNS cache/server of the OpenWrt router, which advertise itself to the local clients and results in the local resolver not able to discriminate requests on a per client basis.
  3. To avoid hardcoded DNS servers to bypass the local resolver, rules must be added to the firewall to redirect DNS traffic

In practice, this translates as the following:

  1. Add, 6,$(IP_LOCAL_DNS)) in LuCI to the following field Network > Interfaces > LAN > DHCP Server > Advanced Settings > DHCP-Options
  2. This can be seen on any device that requests a DHCP lease from the OpenWrt device with the DNS server advertise is the same as the default gateway or on the local DNS resolver which only receives requests originating from the OpenWrt router.
  3. Since LuCI does not provide all the iptables configurations in the Traffic Rules, this results in adding the following rules to Network > Firewall > Custom rules such as:
iptables -t nat -A POSTROUTING -j MASQUERADE
iptables -t nat -I PREROUTING -i br-lan -p tcp --dport 53 -j DNAT --to $(IP_LOCAL_DNS):53
iptables -t nat -I PREROUTING -i br-lan -p udp --dport 53 -j DNAT --to $(IP_LOCAL_DNS):53
iptables -t nat -I PREROUTING -i br-lan -p tcp -s $(IP_LOCAL_DNS) --dport 53 -j ACCEPT
iptables -t nat -I PREROUTING -i br-lan -p udp -s $(IP_LOCAL_DNS) --dport

More things I am interested in knowing either because I do not know what would be the best practices for or because I cannot really wrap my head around it:

  • Since the local DNS resolver is on the LAN, a OpenWrt device facing the Internet cannot use it for itself to avoid the "DNS advertised by peers" ; the next best thing I could find was using an upstream DNS service more privacy-oriented e.g. Quad9. (Side note, it avoids to have to add an upstream DNS server directly onto the local resolver)
  • The DNS traffic redirection does not seems to work as expected in some cases (e.g. Android devices), especially with Use DNS servers advertised by peer enabled in the WAN and WAN6. (Even if two local DNS are provided - it is a known issue with Android devices)
  • I would also be interested in knowing how to do what I do in LuCI with the 'new' version of uci, if someone has the time to document it.

Thanks to everyone who could help me grasp how OpenWrt handles DNS. Do not hesitate to ask me if something is not clear enough or if I made mistakes.

Masquerading can be configured in the firewall zone, but I don't know why you need to masquerade all traffic.

Can't you configure the rules above in "Port Forwards", it seems to work when I tested it.

What does ACCEPT rules in the nat table mean anyway?

All of that is clearly explained in the wiki: