Can't get unbound working with PiHole

Expected Behaviour:

When setting up PiHole to use unbound (Upstream DNS Server: 127.0.0.1#5335) name resolution works correctly.
Environment: Raspberry Pi 2 Model B Rev 1.1
OS: Raspbian GNU/Linux 11 (bullseye)

Actual Behaviour:

Once I remove any other Upstream DNS Servers, DNS resolution stops working, when pinging a domain I get the following on a Windows 10 machine:

C:\Users\xxx>ping www.microsoft.com
Ping request could not find host www.microsoft.com. Please check the name and try again.

unbound seems to be working locally, on PiHole:

pi@pi3:~ $ dig sigok.verteiltesysteme.net @127.0.0.1 -p 5335

; <<>> DiG 9.16.15-Raspbian <<>> sigok.verteiltesysteme.net @127.0.0.1 -p 5335
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 38283
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1472
;; QUESTION SECTION:
;sigok.verteiltesysteme.net.    IN      A

;; ANSWER SECTION:
sigok.verteiltesysteme.net. 60  IN      A       134.91.78.139

;; Query time: 329 msec
;; SERVER: 127.0.0.1#5335(127.0.0.1)
;; WHEN: Fri Sep 17 09:42:00 EEST 2021
;; MSG SIZE  rcvd: 71

This has been driving me crazy for days. PiHole has been working without a problem for years now.

Debug Token:

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

You want to use nslookup or dig to analyse DNS issues.

Run from your RPi 2B hosting Pi-hole, what's the output of:

dig www.microsoft.com @127.0.0.1 -p 5335

Run from your Windows client, what is the output of:

nslookup www.microsoft.com

I forgot to add:

/etc/unbound/unbound.conf.d/pi-hole.conf:

server:
    # If no logfile is specified, syslog is used
    logfile: "/var/log/unbound/unbound.log"
    verbosity: 1

    interface: 127.0.0.1
    port: 5335
    do-ip4: yes
    do-udp: yes
    do-tcp: yes

    # May be set to yes if you have IPv6 connectivity
    do-ip6: no

    # You want to leave this to no unless you have *native* IPv6. With 6to4 and
    # Terredo tunnels your web browser should favor IPv4 for the same reasons
    prefer-ip6: no

    # Use this only when you downloaded the list of primary root servers!
    # If you use the default dns-root-data package, unbound will find it automatically
    # root-hints: "/var/lib/unbound/root.hints"

    # Trust glue only if it is within the server's authority
    harden-glue: yes

    # Require DNSSEC data for trust-anchored zones, if such data is absent, the zone becomes BOGUS
    harden-dnssec-stripped: yes

    # Don't use Capitalization randomization as it known to cause DNSSEC issues sometimes
    # see https://discourse.pi-hole.net/t/unbound-stubby-or-dnscrypt-proxy/9378 for further details
    use-caps-for-id: no

    # Reduce EDNS reassembly buffer size.
    # Suggested by the unbound man page to reduce fragmentation reassembly problems
    edns-buffer-size: 1472

    # Perform prefetching of close to expired message cache entries
    # This only applies to domains that have been frequently queried
    prefetch: yes

    # One thread should be sufficient, can be increased on beefy machines. In reality for most users running on small networks or on a single machine, it should be unnecessary to seek performance enhancement by increasing num-threads above 1.
    num-threads: 1

    # Ensure kernel buffer is large enough to not lose messages in traffic spikes
    so-rcvbuf: 1m

    # Ensure privacy of local IP ranges
    private-address: 192.168.0.0/16
    private-address: 169.254.0.0/16
    private-address: 172.16.0.0/12
    private-address: 10.0.0.0/8
    private-address: fd00::/8
    private-address: fe80::/10

unbound log:

pi@pi3:~ $ cat /var/log/unbound/unbound.log
[1631808182] unbound[19274:0] notice: init module 0: subnet
[1631808182] unbound[19274:0] notice: init module 1: validator
[1631808182] unbound[19274:0] notice: init module 2: iterator
[1631808182] unbound[19274:0] info: start of service (unbound 1.13.1).
[1631808184] unbound[19274:0] info: generate keytag query _ta-4f66. NULL IN
[1631808656] unbound[19274:0] info: generate keytag query _ta-4f66. NULL IN
[1631811236] unbound[19274:0] info: service stopped (unbound 1.13.1).
[1631811236] unbound[19274:0] info: server stats for thread 0: 6716 queries, 2191 answers from cache, 4525 recursions, 106 prefetch, 0 rejected by ip ratelimiting
[1631811236] unbound[19274:0] info: server stats for thread 0: requestlist max 138 avg 25.794 exceeded 0 jostled 0
[1631811236] unbound[19274:0] info: average recursion processing time 4.784707 sec
[1631811236] unbound[19274:0] info: histogram of recursion processing times
[1631811236] unbound[19274:0] info: [25%]=0.551603 median[50%]=2.53941 [75%]=7.26114
[1631811236] unbound[19274:0] info: lower(secs) upper(secs) recursions
[1631811236] unbound[19274:0] info:    0.000000    0.000001 3
[1631811236] unbound[19274:0] info:    0.032768    0.065536 66
[1631811236] unbound[19274:0] info:    0.065536    0.131072 184
[1631811236] unbound[19274:0] info:    0.131072    0.262144 275
[1631811236] unbound[19274:0] info:    0.262144    0.524288 575
[1631811236] unbound[19274:0] info:    0.524288    1.000000 492
[1631811236] unbound[19274:0] info:    1.000000    2.000000 493
[1631811236] unbound[19274:0] info:    2.000000    4.000000 647
[1631811236] unbound[19274:0] info:    4.000000    8.000000 808
[1631811236] unbound[19274:0] info:    8.000000   16.000000 685
[1631811236] unbound[19274:0] info:   16.000000   32.000000 294
[1631811236] unbound[19274:0] info:   32.000000   64.000000 3
[1631811256] unbound[500:0] notice: init module 0: subnet
[1631811256] unbound[500:0] notice: init module 1: validator
[1631811256] unbound[500:0] notice: init module 2: iterator
[1631811256] unbound[500:0] info: start of service (unbound 1.13.1).
[1631811264] unbound[500:0] info: generate keytag query _ta-4f66. NULL IN
[1631830820] unbound[500:0] info: generate keytag query _ta-4f66. NULL IN
[1631840980] unbound[500:0] info: generate keytag query _ta-4f66. NULL IN
[1631855205] unbound[500:0] info: generate keytag query _ta-4f66. NULL IN
pi@pi3:~ $ dig www.microsoft.com @127.0.0.1 -p 5335

; <<>> DiG 9.16.15-Raspbian <<>> www.microsoft.com @127.0.0.1 -p 5335
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 46205
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1472
;; QUESTION SECTION:
;www.microsoft.com.             IN      A

;; Query time: 4740 msec
;; SERVER: 127.0.0.1#5335(127.0.0.1)
;; WHEN: Fri Sep 17 10:01:02 EEST 2021
;; MSG SIZE  rcvd: 46
C:\Users\xxx>nslookup www.microsoft.com
Server:  pi.hole
Address:  192.168.1.3

DNS request timed out.
    timeout was 2 seconds.
DNS request timed out.
    timeout was 2 seconds.
DNS request timed out.
    timeout was 2 seconds.
DNS request timed out.
    timeout was 2 seconds.
*** Request to pi.hole timed-out
I have no trouble resolving via my `unbound` (click for details):
$ dig www.microsoft.com @127.0.1.1 -p 5335

; <<>> DiG 9.11.5-P4-5.1+deb10u5-Debian <<>> www.microsoft.com @127.0.1.1 -p 5335
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 33970
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1472
;; QUESTION SECTION:
;www.microsoft.com.             IN      A

;; ANSWER SECTION:
www.microsoft.com.      3599    IN      CNAME   www.microsoft.com-c-3.edgekey.net.
www.microsoft.com-c-3.edgekey.net. 900 IN CNAME www.microsoft.com-c-3.edgekey.net.globalredir.akadns.net.
www.microsoft.com-c-3.edgekey.net.globalredir.akadns.net. 900 IN CNAME e13678.dscb.akamaiedge.net.
e13678.dscb.akamaiedge.net. 20  IN      A       92.123.229.216

;; Query time: 652 msec
;; SERVER: 127.0.1.1#5335(127.0.1.1)
;; WHEN: Fri Sep 17 08:57:50 CEST 2021
;; MSG SIZE  rcvd: 213

Your unbound is returning a SERVFAIL:

This indicates problems when unbound is trying to contact one of the authoritative DNS servers. Unfortunately, SERVFAIL is a very generic error, giving us no details what exactly went wrong.

To name just two possible reasons, your unbound may be unable to communicate with upstream authoritative servers (e.g. because your ISP blocks or redirects DNS queries), or unbound may fail to verify the DNSSEC chain.

Is that just www.microsoft.com failing, or does this happen for other domains as well?

Thank you for the answer. I am starting to understand now...: When I said name resolution was working fine, I made a mistake as I did the test while still having other Upstream DNS Servers... And then it worked. My mistake - sorry about that. Does this new info help at all? :slight_smile:

No, it is not only microsoft.com, all the domains fail to resolve resulting in not being able to do any browsing on the network.

Also, let me mention, that in my current setup, https://www.dnsleaktest.com/ reports no leak. Does this say anything about the ISP blocking (or not) DNS queries? I would think this means that the ISP is now completely bypassed by DNS queries.

A DNS leak would occur if a VPN client would not send its DNS requests through the VPN tunnel it is supposed to use. If you are not using a client that is currently connected to a VPN, the concept of DNS leakage does not apply at all.

Let 's try to find out whether your DNS requests get redirected.

Run from a client, what's the output of:

nslookup flurry.com 80.241.218.68

And from your RPi:

dig flurry.com @80.241.218.68

EDIT:
Re-reading your post, I don't think there's redirection, as your dig sigok.verteiltesysteme.net @127.0.0.1 -p 5335 was successful.

Here we go:

From a Windows client:

C:\Users\xxx>nslookup flurry.com 80.241.218.68
Server:  dismail.de
Address:  80.241.218.68

Name:    flurry.com
Address:  0.0.0.0

From the pi:

pi@pi3:~ $ dig flurry.com @80.241.218.68

; <<>> DiG 9.16.15-Raspbian <<>> flurry.com @80.241.218.68
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 41673
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;flurry.com.                    IN      A

;; ANSWER SECTION:
flurry.com.             3600    IN      A       0.0.0.0

;; Query time: 60 msec
;; SERVER: 80.241.218.68#53(80.241.218.68)
;; WHEN: Fri Sep 17 15:28:42 EEST 2021
;; MSG SIZE  rcvd: 55

Have you checked the date/time on the Pi to be accurate? This is required for DNSSEC to authenticate. Run the date command from the Pi terminal.

What is the output of the following commands from the Pi terminal:

unbound-checkconf

journalctl -u unbound

sudo grep -v '#\|^$' -R /etc/unbound/unbound.conf*

Please see the responses below:

pi@pi3:~ $ date
Fri 17 Sep 17:51:57 EEST 2021
pi@pi3:~ $ unbound-checkconf
unbound-checkconf: no errors in /etc/unbound/unbound.conf
pi@pi3:~ $ sudo grep -v '#\|^$' -R /etc/unbound/unbound.conf*
/etc/unbound/unbound.conf:include-toplevel: "/etc/unbound/unbound.conf.d/*.conf"
/etc/unbound/unbound.conf.d/pi-hole.conf:server:
/etc/unbound/unbound.conf.d/pi-hole.conf:    logfile: "/var/log/unbound/unbound.log"
/etc/unbound/unbound.conf.d/pi-hole.conf:    verbosity: 1
/etc/unbound/unbound.conf.d/pi-hole.conf:    interface: 127.0.0.1
/etc/unbound/unbound.conf.d/pi-hole.conf:    port: 5335
/etc/unbound/unbound.conf.d/pi-hole.conf:    do-ip4: yes
/etc/unbound/unbound.conf.d/pi-hole.conf:    do-udp: yes
/etc/unbound/unbound.conf.d/pi-hole.conf:    do-tcp: yes
/etc/unbound/unbound.conf.d/pi-hole.conf:    do-ip6: no
/etc/unbound/unbound.conf.d/pi-hole.conf:    prefer-ip6: no
/etc/unbound/unbound.conf.d/pi-hole.conf:    harden-glue: yes
/etc/unbound/unbound.conf.d/pi-hole.conf:    harden-dnssec-stripped: yes
/etc/unbound/unbound.conf.d/pi-hole.conf:    use-caps-for-id: no
/etc/unbound/unbound.conf.d/pi-hole.conf:    edns-buffer-size: 1472
/etc/unbound/unbound.conf.d/pi-hole.conf:    prefetch: yes
/etc/unbound/unbound.conf.d/pi-hole.conf:    num-threads: 1
/etc/unbound/unbound.conf.d/pi-hole.conf:    so-rcvbuf: 1m
/etc/unbound/unbound.conf.d/pi-hole.conf:    private-address: 192.168.0.0/16
/etc/unbound/unbound.conf.d/pi-hole.conf:    private-address: 169.254.0.0/16
/etc/unbound/unbound.conf.d/pi-hole.conf:    private-address: 172.16.0.0/12
/etc/unbound/unbound.conf.d/pi-hole.conf:    private-address: 10.0.0.0/8
/etc/unbound/unbound.conf.d/pi-hole.conf:    private-address: fd00::/8
/etc/unbound/unbound.conf.d/pi-hole.conf:    private-address: fe80::/10
/etc/unbound/unbound.conf.d/root-auto-trust-anchor-file.conf:server:
/etc/unbound/unbound.conf.d/root-auto-trust-anchor-file.conf:    auto-trust-anchor-file: "/var/lib/unbound/root.key"
/etc/unbound/unbound.conf.d/resolvconf_resolvers.conf:forward-zone:
/etc/unbound/unbound.conf.d/resolvconf_resolvers.conf:  name: "local"
/etc/unbound/unbound.conf.d/resolvconf_resolvers.conf:  forward-addr: 192.168.1.3
/etc/unbound/unbound.conf.d/resolvconf_resolvers.conf:forward-zone:
/etc/unbound/unbound.conf.d/resolvconf_resolvers.conf:  name: "."
/etc/unbound/unbound.conf.d/resolvconf_resolvers.conf:  forward-addr: 192.168.1.3

Also, you mention DNSSEC: In PiHole I have the Use DNSSEC option disabled. Is that required to be enabled?

DNSSEC is being done by unbound. The DNSSEC option in Pi-hole is not required for unbound to do this. Enabling this option in Pi-hole adds the DNSSEC status in the query log.

ok, I see now.

What are you trying to do here? You are forwarding all queries from unbound back to Pi-hole for resolution, which creates a circular loop. Pi-hole doesn't know the answer, it forwards the query to unbound to resolve, unbound sends it back to Pi-hole.

Local domains should have already been resolved by Pi-hole prior to them being sent to unbound.

If you intend to run unbound as a recursive resolver (which is what our guide sets up), eliminate this file and restart unbound.

The first line of the file says: # Generated by resolvconf I'm afraid, I have no idea how it got there, I don't recall doing anything with resolvconf.

This is the file's content for reference:

# Generated by resolvconf

forward-zone:
        name: "local"
        forward-addr: 192.168.1.3

forward-zone:
        name: "."
        forward-addr: 192.168.1.3

I removed the file, restarted unbound, but I can't change pihole yet, as I can't interrupt the network again. I'll do it shortly and will report back. If you can think of any way to test it please let me know.

You should not need to make any Pi-hole changes.

Run the following command to test DNS resolution through unbound from the Pi terminal:

dig cnn.com @127.0.0.1 -p5335

Here is the result:

pi@pi3:~ $ dig cnn.com @127.0.0.1 -p5335

; <<>> DiG 9.16.15-Raspbian <<>> cnn.com @127.0.0.1 -p5335
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 25257
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1472
;; QUESTION SECTION:
;cnn.com.                       IN      A

;; ANSWER SECTION:
cnn.com.                60      IN      A       151.101.65.67
cnn.com.                60      IN      A       151.101.129.67
cnn.com.                60      IN      A       151.101.1.67
cnn.com.                60      IN      A       151.101.193.67

;; Query time: 340 msec
;; SERVER: 127.0.0.1#5335(127.0.0.1)
;; WHEN: Fri Sep 17 18:13:26 EEST 2021
;; MSG SIZE  rcvd: 100

Please correct me, but I think the Upstream DNS Servers option in PiHole should only have 127.0.0.1#5335 and not others. Currently, I also have a Quad 9 DNS selected, otherwise I couldn't even write these lines.
This is how it looks at the moment (so that the network is usable):

Every time you tell me to make changes and test it, I perform the following steps:

  1. make the suggested step(s)
  2. DESELECT Quad9
  3. Click Save
  4. Test if things work
  5. SELECT QUAD9
  6. Click Save
    And then I can use the network again.

Anyway, I am very much prepared to be wrong :slight_smile: :slight_smile: I want to learn.

Thanks for sticking with this issue of mine

This is true. You can remove the Quad9 and your Pi-hole should continue working now that you have fixed the unbound problem. To confirm this, delete Quad 9 server, then run the following commands. The first routes a DNS query through Pi-hole, which should then send it to unbound. The second confirms that the request was processed by Pi-hole and unbound as intended.

nslookup bloomberg.com 127.0.0.1

grep -C3 bloomberg.com /var/log/pihole.log

Yes, it seems to be working. Now I only have 127.0.0.1#5335 as an upstream DNS server and these are the results:

pi@pi3:~ $ nslookup bloomberg.com 127.0.0.1
Server:         127.0.0.1
Address:        127.0.0.1#53

Non-authoritative answer:
Name:   bloomberg.com
Address: 69.191.252.15
Name:   bloomberg.com
Address: 69.187.24.15

And the log:

pi@pi3:~ $ grep -C3 bloomberg.com /var/log/pihole.log
Sep 17 18:36:40 dnsmasq[17154]: reply coronacache.home-assistant.io is <RRSIG>
Sep 17 18:36:41 dnsmasq[17154]: query[A] data.mistat.intl.xiaomi.com from 192.168.1.134
Sep 17 18:36:41 dnsmasq[17154]: gravity blocked data.mistat.intl.xiaomi.com is 0.0.0.0
Sep 17 18:36:41 dnsmasq[17154]: query[A] bloomberg.com from 127.0.0.1
Sep 17 18:36:41 dnsmasq[17154]: forwarded bloomberg.com to 127.0.0.1
Sep 17 18:36:41 dnsmasq[17154]: reply bloomberg.com is 69.191.252.15
Sep 17 18:36:41 dnsmasq[17154]: reply bloomberg.com is 69.187.24.15
Sep 17 18:36:41 dnsmasq[17154]: query[AAAA] bloomberg.com from 127.0.0.1
Sep 17 18:36:41 dnsmasq[17154]: forwarded bloomberg.com to 127.0.0.1
Sep 17 18:36:41 dnsmasq[17154]: reply bloomberg.com is NODATA-IPv6
Sep 17 18:36:42 dnsmasq[17154]: query[A] api.ad.intl.xiaomi.com from 192.168.1.134
Sep 17 18:36:42 dnsmasq[17154]: gravity blocked api.ad.intl.xiaomi.com is 0.0.0.0

And not only these look OK, but the whole network seems to be OK, too!

Thank you very much for your time!!!! Much appreciated!

1 Like

All normal outputs. Glad this is sorted and your Pi-hole is working properly again.

1 Like