Unbound: solution for communications error

Hi, new to the forum.
Hope all doing well. I just want to share my finding regarding communication error on Unbound.

I noticed that unbound always send UDP packet trough my router (Mikrotik), but seems there is no response from the DNS server, which is 198.41.0.4 (Verisign) and that’s weird. I don’t know why Unbound sent DNS request to that server. So, I’m looking for solution to make Unbound send request to specific ip.

Here the configuration:

  forward-zone:
    name: "."
    forward-addr: 9.9.9.9
    forward-addr: 1.1.1.3
    # forward-addr: 8.8.8.8
    # forward-addr: 1.1.1.1

Complete configuration that works for me:

server:
  # BASIC SETUP
  cache-min-ttl: 300
  cache-max-ttl: 172800
  directory: "/etc/unbound"
  edns-buffer-size: 1472
  interface: 0.0.0.0
  rrset-roundrobin: yes
  username: "_unbound"  #First "adduser _unbound"
  do-ip4: yes
  do-ip6: yes
  do-udp: yes
  do-tcp: yes
  
  # LOGGING
  log-local-actions: no
  log-queries: no
  log-replies: no
  log-servfail: yes
  use-syslog: yes
  verbosity: 0
  
  # PRIVACY
  aggressive-nsec: yes
  delay-close: 10000
  do-daemonize: no
  do-not-query-localhost: no
  neg-cache-size: 4M
  qname-minimisation: yes
  
  # SECURITY
  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
  access-control: 127.0.0.1/32 allow
  access-control: 192.168.0.0/16 allow
  access-control: 172.16.0.0/12 allow
  access-control: 10.0.0.0/8 allow
  chroot: "/etc/unbound"
  harden-algo-downgrade: yes
  harden-below-nxdomain: yes
  harden-dnssec-stripped: yes
  harden-glue: yes
  harden-large-queries: yes
  harden-referral-path: no
  harden-short-bufsize: yes
  hide-identity: yes
  hide-version: yes
  identity: "DNS"
  ratelimit: 1000
  unwanted-reply-threshold: 10000
  use-caps-for-id: yes
  val-clean-additional: yes
  
  # PERFORMANCE SETTINGS
  infra-cache-slabs: 2
  key-cache-slabs: 2
  incoming-num-tcp: 10
  msg-cache-size: 119173802
  msg-cache-slabs: 2
  num-queries-per-thread: 4096
  num-threads: 1
  outgoing-range: 8192
  rrset-cache-size: 238347605
  rrset-cache-slabs: 2
  minimal-responses: yes
  prefetch: yes
  prefetch-key: yes
  serve-expired: yes
  so-reuseport: yes
  
  # tls-cert-bundle: /etc/unbound/cert/cert.csr

  # FORWARD ZONE (the missing part)
  forward-zone:
    name: "."
    forward-addr: 10.15.100.111 #my local pi-hole -> add to groups > never block addlist
    forward-addr: 9.9.9.9
    forward-addr: 1.1.1.3
    # forward-addr: 8.8.8.8
    # forward-addr: 1.1.1.1
    
    #using tls
    #don't forget to provide the valid certificate: tls-cert-bundle
    # forward-tls-upstream: yes
    # forward-addr: 1.1.1.3@853#cloudflare-dns.com
    # forward-addr: 9.9.9.9@853#dns.quad9.net

I modified from here

Hope this help.
Thanks

Your configuration makes no sense and goes completely against the basic idea of Unbound. The purpose of Unbound is not to use a public DNS provider like Cloudflare or Quad9. The actual purpose is to query the root DNS server directly. Therefore, there is no forward-zone configuration, as Unbound automatically uses the root DNS servers.

Here is a corresponding list of root DNS servers. You will also find the IP 198.41.0.4 there. Root Servers

If you really only want to use Cloudflare or Quad9, then you don’t need Unbound and can map this directly via PiHole.

The configuration of PiHole as upstream DNS in Unbound is also questionable. Normally the sequence should look like this

Client > PiHole > Unbound > Upstream DNS

1 Like

Thanks, Joulinar…
So we now can change the “forward-addr” to specific root servers and test it which one works for us.

feel free to test, but I doubt we will create/ship an Unbound configuration with hardcode DNS server setup.

The Forward Zone

  # FORWARD ZONE (the missing part)
  forward-zone:
    name: "."
    # forward-addr: 10.15.100.111
    # forward-addr: 9.9.9.9
    # forward-addr: 1.1.1.3
    # forward-addr: 8.8.8.8
    forward-addr: 198.41.0.4@53#a.root-servers.net
    forward-addr: 170.247.170.2@53#b.root-servers.net
    forward-addr: 192.33.4.12@53#c.root-servers.net
    forward-addr: 199.7.91.13@53#d.root-servers.net
    forward-addr: 192.203.230.10@53#e.root-servers.net
    forward-addr: 192.5.5.241@53#f.root-servers.net
    forward-addr: 192.112.36.4@53#g.root-servers.net
    forward-addr: 198.97.190.53@53#h.root-servers.net
    forward-addr: 192.36.148.17@53#i.root-servers.net
    forward-addr: 192.58.128.30@53#j.root-servers.net
    forward-addr: 193.0.14.129@53#k.root-servers.net
    forward-addr: 199.7.83.42@53#l.root-servers.net
    forward-addr: 202.12.27.33@53#m.root-servers.net

    #using tls
    #don't forget to provide the valid certificate: tls-cert-bundle
    # forward-tls-upstream: yes
    # forward-addr: 198.41.0.4@853#a.root-servers.net
    # forward-addr: 170.247.170.2@853#b.root-servers.net
    # forward-addr: 192.33.4.12@853#c.root-servers.net
    # forward-addr: 199.7.91.13@853#d.root-servers.net
    # forward-addr: 192.203.230.10@853#e.root-servers.net
    # forward-addr: 192.5.5.241@853#f.root-servers.net
    # forward-addr: 192.112.36.4@853#g.root-servers.net
    # forward-addr: 198.97.190.53@853#h.root-servers.net
    # forward-addr: 192.36.148.17@853#i.root-servers.net
    # forward-addr: 192.58.128.30@853#j.root-servers.net
    # forward-addr: 193.0.14.129@853#k.root-servers.net
    # forward-addr: 199.7.83.42@853#l.root-servers.net
    # forward-addr: 202.12.27.33@853#m.root-servers.net

The result:

It’s works. Thanks.

working the same way without forward-zone configuration.

root@DietPiProd:~# dig amazon.com @127.0.0.1 -p 5335

; <<>> DiG 9.18.24-1-Debian <<>> amazon.com @127.0.0.1 -p 5335
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 5592
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1

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

;; ANSWER SECTION:
amazon.com.             30      IN      A       52.94.236.248
amazon.com.             30      IN      A       205.251.242.103
amazon.com.             30      IN      A       54.239.28.85

;; Query time: 0 msec
;; SERVER: 127.0.0.1#5335(127.0.0.1) (UDP)
;; WHEN: Tue Apr 09 20:05:00 CEST 2024
;; MSG SIZE  rcvd: 87

root@DietPiProd:~#

As well a tcpdump from my PiHole / Unbound system. You see the query client > PiHole (port 53) > Unbound (port 5335) > root DNS (216.239.36.10 port 53)

20:09:19.685056 eth0  In  IP 192.168.0.93.59024 > 192.168.0.11.53: 4+ A? google.com. (28)
20:09:19.686134 lo    In  IP 127.0.0.1.33757 > 127.0.0.1.5335: UDP, length 28
20:09:19.686335 lo    In  IP 127.0.0.1.5335 > 127.0.0.1.33757: UDP, length 44
20:09:19.686774 eth0  Out IP 192.168.0.11.33116 > 216.239.36.10.53: 13134% [1au] A? goOGle.COM. (39)

and that’s the answer root DNS (216.239.36.10 port 53) > Unbound (port 5335) > PiHole (port 53) > client

20:09:19.717506 eth0  In  IP 216.239.36.10.53 > 192.168.0.11.33116: 13134*- 1/0/1 A 142.250.186.142 (55)
20:09:19.731051 eth0  In  IP 216.239.36.10.53 > 192.168.0.11.25440: 41807*- 1/0/1 AAAA 2a00:1450:4001:82a::200e (67)
20:09:19.731212 lo    In  IP 127.0.0.1.5335 > 127.0.0.1.33290: UDP, length 56
20:09:19.731453 eth0  Out IP 192.168.0.11.53 > 192.168.0.93.59025: 5 1/0/0 AAAA 2a00:1450:4001:82a::200e (56)
1 Like

Just a word to this: That config is for using DNS-over-TLS (DoT), what you can see from the @853#cloudflare-dns.com and alike behind the forward addresses. Unbound in this case is not used as recursive DNS resolver, but as upstream DoT resolver. Hence, instead of bypassing public DNS providers for privacy against those, it encrypts DNS traffic for privacy against your LAN or ISP. We have this also documented here: DNS Servers Options - DietPi.com Docs

But using a forward zone without DoT, or without defining another local DNS resolver which provides upstream DoH, DNSCrypt or similar, does indeed not make any sense. Always keep in mind the reason/purpose why you used Unbound in the first place :wink:.

This error is so unpredictable. I read many discussion on the internet and non conclusive.

I believe this error did not come out from the Unbound itself, but rather from the machine, container and/or network surrounding the machine. As I mentioned in the first post, Unbound do sent DNS request to root server but never get the answer.

I tried it several time on different Linux installation. I’m using Proxmox on bare metal. DietPi, Debian Server, and Alpine Linux, all clean install, but non of them work. I followed the DietPi installation instruction carefully, but no avail.

But it does work when you define the DNS root servers in the forward zone? While requests are sent on same port in this case, they are not exactly the same: unbound.conf(5) — Unbound 1.19.3 documentation

  • When not defining a forward zone, Unbound acts as recursive DNS resolver, doing the “recursion” needed for iterative answers by itself, to get the final IP address. This hence can involve multiple requests. This is the common way when querying DNS root servers.
  • When defining a nameserver in the forward zone, Unbound acts as forwarder, asking the remote nameserver to do the recursion instead. This hence involves a single request only. I actually was not aware that DNS root servers even do this, when requested.

Probably something on your system/network/ISP is blocking recursive DNS requests. Probably tcpdump can be used to investigate this:

tcpdump 'port 53'