Pi-hole, Unbound and PiVPN (WireGuard) installation guide#

This guide documents a clean, battle-tested reinstall of a Raspberry Pi DNS + VPN stack:

  • Pi-hole – network-wide DNS filtering
  • Unbound – recursive DNS resolver
  • PiVPN (WireGuard) – secure remote access using your home DNS

It is written to avoid common pitfalls (DNS proxy issues, premature DHCP changes, routing loops).


0. Assumptions#

  • Raspberry Pi 4
  • Raspberry Pi OS (64-bit, Lite or Desktop)
  • Ethernet connection
  • Static LAN IP via DHCP reservation (example: 192.168.1.20)
  • Router supports:
    • Static DNS via DHCP
    • Port forwarding (UDP)

1. Base OS Preparation#

Flash OS#

Use Raspberry Pi Imager:

  • OS: Raspberry Pi OS (64-bit) - Desktop or Lite
  • Enable SSH
  • Set user + password
  • (Optional) Configure Wi-Fi as fallback
  • Set locale + timezone

Boot and connect over ssh (e.g. ssh pi@ipaddress).


2. System Update#

sudo apt update
sudo apt full-upgrade -y
sudo reboot

3. Locale (Hard-coded, permanent)#

In my case, the locale was not set up correclty and gave a warning when logging in over ssh. To fix and check this, run teh following commands.

sudo locale-gen en_GB.UTF-8

Edit:

sudo nano /etc/default/locale
LANG=en_GB.UTF-8
LC_CTYPE=en_GB.UTF-8
LC_ALL=en_GB.UTF-8

Ensure /etc/environment contains no LC_* or LANG overrides.

Reboot.

Verify:

locale

4. Pi-hole Installation#

curl -sSL https://install.pi-hole.net | bash

Installer choices#

  • Interface: eth0
  • Static IP: accept current
  • Upstream DNS: temporary (Cloudflare / Quad9)
  • Web UI: yes
  • Web server: yes

Verify:

pihole status

5. Unbound (Recursive DNS)#

Install#

sudo apt install unbound -y

Config#

sudo nano /etc/unbound/unbound.conf.d/pi-hole.conf
server:
    interface: 127.0.0.1
    port: 5335
    do-ip4: yes
    do-ip6: no
    do-udp: yes
    do-tcp: yes

    root-hints: "/var/lib/unbound/root.hints"

    harden-glue: yes
    harden-dnssec-stripped: yes
    use-caps-for-id: yes
    edns-buffer-size: 1232

    prefetch: yes
    num-threads: 1

    cache-min-ttl: 3600
    cache-max-ttl: 86400

    hide-identity: yes
    hide-version: yes

Root hints#

sudo curl -o /var/lib/unbound/root.hints https://www.internic.net/domain/named.root
sudo chown unbound:unbound /var/lib/unbound/root.hints

Start#

sudo systemctl enable unbound
sudo systemctl restart unbound

Test#

dig . @127.0.0.1 -p 5335

6. Connect Pi-hole → Unbound#

Pi-hole UI#

  • Settings → DNS
  • Disable all upstream DNS providers
  • Custom IPv4 DNS:
    127.0.0.1#5335

Prevent fallback#

sudo nano /etc/dnsmasq.d/99-disable-resolv.conf
no-resolv

Restart DNS:

pihole restartdns reload

Verify in Query Log:

  • Upstream: localhost#5335

7. Router DNS (CRITICAL ORDER)#

⚠️ Do this only after Pi-hole + Unbound work

Router (LAN / DHCP settings):

  • DNS mode: Static
  • Primary DNS: 192.168.1.20
  • Secondary DNS: (empty)

Reboot router.

Verify from a client:

nslookup google.com

Server should be 192.168.1.20.


8. PiVPN (WireGuard)#

Install#

curl -L https://install.pivpn.io | bash

Installer choices#

  • VPN: WireGuard
  • Interface: eth0
  • Port: 51820
  • DNS provider: Custom → 192.168.1.20
  • Enable unattended upgrades

Create client#

pivpn add

Export#

pivpn -qr

9. Router Port Forward#

Forward:

UDP 51820 → 192.168.1.20

10. VPN Test#

From mobile data / outside LAN:

Pi-hole dashboard should show VPN client (10.6.0.x).


11. Known Pitfalls (Avoid These)#

  • ❌ Do NOT enable router DNS Proxy
  • ❌ Do NOT change DHCP DNS before Pi-hole works
  • ❌ Do NOT use 127.0.0.1 as DNS for VPN clients
  • ❌ Do NOT mix static IP on Pi + DHCP reservation

12. Final Architecture#

Clients
  ↓
Router (DHCP)
  ↓
Pi-hole :53
  ↓
Unbound :5335
  ↓
Root DNS servers

VPN clients:

Remote Device
  ↓ WireGuard
PiVPN
  ↓
Pi-hole → Unbound

13. Maintenance#

Update regularly:

sudo apt update && sudo apt full-upgrade -y
pihole -up

Debug:

pivpn debug

End#

This setup provides:

  • Full DNS privacy
  • Network-wide filtering
  • Secure remote access
  • No dependency on third-party DNS providers