diff options
author | doc <doc@filenotfound.org> | 2025-06-29 07:20:14 +0000 |
---|---|---|
committer | doc <doc@filenotfound.org> | 2025-06-29 07:20:14 +0000 |
commit | e5bf3b99d39bac5390bd780b08585f2897caf86d (patch) | |
tree | 45b542a04445bdb3228e4521b0c4b832c9a8ff95 /bootstrap-unbound.sh |
Diffstat (limited to 'bootstrap-unbound.sh')
-rwxr-xr-x | bootstrap-unbound.sh | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/bootstrap-unbound.sh b/bootstrap-unbound.sh new file mode 100755 index 0000000..bed5ff1 --- /dev/null +++ b/bootstrap-unbound.sh @@ -0,0 +1,91 @@ +#!/usr/bin/env bash +# bootstrap-unbound.sh +# One-shot installer / hardener for an Unbound recursive resolver +# Tested on Debian 11+/Ubuntu 22.04+ (systemd-based) + +set -euo pipefail +IFS=$'\n\t' + +######################### 1. Settings ################################ + +# Where youβll listen for queries (adjust subnet as needed!) +LISTEN_SUBNET="192.168.0.0/16" +THREADS="$(nproc)" +ROOT_HINTS="/var/lib/unbound/root.hints" +UNBOUND_CONF="/etc/unbound/unbound.conf" + +######################### 2. Install ################################# + +echo "π¦ Installing Unbound..." +apt-get update -qq +DEBIAN_FRONTEND=noninteractive apt-get install -y unbound curl jq dnsutils + +######################### 3. Root hints ############################## + +echo "π Fetching ICANN root hints..." +curl -sSL https://www.internic.net/domain/named.root -o "$ROOT_HINTS" + +######################### 4. Config file ############################# + +echo "π Writing $UNBOUND_CONF ..." +cat > "$UNBOUND_CONF" <<EOF +server: + interface: 0.0.0.0 + access-control: ${LISTEN_SUBNET} allow + access-control: 127.0.0.0/8 allow + + # Performance + num-threads: ${THREADS} + msg-cache-size: 128m + rrset-cache-size: 256m + prefetch: yes + prefetch-key: yes + + # DNSSEC + auto-trust-anchor-file: "/var/lib/unbound/root.key" + val-permissive-mode: no + + # Root servers + root-hints: "${ROOT_HINTS}" + + # Privacy + qname-minimisation: yes + minimal-responses: yes + + # Hardening + harden-dnssec-stripped: yes + harden-referral-path: yes + + # Logging (comment out if too chatty) + log-queries: no + log-replies: no + +remote-control: + control-enable: yes +EOF + +######################### 5. Control certs ########################### + +echo "π Generating control-channel certificates..." +unbound-control-setup + +######################### 6. Enable + start ########################## + +echo "π Enabling & starting Unbound..." +systemctl enable --now unbound + +######################### 7. Smoke tests ############################# + +echo -e "\nπ Quick DNSSEC validation tests:\n" + +GOOD_DOMAIN="cloudflare.com" +BAD_DOMAIN="dnssec-failed.org" +SERVER="127.0.0.1" + +good=$(dig +dnssec +adflag "$GOOD_DOMAIN" @"$SERVER" | grep -q "flags:.* ad" && echo "β
Validated" || echo "β FAILED") +bad=$(dig +dnssec +adflag "$BAD_DOMAIN" @"$SERVER" | grep -q "SERVFAIL" && echo "β
Blocked " || echo "β FAILED") + +printf " %-25s %s\n" "$GOOD_DOMAIN" "$good" +printf " %-25s %s\n" "$BAD_DOMAIN" "$bad" + +echo -e "\nπ All done. Point your LANβs DNS to this server and enjoy DNSSEC-validated recursion." |