Pihole with multiple local domains

Please follow the below template, it will help us to help you!

Expected Behaviour:

Pi-hole honors the given servers directives within /etc/dnsmasq.d for specified domains.
Given following settings are specified in /etc/dnsmasq.d/99-local_servers.conf:
server=/servers.local/10.10.10.3
server=/lit.int/10.10.30.3
server=/home/10.10.40.1
server=/dmz/10.1.1.1
server=/rw/10.10.60.1
Pi-hole should honor these servers and resolve the queries accordingly.
myhost.dmz should be resolved via 10.1.1.1 and another-host.rw should be resolved via 10.10.60, etc - however, every other (not explicitly specified) domain should be resolved via the upstream servers defined.

Actual Behaviour:

Pi-Hole does not honor the server directive if providing said directive for (multiple) local domains. Local addresses are not resolved in any way.

Debug Token:

https://tricorder.pi-hole.net/1tndesgy5g

The debugger doesn't list any extra files in /etc/dnsmasq.d. Can you get a list of files from there? sudo ls -la /etc/dnsmasq.d.

What IP addresses are returned when a client queries for one of the local domains? Do the queries show on the admin panel query log? Do the clients show on the panel client list page as using Pi-hole for their DNS?

root@pihole:/home/steffen# ls -la /etc/dnsmasq.d
total 16
drwxr-xr-x  2 root root 4096 Dec 22 16:54 .
drwxr-xr-x 98 root root 4096 Dec 22 16:43 ..
-rw-r--r--  1 root root 1418 Dec 22 16:39 01-pihole.conf
-rw-r--r--  1 root root  127 Dec 22 16:38 99-local_servers.conf
root@pihole:/home/steffen# cat /etc/dnsmasq.d/99-local_servers.conf 
server=/servers.local/10.10.10.3
server=/lit.int/10.10.30.3
server=/home/10.10.40.1
server=/dmz/10.1.1.1
server=/rw/10.10.60.1

What IP addresses are returned when a client queries for one of the local domains?
Trying to resolve any host from the local commandline from the pihole itself results in the following:

root@pihole:/home/steffen# ping -c1 openwrt.lan
ping: openwrt.lan: Name or service not known
root@pihole:/home/steffen# dig openwrt.lan

; <<>> DiG 9.10.3-P4-Raspbian <<>> openwrt.lan
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 6232
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;openwrt.lan.                   IN      A

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Mon Dec 23 13:27:15 CET 2019
;; MSG SIZE  rcvd: 40

root@pihole:/home/steffen#

However, the host exists (querying the router directly, which should be done from dnsmasq via the server directive):

root@pihole:/home/steffen# dig @10.10.20.1 openwrt.lan

; <<>> DiG 9.10.3-P4-Raspbian <<>> @10.10.20.1 openwrt.lan
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 35752
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;openwrt.lan.                   IN      A

;; ANSWER SECTION:
openwrt.lan.            0       IN      A       10.10.20.1

;; Query time: 0 msec
;; SERVER: 10.10.20.1#53(10.10.20.1)
;; WHEN: Mon Dec 23 13:15:23 CET 2019
;; MSG SIZE  rcvd: 56

Do the queries show on the admin panel query log?
Do the clients show on the panel client list page as using Pi-hole for their DNS?
I haven't started populating the pi-hole as DNS for any client, because they wouldn't be able to resolve local domains (which are in use pretty heavily).
At the moment I am using the pi-hole as upstream DNS for every router, which serves a local domain. This way, local domains are resolved on the routers and everything else on the pi-hole.
However, this way I cannot see which clients are actually doing DNS lookups, as the router makes the query to the pi-hole - hence the desire to change it.

Thanks!

What is the output of this command to check dnsmasq syntax: pihole-FTL dnsmasq-test

root@pihole:/home/steffen# pihole-FTL dnsmasq-test
dnsmasq: syntax check OK.

Within /etc/dnsmasq.conf the directory /etc/dnsmasq.d/ is given to include configuration files from.

root@pihole:/home/steffen# cat /etc/dnsmasq.conf
conf-dir=/etc/dnsmasq.d
root@pihole:/home/steffen#

For the dig command you posted (dig openwrt.lan), run from the Pi terminal, what are the matching entries in /var/log/pihole.log

root@pihole:/home/steffen# grep openwrt.lan /var/log/pihole.log
Dec 23 13:14:47 dnsmasq[11283]: query[A] openwrt.lan from 127.0.0.1
Dec 23 13:14:47 dnsmasq[11283]: forwarded openwrt.lan to 1.0.0.1
Dec 23 13:14:47 dnsmasq[11283]: query[AAAA] openwrt.lan from 127.0.0.1
Dec 23 13:14:47 dnsmasq[11283]: forwarded openwrt.lan to 1.0.0.1
Dec 23 13:14:47 dnsmasq[11283]: reply openwrt.lan is NXDOMAIN
Dec 23 13:14:47 dnsmasq[11283]: reply openwrt.lan is NODATA-IPv6
Dec 23 13:14:47 dnsmasq[11283]: query[A] openwrt.lan.lan from 127.0.0.1
Dec 23 13:14:47 dnsmasq[11283]: forwarded openwrt.lan.lan to 1.0.0.1
Dec 23 13:14:47 dnsmasq[11283]: query[AAAA] openwrt.lan.lan from 127.0.0.1
Dec 23 13:14:47 dnsmasq[11283]: forwarded openwrt.lan.lan to 1.0.0.1
Dec 23 13:14:47 dnsmasq[11283]: reply openwrt.lan.lan is NXDOMAIN
Dec 23 13:14:47 dnsmasq[11283]: reply openwrt.lan.lan is NODATA-IPv6
Dec 23 13:22:39 dnsmasq[11283]: query[A] openwrt.lan from 127.0.0.1
Dec 23 13:22:39 dnsmasq[11283]: cached openwrt.lan is NXDOMAIN
Dec 23 13:27:15 dnsmasq[11283]: query[A] openwrt.lan from 127.0.0.1
Dec 23 13:27:15 dnsmasq[11283]: cached openwrt.lan is NXDOMAIN
root@pihole:/home/steffen# 

openwrt.lan is not in 99-local_servers.conf. Where is the IP to name mapping set up?

I don't actually know what you mean.
With the following (wall of) text I'd like to thoroughly describe my issue and (hopefully) answer your question(s).

The file 99-local_servers.conf contains mappings of internal domains and where the specified domains should be resolved from.
See Man page of DNSMASQ (look for --server)
Quote:

Specify IP address of upstream servers directly. Setting this flag does not suppress reading of /etc/resolv.conf, use --no-resolv to do that. If one or more optional domains are given, that server is used only for those domains and they are queried only using the specified server. This is intended for private nameservers: if you have a nameserver on your network which deals with names of the form xxx.internal.thekelleys.org.uk at 192.168.1.1 then giving the flag --server=/internal.thekelleys.org.uk/192.168.1.1 will send all queries for internal machines to that nameserver, everything else will go to the servers in /etc/resolv.conf. DNSSEC validation is turned off for such private nameservers, UNLESS a --trust-anchor is specified for the domain in question. An empty domain specification, // has the special meaning of "unqualified names only" ie names without any dots in them. A non-standard port may be specified as part of the IP address using a # character. More than one --server flag is allowed, with repeated domain or ipaddr parts as required.

Same can also be found on https://linux.die.net/man/8/dnsmasq (look for --server).

So, the following configuration

root@pihole:/home/steffen# cat /etc/dnsmasq.d/99-local_servers.conf 
server=/servers.local/10.10.10.3
server=/lit.int/10.10.30.3
server=/home/10.10.40.1
server=/dmz/10.1.1.1
server=/rw/10.10.60.1

equals to
--server=/servers.local/10.10.10.3 --server=/lit.int/10.10.30.3 --server=/home/10.10.40.1 --server=/dmz/10.1.1.1 --server=/rw/10.10.60.1

Means in conclusion:
*.servers.local (eg myhostname.servers.local) will be resolved from 10.10.30.3, *.lit.int (eg another-host-name.lit.int) will be resolved from 10.10.30.3, and so forth.
I have multiple "vanilla" dnsmasq servers configured with those directives - they resolve perfectly fine.

See the following demonstration:

root@OpenWrt.lan:~$ for host in openwrt.lan openwrt.dmz openwrt.home dns.lit.int dns.servers.local; do dig $host; grep $host /var/log/dnsmasq/dnsmasq.log; done

; <<>> DiG 9.11.2-P1 <<>> openwrt.lan
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 57398
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;openwrt.lan.                   IN      A

;; ANSWER SECTION:
openwrt.lan.            0       IN      A       10.10.20.1

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Mon Dec 23 19:29:44 CET 2019
;; MSG SIZE  rcvd: 56

Dec 23 19:29:44 dnsmasq[11011]: 28113 127.0.0.1/46064 query[A] openwrt.lan from 127.0.0.1
Dec 23 19:29:44 dnsmasq[11011]: 28113 127.0.0.1/46064 /tmp/hosts/dhcp.cfg01411c openwrt.lan is 10.10.20.1

; <<>> DiG 9.11.2-P1 <<>> openwrt.dmz
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 46336
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;openwrt.dmz.                   IN      A

;; ANSWER SECTION:
openwrt.dmz.            0       IN      A       10.1.1.1

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Mon Dec 23 19:29:44 CET 2019
;; MSG SIZE  rcvd: 56

Dec 23 19:29:44 dnsmasq[11011]: 28114 127.0.0.1/33565 query[A] openwrt.dmz from 127.0.0.1
Dec 23 19:29:44 dnsmasq[11011]: 28114 127.0.0.1/33565 forwarded openwrt.dmz to 10.1.1.1
Dec 23 19:29:44 dnsmasq[11011]: 28114 127.0.0.1/33565 reply openwrt.dmz is 10.1.1.1

; <<>> DiG 9.11.2-P1 <<>> openwrt.home
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 35273
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;openwrt.home.                  IN      A

;; ANSWER SECTION:
openwrt.home.           0       IN      A       10.10.40.1

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Mon Dec 23 19:29:44 CET 2019
;; MSG SIZE  rcvd: 57

Dec 23 19:29:44 dnsmasq[11011]: 28115 127.0.0.1/34894 query[A] openwrt.home from 127.0.0.1
Dec 23 19:29:44 dnsmasq[11011]: 28115 127.0.0.1/34894 forwarded openwrt.home to 10.10.40.1
Dec 23 19:29:44 dnsmasq[11011]: 28115 127.0.0.1/34894 reply openwrt.home is 10.10.40.1

; <<>> DiG 9.11.2-P1 <<>> dns.lit.int
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 24210
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;dns.lit.int.                   IN      A

;; ANSWER SECTION:
dns.lit.int.            604568  IN      A       10.10.30.3

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Mon Dec 23 19:29:44 CET 2019
;; MSG SIZE  rcvd: 56

Dec 23 19:25:52 dnsmasq[11011]: 27066 127.0.0.1/37659 query[A] dns.lit.int from 127.0.0.1
Dec 23 19:25:52 dnsmasq[11011]: 27066 127.0.0.1/37659 forwarded dns.lit.int to 10.10.30.3
Dec 23 19:25:52 dnsmasq[11011]: 27066 127.0.0.1/37659 reply dns.lit.int is 10.10.30.3
Dec 23 19:29:44 dnsmasq[11011]: 28116 127.0.0.1/36636 query[A] dns.lit.int from 127.0.0.1
Dec 23 19:29:44 dnsmasq[11011]: 28116 127.0.0.1/36636 cached dns.lit.int is 10.10.30.3

; <<>> DiG 9.11.2-P1 <<>> dns.servers.local
;; global options: +cmd
;; Got answer:
;; WARNING: .local is reserved for Multicast DNS
;; You are currently testing what happens when an mDNS query is leaked to DNS
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 13148
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;dns.servers.local.             IN      A

;; ANSWER SECTION:
dns.servers.local.      604557  IN      A       10.10.10.3

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Mon Dec 23 19:29:44 CET 2019
;; MSG SIZE  rcvd: 62

Dec 23 19:25:41 dnsmasq[11011]: 27062 127.0.0.1/55127 query[A] dns.servers.local from 127.0.0.1
Dec 23 19:25:41 dnsmasq[11011]: 27062 127.0.0.1/55127 forwarded dns.servers.local to 10.10.10.3
Dec 23 19:25:41 dnsmasq[11011]: 27062 127.0.0.1/55127 reply dns.servers.local is 10.10.10.3
Dec 23 19:29:44 dnsmasq[11011]: 28117 127.0.0.1/56825 query[A] dns.servers.local from 127.0.0.1
Dec 23 19:29:44 dnsmasq[11011]: 28117 127.0.0.1/56825 cached dns.servers.local is 10.10.10.3
root@OpenWrt.lan:~$ 

and the corresponding dnsmasq configuration:

root@OpenWrt.lan:~$ grep -Ev '#|^$' /etc/dnsmasq.conf dhcp-option=252,"\n" log-facility=/var/log/dnsmasq/dnsmasq.log log-async=15 pid-file=/var/run/dnsmasq/dnsmasq.pid server=/servers.local/10.10.10.3 server=/lit.int/10.10.30.3 server=/home/10.10.40.1 server=/dmz/10.1.1.1 server=/rw/10.10.60.1 server=1.1.1.1 root@OpenWrt.lan:~$

I ported the exact same configuration (besides the dhcp stuff, as pi-hole is not acting as dhcp server in the network) to the dnsmasq instance, which is used from pi-hole. I would have specified it directly in
/etc/dnsmasq.conf, but I thought that it might get overwritten during an upgrade, hence the file 99-local_servers.conf

With that "demonstration" I just wanted to show, that my approach is indeed an intended behavior from dnsmasq, which works and therefore - in my personal opinion - should be working within pi-hole as well.

The only part, where I am not "conform" with the specifications is the servers.local domain (.local domain), which actually is reserved for mDNS (according to RFC 6762 - Multicast DNS)
But then again:

Any DNS query for a name ending with ".local." MUST be sent to the mDNS IPv4 link-local multicast address 224.0.0.251 (or its IPv6 equivalent FF02::FB). The design rationale for using a fixed multicast address instead of selecting from a range of multicast addresses using a hash function is discussed in Appendix B. Implementers MAY choose to look up such names concurrently via other mechanisms (e.g., Unicast DNS) and coalesce the results in some fashion. Implementers choosing to do this should be aware of the potential for user confusion when a given name can produce different results depending on external network conditions (such as, but not limited to, which name lookup mechanism responds faster).

dnsmasq will resolve the domain properly unless you specify stop-dns-rebind without whitelisting the domain(s) using rebind-domain-ok=/servers.local/. (Also described in Man page of DNSMASQ and https://linux.die.net/man/8/dnsmasq).

Thanks for your help!

//EDIT

Where is the IP to name mapping set up?

I think I now understand your question. The IP to name mapping is done on the respective dns for the specified domains.
For example:

  • office-printer.lan has a DNS entry on the "authoritive" resolver for that domain, in this case openwrt.lan (10.10.20.1)
  • access-point.home has a DNS entry on the "authoritive" resolver for that domain, in this case openwrt.home (10.10.40.1)
  • ansible.lit.int has a DNS entry on the "authoritive" resolver for that domain, in this case dns.lit.int (10.10.30.3)
  • etc

Hope this helps?

Where are you telling Pi-hole that either openwrt.lan should resolve to a local IP address or that Pi-hole needs to talk to another resolver (besides the 1.1.1.1 and 1.0.0.1 upstreams) for the IP address.

I don't see anywhere in your configuration that you have server=/lan/ or server=/openwrt.lan.

1 Like

You are absolutely right - this is embarrasing :sweat_smile:
I naturally assumed pihole knows how to resolve .lan, as he is in the same domain - but how could he?
Thanks for pointing that out! :slight_smile:

I can indeed confirm, that pihole takes the servers into consideration:

root@pihole:/home/steffen# dig +short chaos txt servers.bind @127.0.0.1
"10.10.20.1#53 7 0" "10.10.60.1#53 0 0" "10.1.1.1#53 0 0" "10.10.40.1#53 0 0" "10.10.30.3#53 0 0" "10.10.10.3#53 0 0" "1.0.0.1#53 9 0" "1.1.1.1#53 151 5"
root@pihole:/home/steffen#
1 Like

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.