Pi-Hole dns.listeningMode settings vs. default AdGuard

Note that this is solved, I am just looking to understand why this setting solves it, and what the alternatives could be.

The issue I am facing:

I switched from AdGuard Home to PiHole recently, for PiHole's support for multiple local DNS records per domain.

When running AdGuard, I set the Raspberry Pi as the upstream DNS resolver for the entire router.
When I switched to PiHole, that did not work at all - it only worked when putting it as the DNS resolver for the router's DHCP config. This configuration seemed significantly slower on all of our devices, though I have no real proof that this configuration was the culprit. Maybe the router is running its own DNS cache that does not get used by the DHCP clients?

Anyway, the setting that finally got it working again with PiHole only as the router's upstream DNS was setting dns.listeningMode to:

SINGLE

Permit all origins, accept only on the specified interface. Respond only to queries arriving on the specified interface. The loopback (lo) interface is automatically added to the list of interfaces to use when this option is used. Make sure your Pi-hole is properly firewalled!

I am a bit confused why the devices on basic my home network did not qualify for the default setting:

LOCAL (default)

Allow only local requests. This setting accepts DNS queries only from hosts whose address is on a local subnet, i.e., a subnet for which an interface exists on the server.

I do not quite understand what is meant up by “a subnet for which an interface exists on the server”

...and of course whether running with this setting would be any cause for concern.

Details about my system:

Router is 192.168.0.1, all clients receive that IP as their DNS IP when connecting.

PiHole is statically assigned IP 192.168.103.0 by the DHCP server running on my router, which covers my whole local subnet, 192.168.0.2-192.168.255.254.

Wifi is disabled and the Raspberry Pi only uses eth0 - output of ip a for that is:

2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000link/ether dc:a6:32:30:0f:62 brd ff:ff:ff:ff:ff:ffinet 192.168.103.0/16 brd 192.168.255.255 scope global noprefixroute eth0

So the Raspberry Pi - and PiHole are bound to the entire subnet.

The only other non-default thing I am doing is that the Raspberry Pi's local hostname + domain is `rpi.lan` rather than `pi.hole`.

What I have changed since installing Pi-hole:

Just added a few local DNS records for the Pi itself and a TrueNas box.

And of course now changed the dns.listeningMode setting.

Please upload a debug log and post just the token URL that is generated after the log is uploaded by running the following command from the Pi-hole host terminal:

pihole -d

or if you run your Pi-hole as a Docker container:

docker exec -it <pihole-container-name-or-id> pihole -d

where you substitute <pihole-container-name-or-id> as required.

It's the default setting which allows Pi-hole to respond to, for example, any host with a 192.168.1.x IP address, as long as the OS and Pi has a network interface also configured on the 192.168.1.x network.

This is a very common ISP home router type setup – connect something to your router, either via wifi or ethernet, and they can all talk to each other because they're all on the same private subnet. With this setting, if a request comes to Pi-hole from some other network's IP, Pi-hole will ignore that request since it doesn't have a network interface configured on that other network.

You can leave it set to Local unless you have some specific reason to change it.

https://tricorder.pi-hole.net/NnifuL4s/

As stated in the post, I had to turn it from Local to Single because PiHole was not responding to requests on the 1.92.168.0.1/16 subnet, even though it is only using the eth0 interface bound to that subnet.

However it was only not responding when those requests came from the router (192.168.0.1) on behalf of the client. It was fine when they came directly from the other local network clients themselves.

I wasn't commenting on your specific situation, I was explaining the phrase which you mentioned you did not quite understand.

Yeah, that’s the basic understanding I had for the definition of the phrase. I just have not been able to figure out how the current config doesn’t qualify for that. RPi and PiHole being bound to that whole subnet on eth0 works perfectly when the requests come from the clients directly but not when it comes from the router.

Out of interest can you say why you're using a /16 for this network, giving you 65.5K available hosts?

The router is at the bottom end at 192.168.0.1 and Pi-hole on the Pi's ethernet port is at 192.168.103.0 and it can reach the router and external servers no problem. Ad blocking is working correctly.

The router is handing out itself as the DNS server, and presumably is using Pi-hole as its upstream as you mentioned. Note that this means you lose the ability to see which clients are making which requests – they will all come from the router and if the network is in fact large, which a /16 might imply, the router might exceed Pi-hole's query rate limits.

The other way you mention, where the router hands out Pi-hole's IP via DHCP as the sole DNS, would allow you to have a granular view and avoid that router rate limit problem, should it arise.

Does the router have some kind of external access, such that non-192.168.0.0/16 addresses can come in, maybe "VPN" in or from a different network also serviced by that router, and make queries of it, which will also be sent to Pi-hole? Your log appears to show an external IP making PTR queries of your subnet, presumably trying to find out hostnames of your subnet IPs.

It's not clear to me what's going on. But perhaps that could explain the perception that it's not working when only responding to queries from the /16 subnet vs appearing to work when responding to any external address.

Can you explain more about it?

You can inspect your own debug log, and the logs at the end of it, with the command below in the Pi-hole's terminal:

sudo less -r /var/log/pihole/pihole_debug.log

Out of interest can you say why you're using a /16 for this network, giving you 65.5K available hosts?

Simply because it was the router default, always has been.

…if the network is in fact large, which a /16 might imply, the router might exceed Pi-hole's query rate limits.

I only have 14 total clients on the newtork, including a range extender and some stuff that is never used.
It’s basically just two people’s laptops, phones, and a Roku making all the queries so I would be surprised if any rate limit is getting hit.

Does the router have some kind of external access, such that non-192.168.0.0/16 addresses can come in, maybe "VPN" in or from a different network also serviced by that router, and make queries of it, which will also be sent to Pi-hole? Your log appears to show an external IP making PTR queries of your subnet, presumably trying to find out hostnames of your subnet IPs.

This might be it
That is my router’s public IP address assigned by my ISP.
I bet the router is making its DNS queries using its public IP.

I didn’t investigate previously because it seems that the “Pi-hole diagnosis UI” was sort of collapsing these all into one warning, I thought it was a fluke - I did not realize it was a constant thing that all the queries were coming from that IP.

I will look into whether there is away to make this work while still having a similar level of security as the Local-only default, as it does seem to have a lot better performance with the router between all the clients and then calling upstream to the PiHole rather than the clients going directly to the PiHole.