Skip to content

Commit 46440b8

Browse files
committed
try to fix unbound
Signed-off-by: Simon L. <szaimen@e.mail.de>
1 parent 35e2041 commit 46440b8

1 file changed

Lines changed: 79 additions & 25 deletions

File tree

not-supported/pi-hole.sh

Lines changed: 79 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,14 @@ else
7575
if [ -f /etc/unbound/unbound.conf.d/pi-hole.conf ]
7676
then
7777
rm -f /etc/unbound/unbound.conf.d/pi-hole.conf
78+
# Remove the daily restart cron job
79+
crontab -u root -l 2>/dev/null | grep -v "restart unbound" | crontab -u root -
7880
rm -f /etc/systemd/system/unbound.service.d/ncvm-pihole.conf
7981
rmdir /etc/systemd/system/unbound.service.d &>/dev/null
8082
systemctl daemon-reload
81-
if is_this_installed unbound
83+
if is_this_installed unbound || is_this_installed unbound-anchor
8284
then
83-
apt-get purge unbound -y
85+
apt-get purge unbound unbound-anchor -y
8486
apt-get autoremove -y
8587
fi
8688
fi
@@ -372,11 +374,36 @@ ufw allow "$PIHOLE_PROXY_PORT"/tcp comment 'Pi-hole Web' &>/dev/null
372374
if [ "$UNBOUND" = "yes" ]
373375
then
374376
# Install unbound. We do not use install_if_not here, since it installs
375-
# with RUNLEVEL=1, which skips the postinst that creates the DNSSEC anchor.
376-
if ! is_this_installed unbound
377+
# with RUNLEVEL=1, which skips parts of the package setup.
378+
if ! is_this_installed unbound || ! is_this_installed unbound-anchor
377379
then
378380
apt-get update -q4 & spinner_loading
379-
check_command apt-get install unbound -y
381+
check_command apt-get install unbound unbound-anchor -y
382+
fi
383+
384+
# Ubuntu makes unbound listen on 127.0.0.1:53 via resolvconf, which
385+
# conflicts with port 53 that the Pi-hole container publishes
386+
systemctl disable --now unbound-resolvconf.service &>/dev/null
387+
rm -f /etc/unbound/unbound.conf.d/resolvconf_resolvers.conf
388+
389+
# The DNSSEC root trust anchor is not always created by the package,
390+
# but unbound refuses to start without it
391+
if ! [ -f /var/lib/unbound/root.key ]
392+
then
393+
print_text_in_color "$ICyan" "Creating the DNSSEC root trust anchor..."
394+
mkdir -p /var/lib/unbound
395+
# It returns 1 when it had to bootstrap the key from its built-in
396+
# copy, which is the expected case on a fresh installation
397+
unbound-anchor -a /var/lib/unbound/root.key || true
398+
chown unbound:unbound /var/lib/unbound/root.key &>/dev/null
399+
if ! [ -f /var/lib/unbound/root.key ]
400+
then
401+
msg_box "Could not create the DNSSEC root trust anchor in \
402+
'/var/lib/unbound/root.key', which means that unbound cannot start.
403+
404+
Please report this to $ISSUES"
405+
exit 1
406+
fi
380407
fi
381408

382409
# unbound listens on the docker bridge gateway so that the container can
@@ -438,25 +465,61 @@ After=docker.service
438465
UNBOUND_SERVICE
439466
systemctl daemon-reload
440467

441-
# Restart unbound
468+
# Allow the container to reach unbound on the docker bridge
469+
ufw allow in on docker0 to "$DOCKER_GATEWAY" port 5335 comment 'Pi-hole unbound' &>/dev/null
470+
471+
# Restart unbound. A former failed start can latch the unit into a failed
472+
# state with 'start request repeated too quickly', which we clear first
442473
print_text_in_color "$ICyan" "Restarting unbound..."
443-
check_command systemctl restart unbound
444-
countdown "Waiting for unbound to start... " 10
474+
systemctl reset-failed unbound &>/dev/null
475+
systemctl restart unbound &>/dev/null
476+
477+
# Wait for unbound to actually answer instead of guessing a delay, since
478+
# a restart can still end in a failed unit or a not yet ready resolver
479+
UNBOUND_READY=no
480+
for _ in $(seq 1 30)
481+
do
482+
if docker exec pihole dig +time=2 +tries=1 @"$DOCKER_GATEWAY" -p 5335 \
483+
nextcloud.com &>/dev/null
484+
then
485+
UNBOUND_READY=yes
486+
break
487+
fi
488+
sleep 1
489+
done
490+
if [ "$UNBOUND_READY" != "yes" ]
491+
then
492+
msg_box "unbound did not start correctly and does not answer queries.
493+
494+
Please report this to $ISSUES"
495+
exit 1
496+
fi
445497

446-
# Testing DNSSEC
447-
install_if_not dnsutils
448-
if ! dig sigfail.verteiltesysteme.net @"$DOCKER_GATEWAY" -p 5335 | grep -q "SERVFAIL"
498+
# Testing DNSSEC from inside the container, since unbound refuses queries
499+
# from the host. A validated answer carries the 'ad' flag.
500+
if ! docker exec pihole dig +time=10 +tries=1 @"$DOCKER_GATEWAY" -p 5335 \
501+
sigok.verteiltesysteme.net | grep -q "flags:.* ad[;,]"
449502
then
450-
msg_box "Something went wrong while testing SERVFAIL.
503+
msg_box "Something went wrong while testing DNSSEC validation.
504+
unbound did not return an authenticated answer for a signed domain.
505+
451506
Please report this to $ISSUES"
452-
elif ! dig sigok.verteiltesysteme.net @"$DOCKER_GATEWAY" -p 5335 | grep -q "NOERROR"
507+
# A domain with a broken signature must not resolve. unbound either answers
508+
# with SERVFAIL or doesn't answer at all while it retries the nameservers
509+
elif docker exec pihole dig +time=10 +tries=1 @"$DOCKER_GATEWAY" -p 5335 \
510+
sigfail.verteiltesysteme.net | grep -q "flags:.* ad[;,]"
453511
then
454-
msg_box "Something went wrong while testing NOERROR.
512+
msg_box "Something went wrong while testing DNSSEC validation.
513+
unbound validated a domain with a broken signature.
514+
455515
Please report this to $ISSUES"
456516
fi
457517

458-
# Allow the container to reach unbound on the docker bridge
459-
ufw allow in on docker0 to "$DOCKER_GATEWAY" port 5335 comment 'Pi-hole unbound' &>/dev/null
518+
# Restart unbound daily, since a failed start at boot latches the unit and
519+
# would leave the Pi-hole without its upstream DNS server until fixed by hand
520+
crontab -u root -l 2>/dev/null | grep -v "restart unbound" | crontab -u root -
521+
crontab -u root -l 2>/dev/null | { cat; echo "0 4 * * * systemctl reset-failed \
522+
unbound && systemctl restart unbound"; } | crontab -u root -
460523

461524
# Configure Pi-hole to use unbound as its upstream DNS server
462525
print_text_in_color "$ICyan" "Configuring Pi-hole to use unbound..."
@@ -526,13 +589,4 @@ which will generate and show you a new password while keeping all your settings.
526589
Please also note that the DHCP functionality of Pi-hole is not enabled since the \
527590
container doesn't run in the host network."
528591

529-
# Inform about updates
530-
msg_box "Concerning updates:
531-
Pi-hole runs in a Docker container, which means that you can update it \
532-
by running the following commands:
533-
'sudo docker pull pihole/pihole:latest'
534-
and afterwards running this script again and choosing 'Reinstall'.
535-
536-
Your settings and statistics in '$PIHOLE_DIR' will be kept in that process."
537-
538592
exit

0 commit comments

Comments
 (0)