From 9fdd33dc805b950dc2ed622264c3ea373141dda2 Mon Sep 17 00:00:00 2001 From: Staf Wagemakers Date: Tue, 12 Oct 2021 15:35:56 +0200 Subject: [PATCH] Upgrade to Debian Bullseye * Updated the base image to debian:bullseye. * Updated create_zone_config.sh to be able to run outside the container. * Removed the zones.conf generation from the entrypoint * Start the container as the unbound user * Updated to logging.conf * Set the pidfile /tmp/unbound.pid * Added remote-control.conf * Updated the documentation --- Dockerfile | 36 ++++++++--- README.md | 59 +++++++++++++++-- etc/unbound/unbound.conf.d/logging.conf | 15 ++--- etc/unbound/unbound.conf.d/pidfile.conf | 2 + .../unbound.conf.d/remote-control.conf | 3 + scripts/create_zone_config.sh | 63 ++++++++++++++++--- scripts/entrypoint.sh | 7 +-- 7 files changed, 148 insertions(+), 37 deletions(-) create mode 100644 etc/unbound/unbound.conf.d/pidfile.conf create mode 100644 etc/unbound/unbound.conf.d/remote-control.conf diff --git a/Dockerfile b/Dockerfile index 4066d67..5b0dc12 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -ARG BASE_IMAGE=debian:buster +ARG BASE_IMAGE=debian:bullseye FROM $BASE_IMAGE LABEL maintainer "staf wagemakers " @@ -12,31 +12,47 @@ RUN apt-get install unbound-anchor -y RUN apt-get install unbound-host -y RUN apt-get install dns-root-data -y +# get unbound key +RUN unbound-anchor -v -4 || unbound-anchor -v -4 +RUN chown root:unbound /etc/unbound/*.key +RUN chmod 0650 /etc/unbound/*.key +RUN chown root:unbound /etc/unbound/*.pem +RUN chmod 0650 /etc/unbound/*.pem + # config COPY etc/unbound/unbound.conf.d/* /etc/unbound/unbound.conf.d/ RUN chown root:unbound /etc/unbound/unbound.conf.d/* RUN chmod 640 /etc/unbound/unbound.conf.d/* -# get unbound key -RUN unbound-anchor -v || unbound-anchor -v +RUN chown root:unbound /etc/unbound/unbound.conf +RUN chmod 640 /etc/unbound/unbound.conf -# setup local lan server +# copy the required scripts +RUN mkdir -p /home/unbound/scripts +RUN chown -R root:unbound /home/unbound/ +COPY scripts/* /home/unbound/scripts/ +RUN chown root:unbound /home/unbound/scripts/* +RUN chmod 550 /home/unbound/scripts/* + +# setup local lan server RUN mkdir /etc/unbound/zones/ RUN chown root:unbound /etc/unbound/zones/ - COPY etc/unbound/zones/* /etc/unbound/zones/ RUN chown root:unbound /etc/unbound/zones/* RUN chmod 640 /etc/unbound/zones/* -RUN mkdir /root/scripts -COPY scripts/* /root/scripts/ -RUN chown root:root /root/scripts/* -RUN chmod 500 /root/scripts/* +RUN touch /etc/unbound/unbound.conf.d/zones.conf +RUN /home/unbound/scripts/create_zone_config.sh +RUN chown root:unbound /etc/unbound/unbound.conf.d/zones.conf +RUN chmod 640 /etc/unbound/unbound.conf.d/zones.conf EXPOSE 5353/tcp EXPOSE 5353/udp EXPOSE 8953/tcp EXPOSE 8953/udp -ENTRYPOINT ["/root/scripts/entrypoint.sh"] +USER unbound +WORKDIR /home/unbound + +ENTRYPOINT ["/home/unbound/scripts/entrypoint.sh"] diff --git a/README.md b/README.md index c5f43f4..69d5576 100644 --- a/README.md +++ b/README.md @@ -23,9 +23,11 @@ If you want to use another port, you can edit ```etc/unbound/unbound.conf.d/inte #### Use unbound as an authoritative DNS server To use unbound as an authoritative authoritive DNS server - a DNS server that hosts DNS zones - add your zones file ```etc/unbound/zones/```. -Alternatively, you can also use a docker volume to mount ```/etc/unbound/zones/``` to your zone files. -The entrypoint script will create a zone.conf file to serve the zones. +During the creation of the image ```scripts/create_zone_config.sh``` is executed to create the zones configuration file. + +Alternatively, you can also use a docker volume to mount ```/etc/unbound/zones/``` to your zone files. And a volume mount for the ```zones.conf``` +configuration file. You can use subdirectories. The zone file needs to have ```$ORIGIN``` set to our zone origin. @@ -40,6 +42,12 @@ If you want to use another vendor or you want to use the root DNS servers direct $ docker build -t stafwag/unbound . ``` +To use a different BASE_IMAGE, you can use the --build-arg BASE_IMAGE=your_base_image. + +``` +$ docker build --build-arg BASE_IMAGE=stafwag/debian:bullseye -t stafwag/unbound . +``` + ## Run ### Recursive DNS server with DNS-over-TLS @@ -67,7 +75,12 @@ If you want to use unbound as an authoritative dns server you can use the steps [staf@vicky ~]$ ``` -#### Create the zone files +``` +[staf@vicky stafnet]$ cd ~/docker/volumes/unbound/zones/stafnet +[staf@vicky ~]$ +``` + +#### Create the zone files ##### Zone files @@ -106,14 +119,48 @@ $ORIGIN 10.10.10.IN-ADDR.ARPA. Make sure that the volume directoy and zone files have the correct permissions. ``` -$ chmod 755 ~/docker/volumes/unbound/zones/stafnet/ -$ chmod 644 ~/docker/volumes/unbound/zones/stafnet/* +$ sudo chown -R root:5000153 ~/docker/volumes/unbound/ +$ chmod 750 ~/docker/volumes/unbound/zones/stafnet/ +$ chmod 640 ~/docker/volumes/unbound/zones/stafnet/* +``` + +Create the zones.conf configuration file. + +``` +[staf@vicky stafnet]$ cd ~/github/stafwag/docker-stafwag-unbound/ +[staf@vicky docker-stafwag-unbound]$ +``` + +The script will execute a ```chown``` and ```chmod``` on the generated ```zones.conf``` file and is excute with sudo for this reason. + +``` +[staf@vicky docker-stafwag-unbound]$ sudo scripts/create_zone_config.sh -f ~/docker/volumes/unbound/zones.conf -d ~/docker/volumes/unbound/zones/stafnet -p /etc/unbound/zones +Processing: /home/staf/docker/volumes/unbound/zones/stafnet/stafnet.zone +origin=stafnet.local +Processing: /home/staf/docker/volumes/unbound/zones/stafnet/stafnet-rev.zone +origin=1.168.192.IN-ADDR.ARPA +[staf@vicky docker-stafwag-unbound]$ +``` + +Verify the generated ```zones.conf``` + +``` +[staf@vicky docker-stafwag-unbound]$ sudo cat ~/docker/volumes/unbound/zones.conf +auth-zone: + name: stafnet.local + zonefile: /etc/unbound/zones/stafnet.zone + +auth-zone: + name: 1.168.192.IN-ADDR.ARPA + zonefile: /etc/unbound/zones/stafnet-rev.zone + +[staf@vicky docker-stafwag-unbound]$ ``` #### run the container ``` -$ docker run -d --rm --name myunbound -v ~/docker/volumes/unbound/zones/stafnet:/etc//unbound/zones/ -p 127.0.0.1:53:5353 -p 127.0.0.1:53:5353/udp stafwag/unbound +$ docker run --rm --name myunbound -v ~/docker/volumes/unbound/zones/stafnet:/etc//unbound/zones/ -v ~/docker/volumes/unbound/zones.conf:/etc/unbound/unbound.conf.d/zones.conf -p 127.0.0.1:53:5353 -p 127.0.0.1:53:5353/udp stafwag/unbound ``` #### test diff --git a/etc/unbound/unbound.conf.d/logging.conf b/etc/unbound/unbound.conf.d/logging.conf index 2671cf8..9ca609b 100644 --- a/etc/unbound/unbound.conf.d/logging.conf +++ b/etc/unbound/unbound.conf.d/logging.conf @@ -1,7 +1,8 @@ -log-local-actions: no -log-queries: no -log-replies: no -log-servfail: no -logfile: "" -verbosity: 0 -use-syslog: no +server: + log-local-actions: no + log-queries: no + log-replies: no + log-servfail: no + logfile: "" + verbosity: 0 + use-syslog: no diff --git a/etc/unbound/unbound.conf.d/pidfile.conf b/etc/unbound/unbound.conf.d/pidfile.conf new file mode 100644 index 0000000..35a20ca --- /dev/null +++ b/etc/unbound/unbound.conf.d/pidfile.conf @@ -0,0 +1,2 @@ +server: + pidfile: /tmp/unbound.pid diff --git a/etc/unbound/unbound.conf.d/remote-control.conf b/etc/unbound/unbound.conf.d/remote-control.conf new file mode 100644 index 0000000..8b747b8 --- /dev/null +++ b/etc/unbound/unbound.conf.d/remote-control.conf @@ -0,0 +1,3 @@ +remote-control: + control-enable: yes + control-interface: 0.0.0.0 diff --git a/scripts/create_zone_config.sh b/scripts/create_zone_config.sh index b36d2cc..0eb76f2 100755 --- a/scripts/create_zone_config.sh +++ b/scripts/create_zone_config.sh @@ -1,20 +1,58 @@ #!/bin/bash -# creates zones.cfg +# creates zones.conf +set -e -UnboundZoneCfg=/etc/unbound/unbound.conf.d/zones.conf +usage() { + echo >&2 + echo >&2 "Usage: $(basename $0)" + echo >&2 + echo >&2 " optional arguments:" + echo >&2 + echo >&2 " -f Default: /etc/unbound/unbound.conf.d/zones.conf" + echo >&2 " The zones.conf file to create" + echo >&2 " -d Default: /etc/unbound/zones/" + echo >&2 " The zones data source files" + echo >&2 " -p Default: the realpath of zone files " + echo >&2 + exit 1 +} + + +UnboundZoneCfg="/etc/unbound/unbound.conf.d/zones.conf" +ZoneDataDir="/etc/unbound/zones/" +ZonesPath="" + +while getopts “hd:f:p:” OPTION; do + case $OPTION in + f) + UnboundZoneCfg=$OPTARG + ;; + d) + ZoneDataDir=$OPTARG + ;; + p) + ZonesPath=$(echo $OPTARG | sed -e 's@/$@@') + ;; + h) + usage + ;; + ?) + usage + ;; + esac +done > $UnboundZoneCfg || { echo "ERROR: Sorry failed to create $$UnboundZoneCfg" exit 1 } -chown root:unbound $UnboundZoneCfg -chmod 640 $UnboundZoneCfg +ZoneDataDirLen=$(echo $ZoneDataDir | wc -m) while read zoneFile; do - echo "Processing: $zoneFile" + echo >&2 "Processing: $zoneFile" if ! originLine=$(grep "^\$ORIGIN" $zoneFile); then @@ -26,17 +64,26 @@ while read zoneFile; do numberOfOriginLines=$(echo $originLine | wc -l) if [ "$numberOfOriginLines" -gt 1 ]; then - echo "ERROR: $zoneFile has too many \$ORIGIN lines" + echo >&2 "ERROR: $zoneFile has too many \$ORIGIN lines" exit 1 fi origin=$(echo "$originLine" | awk '{ print $2 }' | sed 's/\.$//') - echo "origin=${origin}" + echo >&2 "origin=${origin}" + + if [ -n "$ZonesPath" ]; then + zoneBaseFile=$(echo $zoneFile | cut -c${ZoneDataDirLen}- | sed -e 's@^/@@') + zoneFile="${ZonesPath}/${zoneBaseFile}" + fi + echo "auth-zone:" >> $UnboundZoneCfg echo " name: $origin" >> $UnboundZoneCfg echo " zonefile: $zoneFile" >> $UnboundZoneCfg echo >> $UnboundZoneCfg -done < <(find /etc/unbound/zones/ -name "*.zone") +done < <(find "$ZoneDataDir" -name "*.zone") + +chown root:5000153 $UnboundZoneCfg +chmod 640 $UnboundZoneCfg diff --git a/scripts/entrypoint.sh b/scripts/entrypoint.sh index 46467e7..c75a7fe 100644 --- a/scripts/entrypoint.sh +++ b/scripts/entrypoint.sh @@ -1,8 +1,3 @@ -#!/bin/bash - -/root/scripts/create_zone_config.sh || { - echo "ERROR: failed to create zone configuration" - exit 1 -} +#!/bin/sh unbound -c /etc/unbound/unbound.conf -d