Pi Zero W2 AdGuard Plus Unbound Setup Guide

Complete DNS Privacy & DNSSEC Validation Guide for Raspberry Pi Zero W2

Part 1: Initial Pi Setup

1.1 SSH into the Pi

ssh username@pihole.local

Or use IP address if .local doesn't work:

ssh username@YOUR_PI_IP_ADDRESS

1.2 Update System

sudo apt update
sudo apt upgrade -y

1.3 Install R

...

By A Saleh

Published on December 7, 2025, 6:26 pm

red Tools

⚠️ IMPORTANT: These tools are required for testing and don't come pre-installed on Raspberry Pi OS

sudo apt install -y curl wget nano dnsutils tcpdump

Part 2: Install Unbound

2.1 Install Unbound

sudo apt install -y unbound

2.2 Create Unbound Configuration

sudo nano /etc/unbound/unbound.conf.d/recursive.conf

⚠️ IMPORTANT: Copy this entire configuration exactly and paste into the editor:

server:
    interface: 0.0.0.0
    port: 5335
    do-ip4: yes
    do-ip6: no
    do-udp: yes
    do-tcp: yes
    num-threads: 2
    qname-minimisation: yes
    val-permissive-mode: no
    aggressive-nsec: yes
    hide-identity: yes
    hide-version: yes
    harden-glue: yes
    harden-dnssec-stripped: yes
    use-caps-for-id: yes
    tls-cert-bundle: "/etc/ssl/certs/ca-certificates.crt"
    cache-min-ttl: 300
    cache-max-ttl: 14400
    msg-cache-size: 128m
    rrset-cache-size: 256m
    access-control: 127.0.0.1/32 allow
    access-control: 192.168.0.0/16 allow
    access-control: 172.16.0.0/12 allow
    access-control: 10.0.0.0/8 allow

Save with: Ctrl+X, then Y, then Enter

2.3 Verify & Start Unbound

sudo unbound-checkconf

Should output: unbound-checkconf: no errors in /etc/unbound/unbound.conf

sudo systemctl enable unbound
sudo systemctl restart unbound
sudo systemctl status unbound

2.4 Verify Unbound is Listening

sudo ss -tlnp | grep 5335

Should show: LISTEN 0 256 0.0.0.0:5335

2.5 Test Unbound

dig @127.0.0.1 -p 5335 google.com
dig @127.0.0.1 -p 5335 dnssec.works +dnssec

Second query should show: flags: qr rd ra ad; (ad = DNSSEC validated)

Part 3: Install AdGuard Home

3.1 Download and Install

cd /opt
sudo curl -L https://static.adguard.com/adguardhome/release/AdGuardHome_linux_arm64.tar.gz -o AdGuardHome.tar.gz
sudo tar -xzf AdGuardHome.tar.gz
cd AdGuardHome
sudo ./AdGuardHome -s install

3.2 Start AdGuard

sudo systemctl start AdGuardHome
sudo systemctl enable AdGuardHome

3.3 Access Web Interface

Open your browser and navigate to: http://YOUR_PI_IP_ADDRESS:3000

Complete the setup wizard and create your admin account.

Part 4: Configure AdGuard to Use Unbound

4.1 Set Upstream DNS

  1. Go to http://YOUR_PI_IP_ADDRESS:3000
  2. Click SettingsDNS Settings
  3. In Upstream DNS servers, enter: 127.0.0.1:5335
  4. Click Save

4.2 Disable AdGuard's DNSSEC

  1. In DNS Settings, find DNSSEC protection
  2. Turn it OFF (uncheck the box)
  3. Click Save

Part 5: Configure Router DNS

5.1 Router Configuration (Recommended)

  1. Access your router admin panel (usually 192.168.1.1)
  2. Go to DHCP Settings or DNS Settings
  3. Set Primary DNS to: YOUR_PI_IP_ADDRESS
  4. Leave Secondary DNS blank
  5. Save and restart router

Result: All devices automatically use AdGuard!

5.2 Manual Configuration (Alternative)

On Linux:

sudo nano /etc/resolv.conf

Change to:

nameserver YOUR_PI_IP_ADDRESS

Part 6: Test Your Setup

6.1 Test from Laptop

dig @YOUR_PI_IP_ADDRESS google.com
dig @YOUR_PI_IP_ADDRESS dnssec.works +dnssec

Second query should show ad flag

6.2 Test Recursive Resolution

dig @YOUR_PI_IP_ADDRESS example.com +trace

Should show root nameservers being queried

6.3 Verify No ISP DNS Leaks

sudo tcpdump -i any -n 'udp port 53' | head -20

Run a DNS query in another terminal. You should see YOUR_PI_IP_ADDRESS, NOT ISP servers.

6.4 Check AdGuard Query Log

  1. Go to http://YOUR_PI_IP_ADDRESS:3000
  2. Click Query Log
  3. Should see your DNS queries with status OK

Part 7: Verify DNSSEC

7.1 Test Valid DNSSEC

dig @YOUR_PI_IP_ADDRESS dnssec.works +dnssec

Should show: status NOERROR, flags with "ad", RRSIG record

7.2 Test Invalid DNSSEC

dig @YOUR_PI_IP_ADDRESS dnssec-failed.org +dnssec

Should show: status SERVFAIL (correctly rejected bad signature)

7.3 Online Tests

Visit these sites to verify your setup:

Part 8: Optional - Add DoT (DNS over TLS)

8.1 Update Unbound Config

sudo nano /etc/unbound/unbound.conf.d/recursive.conf

Add this section at the end:

forward-zone:
    name: "."
    forward-tls-upstream: yes
    forward-addr: 1.1.1.1@853#cloudflare-dns.com
    forward-addr: 1.0.0.1@853#cloudflare-dns.com

8.2 Restart Unbound

sudo systemctl restart unbound

8.3 Test DoT

dig @YOUR_PI_IP_ADDRESS dnssec.works +dnssec

Should still show ad flag. Query time may be 200-400ms (normal for DoT)

Troubleshooting

Issue: AdGuard cannot reach Unbound

Error: "could not be used"

Solution: Check access control in Unbound

sudo nano /etc/unbound/unbound.conf.d/recursive.conf

Verify this line exists:

access-control: 192.168.0.0/16 allow

Then restart:

sudo systemctl restart unbound

Issue: DNSSEC queries show SERVFAIL

Solution: Check certificate bundle

ls -lh /etc/ssl/certs/ca-certificates.crt

If missing, reinstall:

sudo apt install --reinstall ca-certificates
sudo update-ca-certificates
sudo systemctl restart unbound

Issue: DNS is slow

Solution: Increase cache size

sudo nano /etc/unbound/unbound.conf.d/recursive.conf

Change these values:

msg-cache-size: 256m
rrset-cache-size: 512m

Restart:

sudo systemctl restart unbound

Final Verification Checklist


Note: Replace YOUR_PI_IP_ADDRESS with your actual Pi IP address throughout all commands.