See also
This idea is not mine, nor is its execution. I got this from Jeff Keller: https://jeff.vtkellers.com/posts/technology/force-all-dns-queries-through-pihole-with-openwrt/ , and this is just my notes for future quick reference. Thanks, Jeff!
Why do this?
PiHole is great, and advertising it on your network via DHCP options is great-er, but devices (or operating systems) which really want to spy on you will probably hard-code their own DNS server IPs and completely ignore your PiHole.
That’s rude.
How to do this?
In OpenWRT, under Network ⇒ Firewall ⇒ Port forwards, add a new rule with the following settings:
- General settings:
- Protocol: TCP and UDP
- Source zone: (firewall zone you want this to take effect for)
- External port: 53
- Destination zone: (firewall zone your PiHole lives in)
- Internal IP address: (IP address of PiHole server)
- Internal port: 53
- Advanced settings:
- Source IP address: add a
!followed by the IP address of your PiHole (for example,!192.168.30.142)
- Source IP address: add a
Add a rule of that sort for all the firewall zones you want to force DNS for, if more than one. Pay attention to the Source and Destination firewall zones when sending traffic across zones.
Under Network ⇒ Firewall ⇒ NAT Rules, add a new rule with the following settings:
- General settings:
- Protocol: TCP and UDP
- Outbound zone: (firewall zone you want this to take effect for)
- Source address: any
- Source port: any
- Destination address: (IP address of the PiHole server)
- Destination port: 53
- Action: MASQUERADE
- Rewrite port: do not rewrite (leave empty)
I’m not certain if this rule needs to be added per firewall zone. I have two port forward rules, but only one NAT rule, and it’s been working fine.
Testing it works
- On the PiHole, add a record for a website that doesn’t exist. For example,
none.yoursite.comreferring to127.1.2.7. - On a device on the network, try to query a public DNS server such as quad9 for that domain:
dig none.yoursite.com @9.9.9.9 - Confirm you get a normal-looking response, seemingly from the quad9 server, but with the address you configured for the nonexistent domain.