xFelix
xFelix

Pihole + unbound docker setup on Raspberry Pi

Pihole + unbound docker setup on Raspberry Pi

Pihole is DNS based Ad blocking solution. It can also be used to enhance your home network security by filtering out malicious domain and provide privacy protection by preventing unnecessary telemetry data leaking out.

I have mentioned couple times in my previous posts. As pihole project has very good documentation of installation, even with the configuration of unbound recursive DNS server, I don’t feel the need to repeat the normal straightforward installation process. However, there’s not much guide talking about the details of pihole + unbound setup in docker container. And during the migration from straight installation to docker containers, I met lot of unexpected issues and mistakes. I think it worth to share my experience and my configuration to save your time doing the troubleshooting.

Why move pihole and unbound to docker container?

Docker adds another abstraction layer on top of OS.

It increases the complexity of initial configuration, but gives you flexibility of future maintenance and migration.

Neat and clean is the main reason people like docker. No need to install hundreds of library and packages into Operation System which may mess up.

Each service is a container. Configuration can be managed by file and docker-compose.yaml. Very quick to replicate the configuration to different devices.

And by using Raspberry pi, considering the SD card may wear after constant write, to backup the docker container configuration is the easiest way to recovery the configuration.

How?

So how to setup pihole and unbound into docker container on Raspberry pi?

Prerequisite

You need a Raspberry Pi and with OS (Raspbian) installed.

Raspbian has already configured with SSH access and static IP address / DNS resolver.

Raspbian installed docker packages including docker-compose. (search google or docker website if you don’t know how to)

File and Structure

Assume you have logged in Raspbian with user ‘pi‘, your home directory will be /home/pi/ .

Create below folders and files with the right path with mkdir command.

mkdir /home/pi/pihole

mkdir /home/pi/pihole/etc-dnsmasq.d

mkdir /home/pi/pihole/etc-pihole

mkdir /home/pi/unbound

mkdir /home/pi/unbound/conf.d

mkdir /home/pi/unbound/log.d

mkdir /home/pi/unbound/zones.d

mkdir /home/pi/unbound/iana.d

Pihole and Docker Compose setup

This is the key part of this guide.

Create docker-compose.yml in your favourite directory with the content below.


version: '2.4'

networks:
  dns_net:
    driver: bridge
    ipam:
        config:
        - subnet: 172.20.0.0/16

services:
  pihole:
    container_name: pihole
    hostname: pihole
    image: pihole/pihole:latest
    networks:
      dns_net:
        ipv4_address: 172.20.0.6
    ports:
      - "53:53/tcp"
      - "53:53/udp"
      - "80:80/tcp"
      - "443:443/tcp"
    environment:
      - TZ=Australia/Sydney
      - WEBPASSWORD=<yourpassword>
      - PIHOLE_DNS_=172.20.0.7#5335
      - CUSTOM_CACHE_SIZE=0
    volumes:
      - '/home/pi/pihole/etc-pihole/:/etc/pihole/'
      - '/home/pi/pihole/etc-dnsmasq.d/:/etc/dnsmasq.d/'
    restart: unless-stopped
  unbound:
    container_name: unbound
    image: madnuttah/unbound:latest
    hostname: unbound
    networks:
      dns_net:
        ipv4_address: 172.20.0.7
    environment:
      - TZ=Australia/Sydney
      - ServerIP=172.20.0.7
      - UNBOUND_UID=1000 #Example only, check your docker user info
      - UNBOUND_GID=1000 
    volumes:
      - /home/pi/unbound/unbound.conf:/usr/local/unbound/unbound.conf:rw
      - /home/pi/unbound/conf.d/:/usr/local/unbound/conf.d/:rw
      - /home/pi/unbound/log.d/unbound.log:/usr/local/unbound/log.d/unbound.log:rw
      - /home/pi/unbound/zones.d/:/usr/local/unbound/zones.d/:rw
      - /home/pi/unbound/iana.d/:/usr/local/unbound/iana.d/:rw
    ports:
      - "5335:5335/tcp"
      - "5335:5335/udp"
    healthcheck:
      disable: true
    restart: unless-stopped

Initial configures

For the unbound instance, you will probably need to create initial config files to allow it start up.

You can follow the Madnuttah unbound Github examples to create those config files. Please make sure the path to each files are aligned exactly same with docker-compose file volumes mapping path.

Unbound configurations

–  I list all my working configurations here in case you have issues with the initial configurations . Bold configuration files are mandatory, others are optional.

/home/pi/unbound/unbound.conf

include: "/usr/local/unbound/conf.d/*.conf"
include: "/usr/local/unbound/zones.d/*.conf"

server:
  module-config: "validator iterator"
  username: ""
  directory: "/usr/local/unbound"
  chroot: ""
  do-daemonize: no
  tls-cert-bundle: /etc/ssl/certs/ca-certificates.crt

/home/pi/unbound/conf.d/access-control.conf

server:
  access-control: 127.0.0.0/8 allow
  access-control: 192.168.0.0/16 allow
  access-control: 172.16.0.0/12 allow

/home/pi/unbound/conf.d/interfaces.conf

server:
  #interface: 127.0.0.1@5335
  #interface: ::1@5335
  interface: 0.0.0.0@5335
  #interface: ::0@5335

  #outgoing-interface: 0.0.0.0

  so-reuseport: yes

  do-ip4: yes
  do-ip6: no
  do-tcp: yes
  do-udp: yes
  udp-connect: yes

  prefer-ip4: yes
  prefer-ip6: no

/home/pi/unbound/conf.d/logging.conf

server:
  use-syslog: no
  log-time-ascii: yes
  logfile: "/usr/local/unbound/log.d/unbound.log"
  log-local-actions: no
  log-queries: no
  log-replies: no
  log-servfail: yes
  val-log-level: 2
  verbosity: 1

/home/pi/unbound/conf.d/performance.conf            – Note: This is just an example of my device hardware, Pls adjust based on your spec. 

server:
  num-threads: 4
  num-queries-per-thread: 4096
  cache-max-ttl: 86400
  cache-min-ttl: 300
  edns-buffer-size: 1232
  rrset-roundrobin: yes
  neg-cache-size: 4M
  delay-close: 10000
  rrset-cache-size: 256m
  rrset-cache-slabs: 4
  ratelimit: 1000
  unwanted-reply-threshold: 10000
  infra-cache-slabs: 4
  infra-cache-numhosts: 100000
  msg-cache-size: 256m
  msg-cache-slabs: 4
  key-cache-size: 4m
  key-cache-slabs: 4
  prefetch: yes
  prefetch-key: yes
  serve-expired: yes
  max-udp-size: 4096
  msg-buffer-size: 65552
  stream-wait-size: 4m
  outgoing-range: 32768
  outgoing-port-permit: 32768

/home/pi/unbound/conf.d/remote-control.conf

remote-control:
  control-enable: yes
  control-use-cert: no

/home/pi/unbound/conf.d/security.conf

server:
  do-not-query-localhost: no

  # unblock-lan-zones: no
  # insecure-lan-zones: yes

  # private-domain: "yourdomain.lan."
  # private-domain: "0.168.192.in-addr.arpa."

  # domain-insecure: "yourdomain.lan."
  # domain-insecure: "0.168.192.in-addr.arpa."
  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
  private-address: ::ffff:0:0/96

  hide-identity: yes
  identity: "server"
  hide-version: yes
  version: "" 
  aggressive-nsec: yes
  qname-minimisation: yes
  qname-minimisation-strict: no
  disable-dnssec-lame-check: no
  hide-trustanchor: yes
  harden-algo-downgrade: yes
  harden-below-nxdomain: yes
  harden-dnssec-stripped: yes
  harden-glue: yes
  harden-large-queries: yes
  harden-referral-path: yes
  harden-short-bufsize: yes
  minimal-responses: yes
  deny-any: yes
  use-caps-for-id: yes
  val-clean-additional: yes
  val-max-restart: 5
  root-key-sentinel: yes
  zonemd-permissive-mode: no

/home/pi/unbound/conf.d/trust-anchor.conf

server:
  auto-trust-anchor-file: "/usr/local/unbound/iana.d/root.key"
  trust-anchor-signaling: yes

/home/pi/unbound/zones.d/auth-zone.conf 

auth-zone:
  name: "."
  primary: 199.9.14.201 # b.root-servers.net
  primary: 192.33.4.12 # c.root-servers.net
  primary: 199.7.91.13 # d.root-servers.net
  primary: 192.5.5.241 # f.root-servers.net
  primary: 192.112.36.4 # g.root-servers.net
  primary: 193.0.14.129 # k.root-servers.net
  primary: 192.0.47.132 # iad.xfr.dns.icann.org
  primary: 192.0.32.132 # lax.xfr.dns.icann.org
  primary: 2001:500:200::b # b.root-servers.net
  primary: 2001:500:2::c # c.root-servers.net
  primary: 2001:500:2d::d # d.root-servers.net
  primary: 2001:500:2f::f # f.root-servers.net
  primary: 2001:500:12::d0d # g.root-servers.net
  primary: 2001:7fd::1 # k.root-servers.net
  primary: 2620:0:2830:202::132 # iad.xfr.dns.icann.org
  primary: 2620:0:2d0:202::132 # lax.xfr.dns.icann.org
  #url: "https://www.internic.net/domain/root.zone"
  fallback-enabled: yes
  for-downstream: no
  for-upstream: yes
  zonemd-check: yes
  zonemd-reject-absence: no
  zonefile: "/usr/local/unbound/iana.d/root.zone"

/home/pi/unbound/iana.d/root.zone 

Download it from https://www.internic.net/domain/root.zone

You can use wget https://www.internic.net/domain/root.zone to get into /home/pi/unbound/iana.d/

File Permissions

Need to execute sudo chown -R root:1000 /home/pi/unbound/ to make sure the unbound container have the permission to read/write to mapped volume.

Start the services

Let’s start unbound container first

sudo docker-compose up -d unbound

If everything goes right, you will see something says pi_dns_net has been created a new container is up.

You can now test if unbound is working as expected

dig www.google.com @172.20.0.7 -p 5335

dig www.google.com @127.0.0.1 -p 5335

If all return normal results then unbound is up running. Make sure your system iptables allow those 5335 ports.

Then start pihole container.

sudo docker-compose up -d pihole

You can test if pihole is working

dig www.google.com @172.20.0.6 -p 53

dig www.google.com @127.0.0.1 -p 53

You can also try to access http://your-Raspberry-pi-ip/admin/index.php to configure pihole blocklist and etc.

Override container configuration

If there’s any configuration you need to change, you can first add environment into docker-compose file if the image support.

Otherwise, you can touch the configuration file directly.

For example, if you want to reduce the pihole cache size from 10000 to 0, let unbound do the caching. You can modify /home/pi/pihole/etc-dnsmasq.d/01-pihole.conf to set cache-size=0 . Save the file then restart dnsmasq service from pihole admin portal.

If you want to add a custom configuration file for pihole or unbound, just add *.conf file under the mapped volume.

Then restart the container.

sudo docker stop <container name>

sudo docker-compose up -d <container name>

It will usually recreate the container if there’s any configuration change.

Commands to troubleshoot

sudo docker ps

sudo docker inspect <container name, such as pihole or unbound>

sudo docker logs pihole

Maintenance and Update

sudo docker pull pihole/pihole:latest

sudo docker pull mvance/unbound-rpi:latest

sudo docker stop pihole

sudo docker stop unbound

sudo docker rm pihole

sudo docker rm unbound

sudo docker-compose up -d unbound

sudo docker-compose up -d pihole

End

Hope this post help you and save your time. Please leave comment if you have any question.

 

Updated on April 3rd 2023. Changed unbound docker image to madnuttah/unbound. Updated on April 29th 2023 to include example unbound configurations.

Leave a Reply

textsms
account_circle
email

  • Liju

    Super useful. Thanks!

    4 years ago Reply
  • kevin

    There is an error in your docker-compose file.
    networks:
    dns_net:
    driver: bridge
    ipam:
    config:
    – subnet: 172.20.0.0/16

    driver: and ipam: should both be at the same level

    4 years ago Reply
  • Jack

    I am getting a warning that rcvbuf was not granted 306448 , what is this and what do I need to do to grant it.

    4 years ago Reply
    • FelixOwner

      @Jack: Which step you get this message?

      4 years ago Reply
      • Jack

        @Felix: I completed your tutorial. But when I check unbounds logs. It gives me that warning. I dont know of this is a bad thing?

        4 years ago Reply
        • Jack

          @Jack: Also dnssec is sometimes not validating signatures. How come? Harden dnssec stripped is on yes.

          Also how do I setup unbound dns over https? I read thats a feature now.

          4 years ago Reply
          • Jack

            @Jack: Sorry I mean doh

            4 years ago
          • Jack

            @Jack: Lol again sorry not doh but dot, u can delete that other comment

            4 years ago
  • ch33baguy

    Thank you for your work!
    Really appreciate what you have done here.

    3 years ago Reply
  • Tno

    Hi,

    Just for your information, you should also add this line to the unbound config to prevent warnings from the containers integrated health check:

    healthcheck:
    test: [“CMD”, “drill”, “@127.0.0.1”, “-p 5053”, “cloudflare.com”]

    Reason:
    There is a healthcheck entry in the docker file which goes to the default port :53 and causes a waring message in the log:

    HEALTHCHECK –interval=5s –timeout=3s –start-period=5s CMD drill @127.0.0.1 cloudflare.com || exit 1

    By the way, there are also some log entries during the start of the container (tested with unbound-rpi version 1.13.0):

    unbound[1:0] warning: so-rcvbuf 1048576 was not granted. Got 360448. To fix: start with root permissions(linux) or sysctl bigger net.core.rmem_max(linux) or kern.ipc.maxsockbuf(bsd) values.

    and there are also some udp connect failures to the IPv6 addresses of some root servers.

    error: udp connect failed: Cannot assign requested address for 2001:503:c27::2:30 port 53
    error: udp connect failed: Cannot assign requested address for 2001:500:12::d0d port 53
    error: udp connect failed: Cannot assign requested address for 2001:503:c27::2:30 port 53


    But these errors do not cause any issues (and I have also disabled IPv6 support within docker, that’s why this could not work). I would expect that unbound would not try to use IPv6 if settings in unbound.conf are set to not using IPv6 – anyway, no issue at all.

    Cheers,
    Tino

    3 years ago Reply
  • pancho-villa

    Hello, and thank you for this! It’s working great here! I was wondering about the root.hints file tho. Shouldn’t you change the unbound.conf to point at it in your docker volume location, it would look like this in unbound.conf:

    root-hints: “/opt/unbound/etc/unbound/root.hints”

    Otherwise when you download it into /home/pi/unbound/ it will default to the /var/lib/unbound/ location. Right? Or am I off base? Also, you have to update that file about every 6 months to update the root servers.

    Thanks again!

    3 years ago Reply
    • FelixOwner

      @pancho-villa: Hi pancho-villa, the root-hints path has been quoted out of this config file. And since you download it manually to the mapped unbound docker folder, unbound will automatically find and load it. No need to specify the actual path.

      3 years ago Reply
      • Atrocia6

        @Felix: Are you sure this is right? According to the unbound.conf(5) man page, “Default is nothing, using builtin hints for the IN class.” And according to Matthew Vance, the developer of the unbound docker image, you do need to include a root-hints: line pointing unbound to the downloaded root-hints, even when you’re putting it in the same directory as the config file: https://github.com/MatthewVance/unbound-docker/issues/21

        3 years ago Reply
  • Mike

    If you enable DHCP piHole fails withe the following error

    DNSMASQ_CONFIG FTL failed to start due to process is missing required capability NET_ADMIN

    3 years ago Reply
    • Mark

      @Mike: Clearly DHCP will never work with build as port 67 is not in the port list. I would suggest it has never been tested

      3 years ago Reply
  • The Dogfather

    Excellent. Thank you!

    3 years ago Reply
  • AppieHappie

    Thanks! I struggled a bit with the “root.hints” line in the supplied unbound.conf. Indeed, the container restarts endlessly. That can be fixed by surrounding the line in normal double quotes… Then the supplied path is not even necessary. My line: root-hints: “root.hints”

    3 years ago Reply
  • abielo

    Great guide. Thank you! The note on the a-record helped me deal with other missing record files which the default unbound.conf was using (I used the default configuration in my setup).

    3 years ago Reply
  • Alex.

    Thank you for this tutorial.
    In my opinion this line “dig http://www.google.com @172.20.0.7 -p 5053″ should be “dig http://www.google.com @172.20.0.7 -p 53″
    The Port number is wrong.

    2 years ago Reply
    • FelixOwner

      @Alex.: No, the intent is to test whether unbound service is running properly. Unbound is listening on port 5053.

      2 years ago Reply
  • gaayab

    I followed the instructions and updated .yml and .config file to suit my network. the unbound instance starts without any error but I cannot dig any websites. Can;t find any logs either.

    2 years ago Reply
  • waveformer

    fantastic guide, but with that configuration I’m not able to update Gravity ->

    2 years ago Reply
  • Broomwalker

    I was also unable to update gravity & get:
    [✗] DNS resolution is currently unavailable*
    [✗] DNS resolution is not available*

    1 year ago Reply
    • FelixOwner

      @Broomwalker: Make sure your unbound instance is up and working.
      I may need to update the guide of unbound docket instance a bit.

      1 year ago Reply
      • Broomwalker

        @Felix: Yeah, I don’t know how to trouble shoot the problem. I’ve followed the guide and it just doesn’t work. It possibly is Unbound that isn’t working – your “ dig http://www.google.com @172.22.0.7 -p 5335” doesn’t work:

        “dig http://www.google.com @172.22.0.7 -p 5335

        ; <> DiG 9.16.37-Debian <> http://www.google.com @172.22.0.7 -p 5335
        ;; global options: +cmd
        ;; connection timed out; no servers could be reached”

        The only items that I swapped out are the IP addresses to get a dedicated subnet (172.22.0.X) for Pi-hole/Unbound. I created the files from in the right folders as mentioned. Otherwise, generally a copy/paste.

        It’s a shame – I feel like your article is probably the only succinct page on the internet for this issue. Bit of a rabbit hole this topic!

        1 year ago Reply
  • Esteban

    “unbund” won’t start, error …

    Starting unbound … error

    ERROR: for unbound Cannot start service unbound: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: error mounting “/home/pi/unbound/unbound.conf” to rootfs at “/usr/local/unbound/unbound.conf”: mount /home/pi/unbound/unbound.conf:/usr/local/unbound/unbound.conf (via /proc/self/fd/6), flags: 0x5000: not a directory: unknown: Are you trying to mount a directory onto a file (or vice-versa)? Check if the specified host path exists and is the expected type

    ERROR: for unbound Cannot start service unbound: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: error mounting “/home/pi/unbound/unbound.conf” to rootfs at “/usr/local/unbound/unbound.conf”: mount /home/pi/unbound/unbound.conf:/usr/local/unbound/unbound.conf (via /proc/self/fd/6), flags: 0x5000: not a directory: unknown: Are you trying to mount a directory onto a file (or vice-versa)? Check if the specified host path exists and is the expected type
    ERROR: Encountered errors while bringing up the project.

    1 year ago Reply
    • FelixOwner

      @Esteban: Make sure docker has permission to create unbound.conf at that path or you can create a conf file yourself.

      1 year ago Reply
      • teflon

        @Felix: hey Felix thanks for your guide. However I have the same OCI runtime error mentioned in the post below. Can you let me know how to resolve this issue please

        1 year ago Reply
        • roynuj

          @teflon: Seems like it’s a problem with the Dockerfile. unbound.conf and log.d/unbound.log are being created as directories, not files. If you remove those 2 directories and replace them with files, the container should start. I submitted a issue for the unbound container’s GitHub: https://github.com/madnuttah/unbound-docker/issues/23.

          1 year ago Reply
  • Broomwalker

    Some content from the unbound.log (not sure if helpful):

    Apr 28 21:50:24 unbound[1:0] notice: init module 0: validator
    Apr 28 21:50:24 unbound[1:0] notice: init module 1: iterator
    Apr 28 21:50:25 unbound[1:0] info: start of service (unbound 1.17.1).
    Apr 28 21:50:25 unbound[1:0] fatal error: could not open autotrust file for writing, /iana.d/root.key.1-0-7fa96dd610: Permission denied

    1 year ago Reply
    • FelixOwner

      @Broomwalker: The log shows permission issue. Seems to be the volume mapping problem. The only thing I can suggest is try to only map the config files you need to customise, otherwise leave it default. Let the unbound docker instance successfully start once with very basic config. Then you can tweak the config afterwards.

      1 year ago Reply
      • Broomwalker

        @Felix: Thanks, but that’s not enough info for me to troubleshoot the problem. Is there anything wrong with your instructions above or further instructions that might not be described? If I’ve copied and pasted the script & downloaded the files/folders from GitHub…

        1 year ago Reply
        • FelixOwner

          @Broomwalker: I updated the instruction to include my working configuration. You can take it as reference. Please make sure the system and file permissions to unbound and docker service.

          1 year ago Reply
          • Broomwalker

            @Felix: Thank you – this did help to understand what was needed besides me recreating the files from the github examples.

            I’ve followed this fresh (deleted /home/pi/unbound/ and /home/pi/pihole).
            I’ve created the directories
            I’ve created the docker-compose.yml file – editing my IP to 172.22.0.6 and 172.22.0.7, keeping the 5335 port.
            I’ve created all of the config files listed in bold. I’ve changed nothing from these – nothing stood out to me as requiring change.
            I didn’t create performance.conf – I wouldn’t have the foggiest how what I would need to modify
            I didn’t create remote-control.conf (not bold)
            I created root.zone but VNC’ing in and downloading from https://www.internic.net/domain/. “wget” command didn’t work for me.
            I started up Unbound, and I got the following error:

            Creating unbound … error

            ERROR: for unbound Cannot start service unbound: OCI runtime create failed: container_linux.go:367: starting container process caused: process_linux.go:495: container init caused: rootfs_linux.go:76: mounting “/home/pi/unbound/log.d/unbound.log” to rootfs at “/usr/local/unbound/log.d/unbound.log” caused: mount through procfd: not a directory: unknown: Are you trying to mount a directory onto a file (or vice-versa)? Check if the specified host path exists and is the expected type

            ERROR: for unbound Cannot start service unbound: OCI runtime create failed: container_linux.go:367: starting container process caused: process_linux.go:495: container init caused: rootfs_linux.go:76: mounting “/home/pi/unbound/log.d/unbound.log” to rootfs at “/usr/local/unbound/log.d/unbound.log” caused: mount through procfd: not a directory: unknown: Are you trying to mount a directory onto a file (or vice-versa)? Check if the specified host path exists and is the expected type
            ERROR: Encountered errors while bringing up the project.

            I followed on from the discussion below from roynuj @ https://github.com/madnuttah/unbound-docker/issues/23, and removed “unbound.log” the directory, and created an empty “unbound.log” the file.

            I respun up Unbound and it created the container.
            I tried your suggested command but for @172.22.0.7 (my IP address) – and I get the following error:

            ; <> DiG 9.16.37-Debian <> http://www.google.com @172.22.0.7 -p 5335
            ;; global options: +cmd
            ;; connection timed out; no servers could be reached

            It seems like it didn’t work?
            Nonetheless, I continued on and created Pihole
            And I get the errors I was getting before, updating gravity I get:

            [✗] DNS resolution is currently unavailable
            [✗] DNS resolution is not available

            And the “Domains on Adlists” is a negative number.

            Sorry you’re probably like “wtf” why aren’t you getting this right! By the end of this there will be the idiots guide equivalent!

            1 year ago
          • FelixOwner

            @Broomwalker: Looks like the image do have some permission and mapping issues. I played around a bit and updated my instruction especially quote out those logging file and root.key path. Hopefully it should be working now. Can you test again?

            1 year ago
  • Jiggy

    I hve this issue

    sudo docker logs unbound
    May 26 15:52:11 unbound[1:0] error: Could not open logfile /log.d/unbound.log: Permission denied
    May 26 15:52:11 unbound[1:0] notice: init module 0: validator
    May 26 15:52:11 unbound[1:0] notice: init module 1: iterator
    May 26 15:52:13 unbound[1:0] info: start of service (unbound 1.17.1).
    May 26 15:52:15 unbound[1:0] error: could not open /iana.d/root.zone.tmp1: Permission denied
    May 26 20:22:22 unbound[1:0] error: could not open /iana.d/root.zone.tmp1: Permission denied
    May 26 23:22:27 unbound[1:0] error: could not open /iana.d/root.zone.tmp1: Permission denied
    May 27 07:52:39 unbound[1:0] error: could not open /iana.d/root.zone.tmp1: Permission denied
    May 27 19:52:56 unbound[1:0] error: could not open /iana.d/root.zone.tmp1: Permission denied
    May 28 07:53:16 unbound[1:0] error: could not open /iana.d/root.zone.tmp1: Permission denied
    May 28 20:53:34 unbound[1:0] error: could not open /iana.d/root.zone.tmp1: Permission denied
    May 29 07:53:52 unbound[1:0] error: could not open /iana.d/root.zone.tmp1: Permission denied
    May 29 20:54:10 unbound[1:0] error: could not open /iana.d/root.zone.tmp1: Permission denied

    1 year ago Reply
    • cosmic303

      @Jiggy: Try adjusting the permissions for /unbound again. The user that runs the container (usually “pi”) needs rw on the folder and subfolders. Even though i created the folders and files with the user, i still had to use sudo chmod 755 -R unbound/ to make it work

      11 months ago Reply
  • Munkie

    Hello
    For this setting is there nexxesary to update the pihole/admin dns upstream aswell?
    Struggling to add upstream to already running docker image for pihole

    10 months ago Reply
    • FelixOwner

      @Munkie: No. The docker-compose configuration already set the Pihole upstream DNS to the unbound container.
      You can edit the Pihole upstream DNS to any DNS servers as you wish in its admin portal.

      10 months ago Reply
  • Ricardo

    Hi @Felix

    I’m trying to install pihole + unbound using your guide and everything goes smoothly until I try to do the first dig, which doesn’t work:

    ;; communications error to 172.20.0.7#5335: timed out
    ;; communications error to 172.20.0.7#5335: timed out
    ;; communications error to 172.20.0.7#5335: timed out

    ; <> DiG 9.18.19-1~deb12u1-Debian <> http://www.google.com @172.20.0.7 -p 5335
    ;; global options: +cmd
    ;; no servers could be reached

    I saw in the last comments that this could be a permission issue with the image which I already ran the chown command to change the unbound folder permissions and I also saw on the GitHub issue (https://github.com/madnuttah/unbound-docker/issues/23) that no solution was found to resolve this problem.

    Docker container logs:

    Jan 16 02:12:18 unbound[1:0] error: Could not open logfile /log.d/unbound.log: Permission denied
    Jan 16 02:12:18 unbound[1:0] notice: init module 0: validator
    Jan 16 02:12:18 unbound[1:0] notice: init module 1: iterator
    Jan 16 02:12:18 unbound[1:0] info: start of service (unbound 1.19.0).

    Permissions of “unbound/iana.d” before I ran the dig command (dig http://www.google.com @172.20.0.7 -p 5335):

    drwxr-xr-x 2 root pi 4096 Jan 16 02:16 .
    drwxr-xr-x 6 root pi 4096 Jan 16 01:16 ..
    -rw-r–r– 1 root pi 758 Jan 16 02:16 root.key
    -rwxr-xr-x 1 root pi 2254606 Jan 15 19:10 root.zone

    Permissions of “unbound/iana.d” after I ran the dig command:

    drwxr-xr-x 2 root pi 4096 Jan 16 02:24 .
    drwxr-xr-x 6 root pi 4096 Jan 16 01:16 ..
    -rw-r–r– 1 root root 758 Jan 16 02:24 root.key
    -rwxr-xr-x 1 root pi 2254606 Jan 15 19:10 root.zone

    Please let me know if you have new information that could solve this issue.

    Thanks for the help in advance.

    Ricardo

    5 months ago Reply
    • FelixOwner

      @Ricardo: Hi @Ricardo, you can try to map the unbound.log file directly in the docker-compose file instead of mapping the log.d directory.
      – /home/pi/unbound/log.d/unbound.log:/usr/local/unbound/log.d/unbound.log:rw

      This should solve the issue you met. Just make sure you have unbound instance up running properly first.

      5 months ago Reply
      • Ricardo

        @Felix: Hi Felix,

        Thanks for the feedback but I still have the same issues.
        I added the unbound.log file to the docker compose volumes as you said:

        volumes:
        – /home/pi/unbound/unbound.conf:/usr/local/unbound/unbound.conf:rw
        – /home/pi/unbound/conf.d/:/usr/local/unbound/conf.d/:rw
        – /home/pi/unbound/log.d/unbound.log:/usr/local/unbound/log.d/unbound.log:rw
        – /home/pi/unbound/zones.d/:/usr/local/unbound/zones.d/:rw
        – /home/pi/unbound/iana.d/:/usr/local/unbound/iana.d/:rw

        Docker container logs:

        “Could not open logfile /log.d/unbound.log: Permission denied”
        “Could not open autotrust file for writing, /iana.d/root.key.1-0-7fffa35072c0: Permission denied”

        Jan 16 18:37:14 unbound[1:0] warning: unbound is already running as pid 1.
        Jan 16 18:37:14 unbound[1:0] error: Could not open logfile /log.d/unbound.log: Permission denied
        Jan 16 18:37:14 unbound[1:0] notice: init module 0: validator
        Jan 16 18:37:14 unbound[1:0] notice: init module 1: iterator
        Jan 16 18:37:14 unbound[1:0] info: start of service (unbound 1.19.0).
        Jan 16 18:37:18 unbound[1:0] info: generate keytag query _ta-4f66. NULL IN
        Jan 16 18:37:18 unbound[1:0] fatal error: could not open autotrust file for writing, /iana.d/root.key.1-0-7fffa35072c0: Permission denied
        Jan 16 18:37:18 unbound[1:0] warning: unbound is already running as pid 1.
        Jan 16 18:37:18 unbound[1:0] error: Could not open logfile /log.d/unbound.log: Permission denied
        Jan 16 18:37:18 unbound[1:0] notice: init module 0: validator
        Jan 16 18:37:18 unbound[1:0] notice: init module 1: iterator
        Jan 16 18:37:19 unbound[1:0] info: start of service (unbound 1.19.0).

        I created the file unbound.log because I had that issue when a directory is created instead of a file.
        I ran the commands “sudo chown -R root:1000 /home/pi/unbound/” and “sudo chmod 755 -R /home/pi/unbound/” to have the correct permissions.

        /home/pi/unbound/log.d/
        total 8
        drwxr-xr-x 2 root pi 4096 Jan 16 18:33 .
        drwxr-xr-x 6 root pi 4096 Jan 16 01:16 ..
        -rwxr-xr-x 1 root pi 0 Jan 16 18:33 unbound.log

        /home/pi/unbound/iana.d/
        total 2216
        drwxr-xr-x 2 root pi 4096 Jan 16 18:37 .
        drwxr-xr-x 6 root pi 4096 Jan 16 01:16 ..
        -rw-r–r– 1 root root 758 Jan 16 18:37 root.key
        -rwxr-xr-x 1 root pi 2254606 Jan 15 19:10 root.zone

        5 months ago Reply
        • FelixOwner

          @Ricardo: Ok, which user your docker is running as? Why those mapped volumes use root:pi user group?

          5 months ago Reply
          • Ricardo

            @Felix: Sorry, I’m pretty new to this. How can I check that? I tried running bash on the container to see but I got the following error:

            OCI runtime exec failed: exec failed: unable to start container process: exec: “bash”: executable file not found in $PATH: unknown

            5 months ago
          • FelixOwner

            @Ricardo: In this case I have to suggest you read some instruction articles about docker and Linux file permissions.
            For example, https://mydeveloperplanet.com/2022/10/19/docker-files-and-volumes-permission-denied/
            https://medium.com/@nielssj/docker-volumes-and-file-system-permissions-772c1aee23ca
            Hope this helps.

            5 months ago
          • Ricardo

            @Felix: Hi Felix,

            Thank you for the articles about this matter.
            It really helped understand the importance of permissions and groups for Docker containers. I wasn’t aware that it was that important.

            With that in mind, I troubleshooted more and finally found a solution.
            I will explain all the steps I did to solve the issue:

            1st – I noticed that my user “pi” was in the same GID as the unbound user (_unbound on Dockerfile), ID 1000. I wasn’t sure if that was correct so I changed my pi’s group ID to 1001.
            But even after recreating the directories and files again and running the docker-compose again in a fresh Docker installation (pruned all the settings) didn’t worked, same permissions issues happened.

            2nd – While I was checking the Github issue about this problem (https://github.com/madnuttah/unbound-docker/issues/23) I noticed that madnuttah shared his output of the unbound directory with 1000:1000 as the group ID for all the sub directories. So, I ran the chown command with that in mind: sudo chown -R 1000:1000 /home/pi/unbound/. After that my unbound directory permissions looked like this:

            total 28
            drwxr-xr-x 6 pi 1000 4096 Jan 17 01:52 .
            drwxr-xr-x 5 pi pi 4096 Jan 17 01:48 ..
            drwxr-xr-x 2 pi 1000 4096 Jan 17 01:55 conf.d
            drwxr-xr-x 2 pi 1000 4096 Jan 17 02:22 iana.d
            drwxr-xr-x 2 pi 1000 4096 Jan 17 01:59 log.d
            -rwxr-xr-x 1 pi 1000 298 Jan 17 01:52 unbound.conf
            drwxr-xr-x 2 pi 1000 4096 Jan 17 01:55 zones.d

            Ran the dig command and it worked!

            dig http://www.google.com @172.20.0.7 -p 5335

            ; <> DiG 9.18.19-1~deb12u1-Debian <> http://www.google.com @172.20.0.7 -p 5335
            ;; global options: +cmd
            ;; Got answer:
            ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 37987
            ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

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

            ;; ANSWER SECTION:
            http://www.google.com. 300 IN A 172.217.168.164

            ;; Query time: 95 msec
            ;; SERVER: 172.20.0.7#5335(172.20.0.7) (UDP)
            ;; WHEN: Wed Jan 17 02:49:51 WET 2024
            ;; MSG SIZE rcvd: 59

            Thanks for the help Felix and hope this helps future people if needed.

            P.S: Still not sure if changing the GID helped fixing this (probably not).

            5 months ago
  • Ricardo

    # Continuation of last comment thread (couldn’t add more replies) #

    Hi Felix,

    Thank you for the articles about this matter.
    It really helped understand the importance of permissions and groups for Docker containers. I wasn’t aware that it was that important.

    With that in mind, I troubleshooted more and finally found a solution.
    I will explain all the steps I did to solve the issue:

    1st – I noticed that my user “pi” was in the same GID as the unbound user (_unbound on Dockerfile), ID 1000. I wasn’t sure if that was correct so I changed my pi’s group ID to 1001.
    But even after recreating the directories and files again and running the docker-compose again in a fresh Docker installation (pruned all the settings) didn’t worked, same permissions issues happened.

    2nd – While I was checking the Github issue about this problem (https://github.com/madnuttah/unbound-docker/issues/23) I noticed that madnuttah shared his output of the unbound directory with 1000:1000 as the group ID for all the sub directories. So, I ran the chown command with that in mind: sudo chown -R 1000:1000 /home/pi/unbound/. After that my unbound directory permissions looked like this:

    total 28
    drwxr-xr-x 6 pi 1000 4096 Jan 17 01:52 .
    drwxr-xr-x 5 pi pi 4096 Jan 17 01:48 ..
    drwxr-xr-x 2 pi 1000 4096 Jan 17 01:55 conf.d
    drwxr-xr-x 2 pi 1000 4096 Jan 17 02:22 iana.d
    drwxr-xr-x 2 pi 1000 4096 Jan 17 01:59 log.d
    -rwxr-xr-x 1 pi 1000 298 Jan 17 01:52 unbound.conf
    drwxr-xr-x 2 pi 1000 4096 Jan 17 01:55 zones.d

    Ran the dig command and it worked!

    dig http://www.google.com @172.20.0.7 -p 5335

    ; DiG 9.18.19-1~deb12u1-Debian http://www.google.com @172.20.0.7 -p 5335
    ;; global options: +cmd
    ;; Got answer:
    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 37987
    ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

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

    ;; ANSWER SECTION:
    http://www.google.com. 300 IN A 172.217.168.164

    ;; Query time: 95 msec
    ;; SERVER: 172.20.0.7#5335(172.20.0.7) (UDP)
    ;; WHEN: Wed Jan 17 02:49:51 WET 2024
    ;; MSG SIZE rcvd: 59

    Thanks for the help Felix and hope this helps future people if needed.

    P.S: Still not sure if changing the GID helped fixing this (probably not).

    5 months ago Reply
  • quaff

    Hi thanks for your guide! It really helped me set up my own pihole + unbound docker container setup. I’ve been using this for a few years now and it’s been running great. I noticed since your recent update you’ve switched the unbound docker image from mvance to madnuttah. What was your reasoning for doing so? I am using an older revision of this guide that had mvance’s unbound image. Would love to know if I should switch over too 🙏

    3 months ago Reply
    • FelixOwner

      @quaff: Hi Quaff, thank you for your comment. The reason to switch the docker image was some problems I cannot solve. The madnuttah’s unbound image configuration is quite straightforward and focusing on secure configuration which I prefer.

      3 months ago Reply

xFelix

Pihole + unbound docker setup on Raspberry Pi
Pihole is DNS based Ad blocking solution. It can also be used to enhance your home network security by filtering out malicious domain and provide privacy protection by preven…
Scan QR code to continue reading
2020-09-16