Unbound + Pihole - Custom DNS Issue

Hi guys, i’m trying to run the custom DNS via unbound on Pihole, but the local dns returns SERVFAIL → 127.0.0.1:5335

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

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

;; Query time: 80 msec
;; SERVER: 127.0.0.1#5335(127.0.0.1)
;; WHEN: Thu Feb 03 19:34:20 CET 2022
;; MSG SIZE  rcvd: 55

The unbound.service is running without errors and I switched the custom DNS on the Pihole Panel

I also followed the page on github (https://github.com/MichaIng/DietPi/issues/2409) where someone from the Dietpi community posted a similar issue, but I didn’t found any solution to my problem.

This is my config

   server:
        # Do not daemonize, to allow proper systemd service control and status estimation.
        do-daemonize: no

        # A single thread is pretty sufficient for home or small office instances.
        num-threads: 1

        # Logging: For the sake of privacy and performance, keep logging at a minimum!
        # - Verbosity 2 and up practically contains query and reply logs.
        verbosity: 0
        log-queries: no
        log-replies: no
        # - If required, uncomment to log to a file, else logs are available via "journalctl -u unbound".
        #logfile: "/var/log/unbound.log"

        # Set interface to "0.0.0.0" to make Unbound listen on all network interfaces.
        # Set it to "127.0.0.1" to listen on requests from the same machine only, useful in combination with Pi-hole.
        interface: 127.0.0.1
        # Default DNS port is "53". When used with Pi-hole, set this to e.g. "5335", since "5353" is used by mDNS already.
        port: 5335

        # Control IP ranges which should be able to use this Unbound instance.
        # The DietPi defaults permit access from official local network IP ranges only, hence requests from www are denied.
        access-control: 0.0.0.0/0 refuse
        access-control: 10.0.0.0/8 allow
        access-control: 127.0.0.1/8 allow
        access-control: 172.16.0.0/12 allow
        access-control: 192.168.0.0/16 allow
        access-control: ::/0 refuse
        access-control: ::1/128 allow
        access-control: fd00::/8 allow
        access-control: fe80::/10 allow

        # Private IP ranges, which shall never be returned or forwarded as public DNS response.
        # NB: 127.0.0.1/8 is sometimes used by adblock lists, hence DietPi by default allows those as response.
        private-address: 10.0.0.0/8
        private-address: 172.16.0.0/12
        private-address: 192.168.0.0/16
        private-address: 169.254.0.0/16
        private-address: fd00::/8
        private-address: fe80::/10

   # Define protocols for connections to and from Unbound.
        # NB: Disabling IPv6 does not disable IPv6 IP resolving, which depends on the clients request.
        do-udp: yes
        do-tcp: yes
        do-ip4: yes
        do-ip6: yes
        prefer-ip6: no

        # DNS root server information file. Updated monthly via cron job: /etc/cron.monthly/dietpi-unbound
        root-hints: "/var/lib/unbound/root.hints"

        # Maximum number of queries per second
        ratelimit: 1000

        # Defend against and print warning when reaching unwanted reply limit.
        unwanted-reply-threshold: 10000

        # Set EDNS reassembly buffer size to match new upstream default, as of DNS Flag Day 2020 recommendation.
        edns-buffer-size: 1232

        # Increase incoming and outgoing query buffer size to cover traffic peaks.
        so-rcvbuf: 4m
        so-sndbuf: 4m

        # Hardening
        harden-glue: yes
        harden-dnssec-stripped: yes
        harden-algo-downgrade: yes
        harden-large-queries: yes
        harden-short-bufsize: yes

        # Privacy
        use-caps-for-id: no # Spoof protection by randomising capitalisation
        rrset-roundrobin: yes
        qname-minimisation: yes
        minimal-responses: yes
        hide-identity: yes
        identity: "Server" # Purposefully a dummy identity name
        hide-version: yes

        # Caching
        cache-min-ttl: 300
        cache-max-ttl: 86400
        serve-expired: yes
        neg-cache-size: 4M
        prefetch: yes
        prefetch-key: yes
        msg-cache-size: 50m

Any suggestion?
Thanks

Sorry guys, this thread was for Troubleshooting :frowning:

let’s try to perform some tcpdump to see what happen

dietpi-software install 15
tcpdump -i any -c500 -nn port 53 or port 5335

this will capture 500 lines and terminate themselves or until you cancel it manually

once tcpdump is running, do the DNS resolution on a 2nd SSH session

dig @127.0.0.1 google.com

This will ask the PiHole > Unbound > Upstream

Hi there, thanks for the reply.
Here the response:

20:33:52.316789 eth0  In  IP 192.168.1.102.51258 > 192.168.1.6.53: 40914+ AAAA? www.google.com. (32)
20:33:52.316890 eth0  In  IP 192.168.1.102.58355 > 192.168.1.6.53: 55495+ A? www.google.com. (32)
20:33:52.316930 eth0  In  IP 192.168.1.102.42120 > 192.168.1.6.53: 21394+ AAAA? www.google.com. (32)
20:33:52.316961 eth0  In  IP 192.168.1.102.40432 > 192.168.1.6.53: 35417+ A? www.google.com. (32)
20:33:52.318083 lo    In  IP 127.0.0.1.38154 > 127.0.0.1.5335: UDP, length 43
20:33:52.319406 eth0  Out IP 192.168.1.6.15694 > 198.41.0.4.53: 29765% [1au] NS? . (28)
20:33:52.320778 eth0  In  IP 198.41.0.4.53 > 192.168.1.6.15694: 29765 ServFail 0/0/0 (17)
20:33:52.321733 lo    In  IP 127.0.0.1.54277 > 127.0.0.1.5335: UDP, length 43
20:33:52.324460 eth0  Out IP 192.168.1.6.61836 > 192.112.36.4.53: 4485% [1au] NS? . (28)
20:33:52.325778 eth0  In  IP 192.112.36.4.53 > 192.168.1.6.61836: 4485 ServFail 0/0/0 (17)
20:33:52.327493 eth0  Out IP 192.168.1.6.57672 > 192.36.148.17.53: 31584% [1au] NS? . (28)
20:33:52.328651 eth0  In  IP 192.36.148.17.53 > 192.168.1.6.57672: 31584 ServFail 0/0/0 (17)
20:33:52.332712 eth0  Out IP 192.168.1.6.40352 > 198.97.190.53.53: 41105% [1au] NS? . (28)
20:33:52.333908 eth0  In  IP 198.97.190.53.53 > 192.168.1.6.40352: 41105 ServFail 0/0/0 (17)
20:33:52.335484 eth0  Out IP 192.168.1.6.24582 > 199.9.14.201.53: 51718% [1au] NS? . (28)
20:33:52.336736 eth0  In  IP 199.9.14.201.53 > 192.168.1.6.24582: 51718 ServFail 0/0/0 (17)
20:33:52.338832 eth0  Out IP 192.168.1.6.21301 > 192.5.5.241.53: 63959% [1au] NS? . (28)
20:33:52.340003 eth0  In  IP 192.5.5.241.53 > 192.168.1.6.21301: 63959 ServFail 0/0/0 (17)
20:33:52.342682 eth0  Out IP 192.168.1.6.36733 > 193.0.14.129.53: 6254% [1au] NS? . (28)
20:33:52.343871 eth0  In  IP 193.0.14.129.53 > 192.168.1.6.36733: 6254 ServFail 0/0/0 (17)
20:33:52.345542 eth0  Out IP 192.168.1.6.27816 > 192.112.36.4.53: 9322% [1au] NS? . (28)
20:33:52.346629 eth0  In  IP 192.112.36.4.53 > 192.168.1.6.27816: 9322 ServFail 0/0/0 (17)
20:33:52.347607 eth0  Out IP 192.168.1.6.42794 > 192.112.36.4.53: 8651% [1au] NS? . (28)
20:33:52.348782 eth0  In  IP 192.112.36.4.53 > 192.168.1.6.42794: 8651 ServFail 0/0/0 (17)
20:33:52.349772 eth0  Out IP 192.168.1.6.26907 > 202.12.27.33.53: 63414% [1au] NS? . (28)
20:33:52.350943 eth0  In  IP 202.12.27.33.53 > 192.168.1.6.26907: 63414 ServFail 0/0/0 (17)
20:33:52.351937 eth0  Out IP 192.168.1.6.17384 > 202.12.27.33.53: 15151% [1au] NS? . (28)
20:33:52.353110 eth0  In  IP 202.12.27.33.53 > 192.168.1.6.17384: 15151 ServFail 0/0/0 (17)
20:33:52.357807 eth0  Out IP 192.168.1.6.53829 > 193.0.14.129.53: 49685% [1au] NS? . (28)
20:33:52.358996 eth0  In  IP 193.0.14.129.53 > 192.168.1.6.53829: 49685 ServFail 0/0/0 (17)
20:33:52.360830 eth0  Out IP 192.168.1.6.56960 > 192.5.5.241.53: 6266% [1au] NS? . (28)
20:33:52.362042 eth0  In  IP 192.5.5.241.53 > 192.168.1.6.56960: 6266 ServFail 0/0/0 (17)
20:33:52.363615 eth0  Out IP 192.168.1.6.51247 > 199.7.91.13.53: 63564% [1au] NS? . (28)
20:33:52.364787 eth0  In  IP 199.7.91.13.53 > 192.168.1.6.51247: 63564 ServFail 0/0/0 (17)
20:33:52.365776 eth0  Out IP 192.168.1.6.15199 > 202.12.27.33.53: 15012% [1au] NS? . (28)
20:33:52.367016 eth0  In  IP 202.12.27.33.53 > 192.168.1.6.15199: 15012 ServFail 0/0/0 (17)
20:33:52.368010 eth0  Out IP 192.168.1.6.61924 > 198.97.190.53.53: 57510% [1au] NS? . (28)
20:33:52.369132 eth0  In  IP 198.97.190.53.53 > 192.168.1.6.61924: 57510 ServFail 0/0/0 (17)
20:33:52.370123 eth0  Out IP 192.168.1.6.61584 > 202.12.27.33.53: 25517% [1au] NS? . (28)
20:33:52.371498 eth0  In  IP 202.12.27.33.53 > 192.168.1.6.61584: 25517 ServFail 0/0/0 (17)
20:33:52.373581 eth0  Out IP 192.168.1.6.38881 > 199.7.91.13.53: 51194% [1au] NS? . (28)
20:33:52.374808 eth0  In  IP 199.7.91.13.53 > 192.168.1.6.38881: 51194 ServFail 0/0/0 (17)
20:33:52.377037 eth0  Out IP 192.168.1.6.16632 > 199.9.14.201.53: 64174% [1au] NS? . (28)
20:33:52.378268 eth0  In  IP 199.9.14.201.53 > 192.168.1.6.16632: 64174 ServFail 0/0/0 (17)
20:33:52.379247 eth0  Out IP 192.168.1.6.41506 > 192.5.5.241.53: 17756% [1au] NS? . (28)
20:33:52.380810 eth0  In  IP 192.5.5.241.53 > 192.168.1.6.41506: 17756 ServFail 0/0/0 (17)
20:33:52.394438 eth0  Out IP 192.168.1.6.60196 > 199.7.83.42.53: 15604% [1au] NS? . (28)
20:33:52.395779 eth0  In  IP 199.7.83.42.53 > 192.168.1.6.60196: 15604 ServFail 0/0/0 (17)
20:33:52.397563 eth0  Out IP 192.168.1.6.49819 > 198.97.190.53.53: 31070% [1au] NS? . (28)
20:33:52.398771 eth0  In  IP 198.97.190.53.53 > 192.168.1.6.49819: 31070 ServFail 0/0/0 (17)
20:33:52.399832 eth0  Out IP 192.168.1.6.49917 > 192.33.4.12.53: 56858% [1au] NS? . (28)
20:33:52.401007 eth0  In  IP 192.33.4.12.53 > 192.168.1.6.49917: 56858 ServFail 0/0/0 (17)
20:33:52.402812 eth0  Out IP 192.168.1.6.48976 > 198.97.190.53.53: 31924% [1au] NS? . (28)
20:33:52.404136 eth0  In  IP 198.97.190.53.53 > 192.168.1.6.48976: 31924 ServFail 0/0/0 (17)
20:33:52.409368 eth0  Out IP 192.168.1.6.34898 > 192.203.230.10.53: 23876% [1au] NS? . (28)
20:33:52.410545 eth0  In  IP 192.203.230.10.53 > 192.168.1.6.34898: 23876 ServFail 0/0/0 (17)
20:33:52.415159 eth0  Out IP 192.168.1.6.8721 > 193.0.14.129.53: 38701% [1au] NS? . (28)
20:33:52.416643 eth0  In  IP 193.0.14.129.53 > 192.168.1.6.8721: 38701 ServFail 0/0/0 (17)
20:33:52.420173 eth0  Out IP 192.168.1.6.10849 > 192.112.36.4.53: 47933% [1au] NS? . (28)
20:33:52.421491 eth0  In  IP 192.112.36.4.53 > 192.168.1.6.10849: 47933 ServFail 0/0/0 (17)
20:33:52.424412 eth0  Out IP 192.168.1.6.45579 > 192.5.5.241.53: 13702% [1au] NS? . (28)
20:33:52.425761 eth0  In  IP 192.5.5.241.53 > 192.168.1.6.45579: 13702 ServFail 0/0/0 (17)
20:33:52.431494 eth0  Out IP 192.168.1.6.7918 > 199.9.14.201.53: 41082% [1au] NS? . (28)
20:33:52.432779 eth0  In  IP 199.9.14.201.53 > 192.168.1.6.7918: 41082 ServFail 0/0/0 (17)
20:33:52.437861 eth0  Out IP 192.168.1.6.36177 > 199.7.83.42.53: 22650% [1au] NS? . (28)
20:33:52.439144 eth0  In  IP 199.7.83.42.53 > 192.168.1.6.36177: 22650 ServFail 0/0/0 (17)
20:33:52.448956 eth0  Out IP 192.168.1.6.55849 > 198.41.0.4.53: 21261% [1au] NS? . (28)
20:33:52.450156 eth0  In  IP 198.41.0.4.53 > 192.168.1.6.55849: 21261 ServFail 0/0/0 (17)
20:33:52.453482 eth0  Out IP 192.168.1.6.59289 > 193.0.14.129.53: 41329% [1au] NS? . (28)
20:33:52.454664 eth0  In  IP 193.0.14.129.53 > 192.168.1.6.59289: 41329 ServFail 0/0/0 (17)
20:33:52.455641 eth0  Out IP 192.168.1.6.7892 > 198.41.0.4.53: 5786% [1au] NS? . (28)
20:33:52.456714 eth0  In  IP 198.41.0.4.53 > 192.168.1.6.7892: 5786 ServFail 0/0/0 (17)
20:33:52.457329 lo    In  IP 127.0.0.1.5335 > 127.0.0.1.54277: UDP, length 43
20:33:52.457780 lo    In  IP 127.0.0.1.54277 > 127.0.0.1.5335: UDP, length 43
20:33:52.458589 lo    In  IP 127.0.0.1.5335 > 127.0.0.1.38154: UDP, length 43
20:33:52.459012 lo    In  IP 127.0.0.1.38154 > 127.0.0.1.5335: UDP, length 43

192.168.1.6 is my local static IP address for DietPI (and Pihole)

hmm there is an issue of Unbound to check with upstream DNS

20:33:52.431494 eth0  Out IP 192.168.1.6.7918 > 199.9.14.201.53: 41082% [1au] NS? . (28)
20:33:52.432779 eth0  In  IP 199.9.14.201.53 > 192.168.1.6.7918: 41082 ServFail 0/0/0 (17)

can you do the same test asking Unbound directly

dig @127.0.0.1 -p 5335 google.com

Always SERVFAIL

; <<>> DiG 9.16.22-Raspbian <<>> @127.0.0.1 -p 5335 google.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 42824
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

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

;; Query time: 80 msec
;; SERVER: 127.0.0.1#5335(127.0.0.1)
;; WHEN: Thu Feb 03 20:49:01 CET 2022
;; MSG SIZE  rcvd: 39

let’s try something else and activate DNS over TLS (DoT). You can copy following at once and copy it as is into SSH command line.

cat << '_EOF_' > /etc/unbound/unbound.conf.d/dietpi-dot.conf
# Adding DNS-over-TLS support
server:
tls-cert-bundle: /etc/ssl/certs/ca-certificates.crt
forward-zone:
name: "."
forward-tls-upstream: yes
## Cloudflare
forward-addr: 1.1.1.1@853#cloudflare-dns.com
forward-addr: 1.0.0.1@853#cloudflare-dns.com
## Quad9
forward-addr: 9.9.9.9@853#dns.quad9.net
forward-addr: 149.112.112.112@853#dns.quad9.net
_EOF_

once done restart unbound and check again

systemctl status unbound
dig @127.0.0.1 -p 5335 google.com

tcpdump would be as follow now

tcpdump -i any -c500 -nn port 53 or port 5335 or port 853

The DoT configuration was one of my next options :rofl: it worked!

; <<>> DiG 9.16.22-Raspbian <<>> @127.0.0.1 -p 5335 google.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 4522
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

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

;; ANSWER SECTION:
google.com.		300	IN	A	142.250.184.78

;; Query time: 300 msec
;; SERVER: 127.0.0.1#5335(127.0.0.1)
;; WHEN: Thu Feb 03 21:25:31 CET 2022
;; MSG SIZE  rcvd: 55

With DoT configuration the custom DNS seems to work smooth with unbound and my DNS requests are also encrypted now :smiley:
Thank you very much, I wonder why before of the DoT configuration, the custom DNS couldn’t not resolve any query.

looks like DNS communication between Unbound and Upstream DNS was not working well. Do you have any special network component like a firewall or something that could inspect DNS request?

Actually I don’t think so. The only ploblem could be my ISP (custom) router that doesn’t allow to change the DNS from the router itself: for this reason I use the Pihole like a DHCP server (shutting down the DHCP server of the ISP router). I don’t know if this kind of routing can give some problem with the DNS request who came from the Pihole. Maybe not.

Probably we wound find out. But good it is working now using DoT.

Hi guys, sorry if I re-open the thread, but I have studied a little better how unbound works.
Using DoT with unbound makes the upstream forwarded to public DNS, I’d like to use the recursive method instead.
At the moment the local DNS 127.0.0.1 on port 5335 still doesn’t resolve any address. I also ran

unbound-checkconf

to check some error in the config file but no error occured. Someone has some other hint to make recursive unbound works? Thank you.

Not sure what is causing this. For me this looks like local network or the ISP who has an influence on the DNS resolution between Unbound ans upstream DNS root server. You could test a global upstream DNS directly that failed on unbound.

from your tcpdump snap shot

20:33:52.431494 eth0  Out IP 192.168.1.6.7918 > 199.9.14.201.53: 41082% [1au] NS? . (28)
20:33:52.432779 eth0  In  IP 199.9.14.201.53 > 192.168.1.6.7918: 41082 ServFail 0/0/0 (17)

to test the DNS server 199.9.14.201 directly

dig @199.9.14.201 google.com

and to cross check using Quad9

dig @9.9.9.9 google.com

Hi Joulinar, here it is

; <<>> DiG 9.16.22-Raspbian <<>> @199.9.14.201 google.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 39218
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1220
; COOKIE: 98efcddbb544339d9a60d5f261feb1df029c8488bb221207 (good)
;; QUESTION SECTION:
;google.com.                    IN      A

;; ANSWER SECTION:
google.com.             262     IN      A       216.58.208.174

;; Query time: 10 msec
;; SERVER: 199.9.14.201#53(199.9.14.201)
;; WHEN: Sat Feb 05 18:20:33 CET 2022
;; MSG SIZE  rcvd: 83

and

; <<>> DiG 9.16.22-Raspbian <<>> @9.9.9.9 google.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 17426
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

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

;; ANSWER SECTION:
google.com.             245     IN      A       216.58.208.174

;; Query time: 0 msec
;; SERVER: 9.9.9.9#53(9.9.9.9)
;; WHEN: Sat Feb 05 18:20:49 CET 2022
;; MSG SIZE  rcvd: 55

it seems all good from there

that seems to be working. Not sure what the issue on your unbound installation is. Hmm you could try to disable dnssec for testing

G_CONFIG_INJECT 'harden-dnssec-stripped:' '        harden-dnssec-stripped: no' /etc/unbound/unbound.conf.d/dietpi.conf
systemctl restart unbound
dig @127.0.0.1 -p 5335 goggle.com
1 Like

Nope, Disabling dnssec didn’t work unfortunately.

; <<>> DiG 9.16.22-Raspbian <<>> @127.0.0.1 -p 5335 google.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 64233
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

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

;; Query time: 0 msec
;; SERVER: 127.0.0.1#5335(127.0.0.1)
;; WHEN: Sat Feb 05 19:31:09 CET 2022
;; MSG SIZE  rcvd: 39

In your opinion it could be something wrong in the root.hints?

I don’t think so. Because unbound is going to ask root DNS server nas you can see on tcpdump output. But something is wrong on communication between unbound and root DNS server. But I don’t know what. Maybe you would need to contact unbound guys directly or via their support platform to have a deeper look.

In parallel you could have a look to error log

journalctl -u unbound

Thanks for your time Joulinar!
I’ll try to contact unbound guys, even if they don’t have a forum but only a mailing list :slight_smile:

Pls keep us posted on this issue. Would be good to know what is is in your case.