unbound icon indicating copy to clipboard operation
unbound copied to clipboard

Pi-hole in Docker fails to connect to Encrypted Unbound DNS

Open akayashi-mika opened this issue 2 years ago • 2 comments

Describe the bug I want to use Pi-hole with Unbound as Local DNS. Both Pi-hole and Encrypted Unbound seems to be working fine on their own. Pi-hole can block ads when Quad9 is used as Upstream DNS, and Unbound can dig websites without fail. When I try to set Unbound as Upstream DNS Server however, I no longer am able to connect to any website.

To reproduce Steps to reproduce the behavior:

  1. Install Pi-hole in docker via sudo docker up -d pihole with this docker-compose.yml configuration
version: "3"

# More info at https://github.com/pi-hole/docker-pi-hole/ and https://docs.pi-hole.net/
services:
  pihole:
    container_name: pihole
    image: pihole/pihole:latest
    # For DHCP it is recommended to remove these ports and instead add: network_mode: "host"
    ports:
      - "127.0.0.1:53:53/tcp"
      - "127.0.0.1:53:53/udp"
      - "127.0.0.1:80:80/tcp"
    environment:
      TZ: 'America/Chicago'
      # WEBPASSWORD: 'set a secure password here or it will be random'
    # Volumes store your data between container upgrades
    # privileged: true
    volumes:
      - './etc-pihole:/etc/pihole'
      - './etc-dnsmasq.d:/etc/dnsmasq.d'    
    #   https://github.com/pi-hole/docker-pi-hole#note-on-capabilities
    cap_add:
      - NET_ADMIN # Required if you are using Pi-hole as your DHCP server, else not needed
    restart: unless-stopped
  1. Install Unbound via sudo pacman -S --needed unbound
  2. Edit /etc/unbound/unbound.conf This is my /etc/unbound/unbound.conf :
server:
    # If no logfile is specified, syslog is used
    logfile: /var/log/unbound/unbound.log
    verbosity: 0

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

	# Provide TLS on port 853
	interface: 127.0.0.1@853
	tls-port: 853

    # 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.
    # IP fragmentation is unreliable on the Internet today, and can cause
    # transmission failures when large DNS messages are sent via UDP. Even
    # when fragmentation does work, it may not be secure; it is theoretically
    # possible to spoof parts of a fragmented DNS message, without easy
    # detection at the receiving end. Recently, there was an excellent study
    # >>> Defragmenting DNS - Determining the optimal maximum UDP response size for DNS <<<
    # by Axel Koolhaas, and Tjeerd Slokker (https://indico.dns-oarc.net/event/36/contributions/776/)
    # in collaboration with NLnet Labs explored DNS using real world data from the
    # the RIPE Atlas probes and the researchers suggested different values for
    # IPv4 and IPv6 and in different scenarios. They advise that servers should
    # be configured to limit DNS messages sent over UDP to a size that will not
    # trigger fragmentation on typical network links. DNS servers can switch
    # from UDP to TCP when a DNS response is too big to fit in this limited
    # buffer size. This value has also been suggested in DNS Flag Day 2020.
    edns-buffer-size: 1232

    # 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

	do-not-query-localhost: no
	tls-system-cert: yes
	tls-cert-bundle: "/etc/ssl/cert.pem"

# control which clients are allowed to make (recursive) queries
access-control: 127.0.0.1/32 allow_snoop
access-control: ::1 allow_snoop
access-control: 127.0.0.0/8 allow
access-control: 192.168.1.0/24 allow

# Upstream Servers
forward-zone:
  name: "."
  forward-tls-upstream: yes
    forward-addr: 9.9.9.9@853#dns.quad9.net
    forward-addr: 149.112.112.112@853#dns.quad9.net
  1. Download root.hints wget https://www.internic.net/domain/named.root -qO- | sudo tee /var/lib/unbound/root.hints
  2. Enable unbound sudo systemctl enable --now unbound
  3. Test if unbound is working properly
╰─>$ dig sigfail.verteiltesysteme.net @127.0.0.1 -p 5335

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

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

;; Query time: 2766 msec
;; SERVER: 127.0.0.1#5335(127.0.0.1) (UDP)
;; WHEN: Fri Jun 17 01:24:22 +08 2022
;; MSG SIZE  rcvd: 57
╰─>$ dig sigok.verteiltesysteme.net @127.0.0.1 -p 5335

; <<>> DiG 9.18.3 <<>> sigok.verteiltesysteme.net @127.0.0.1 -p 5335
;; global options: +cmd
;; Got answer:


;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 23492
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

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

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

;; Query time: 2073 msec
;; SERVER: 127.0.0.1#5335(127.0.0.1) (UDP)
;; WHEN: Fri Jun 17 01:24:05 +08 2022
;; MSG SIZE  rcvd: 71
  1. Change your DNS servers to 127.0.0.1 in /etc/resolv.conf
╰─>$ cat /etc/resolv.conf
# Generated by resolvconf
nameserver 127.0.0.1
nameserver ::1
options trust-ad
  1. Open Pi-hole in your browser, then add 127.0.0.1#5335 as a Custom Upstream DNS Server, then save it Screenshot 2022-06-16 at 17-39-38 Pi-hole - fd54d6c0a3fa
  2. Load any website you want

Expected behavior Pi-hole will filter my network and use my Local Encrypted Unbound DNS to load webpages properly as it should. Pi-hole => Unbound => TLS Encrypted Quad9 => <website>

System:

  • Unbound version: Version 1.16.0
  • OS: Arch Linux x86_64
  • unbound -V output:
Version 1.16.0

Configure line: --prefix=/usr --sysconfdir=/etc --localstatedir=/var --sbindir=/usr/bin --disable-rpath --enable-dnscrypt --enable-dnstap --enable-pie --enable-relro-now --enable-subnet --enable-systemd --enable-tfo-client --enable-tfo-server --enable-cachedb --with-libhiredis --with-conf-file=/etc/unbound/unbound.conf --with-pidfile=/run/unbound.pid --with-rootkey-file=/etc/trusted-key.key --with-libevent --with-libnghttp2 --with-pyunbound
Linked libs: libevent 2.1.12-stable (it uses epoll), OpenSSL 1.1.1o  3 May 2022
Linked modules: dns64 cachedb subnetcache respip validator iterator
DNSCrypt feature available
TCP Fastopen feature available

BSD licensed, see LICENSE in source package for details.
Report bugs to [email protected] or https://github.com/NLnetLabs/unbound/issues

Additional information This is what neofetch gives me

╰─>$ neofetch
                   -`                    
                  .o+`                   --------- 
                 `ooo/                   OS: Arch Linux x86_64 
                `+oooo:                  Host: VivoBook_ASUSLaptop X515EA_X515EA 1.0 
               `+oooooo:                 Kernel: 5.18.3-arch1-1 
               -+oooooo+:                Uptime: 2 hours, 16 mins 
             `/:-:++oooo+:               Packages: 995 (pacman), 10 (flatpak) 
            `/++++/+++++++:              Shell: fish 3.4.1 
           `/++++++++++++++:             Resolution: 1920x1080 
          `/+++ooooooooooooo/`           WM: i3 
         ./ooosssso++osssssso+`          Theme: Adwaita [GTK2/3] 
        .oossssso-````/ossssss+`         Icons: Adwaita [GTK2/3] 
       -osssssso.      :ssssssso.        Terminal: xfce4-terminal 
      :osssssss/        osssso+++.       Terminal Font: Monospace 12 
     /ossssssss/        +ssssooo/-       CPU: 11th Gen Intel i3-1115G4 (4) @ 3.000GHz 
   `/ossssso+/:-        -:/+osssso+-     GPU: Intel Device 9a78 
  `+sso+:-`                 `.-/+oso:    Memory: 6951MiB / 11666MiB 
 `++:.                           `-/+/
 .`                                 `/                           
                                                                 

What I have tried

  • [x] Recreate the Docker Container
  • [x] Run the Docker Container with the --privileged flag enabled
  • [ ] Reinstall Unbound and removed Encryption

None of these worked for me

akayashi-mika avatar Jun 17 '22 14:06 akayashi-mika

If unbound is working fine on its own, then I do not see any problem. With unbound. I mean, you can dig at the unbound port number and it responds with the correct reply, so there is no problem on the unbound side of things. Also the configuration of unbound looks fine.

Something must be wrong on the system integration side, since you say there is something that goes wrong. You edit the resolv.conf file but the file says it is managed by the 'resolvconf' utility? Perhaps it was overwritten again. Also, that 127.0.0.1 communicates to port 53, I guess not 5335. If after configuring the unbound in the Pihole interface you want to know if queries actually arrive at unbound, or if they go elsewhere, there is the options log-queries: yes and log-replies: yes so you can see what actually arrives at the unbound level.

wcawijngaards avatar Jun 17 '22 14:06 wcawijngaards

I think problem here is that inside docker container 127.0.0.1 is not the same as on the host. You need to either set up unbound inside the container alongside pi-hole and connect to that container's address, or connect to your host's public/private ip (also make sure, that your fw isn't blocking such connections).

isbear avatar Jun 27 '22 10:06 isbear