Pi-hole installed on Raspberry Pi as network-wide DNS ad blocker.
- Device: Raspberry Pi (64-bit ARM)
- Storage: 14.8GB SD card
- Network: Ethernet (DHCP)
| Setting | Value |
|---|---|
| IPv4 Address | 192.168.1.118 |
| IPv6 Address | fdaa:bbcc:ddee:0:dea6:32ff:fe0d:d680 |
| Hostname | pihole |
| mDNS | pihole.local |
| Web UI | http://pihole.local/admin |
| Web Password | ******** (masked) |
| Upstream DNS | Quad9 (9.9.9.9, 149.112.112.112) |
| Pi-hole Core | v6.3 |
| Pi-hole Web | v6.4 |
| Pi-hole FTL | v6.4.1 |
Downloaded and flashed Raspberry Pi OS Lite (Trixie) 64-bit:
# Download image
curl -L -O "https://downloads.raspberrypi.com/raspios_lite_arm64/images/raspios_lite_arm64-2025-12-04/2025-12-04-raspios-trixie-arm64-lite.img.xz" -o ~/Downloads/
# Flash to SD card
sudo xzcat ~/Downloads/2025-12-04-raspios-trixie-arm64-lite.img.xz | sudo dd of=/dev/sdb bs=4M status=progress conv=fsyncMounted boot partition and created cloud-init configuration:
/boot/user-data:
#cloud-config
hostname: pihole
ssh_pwauth: false
users:
- name: pihole
gecos: Pi-hole Admin
groups: sudo, adm, dialout, cdrom, audio, video, plugdev, games, users, input, netdev, gpio, i2c, spi
sudo: ALL=(ALL) NOPASSWD:ALL
shell: /bin/bash
lock_passwd: true
ssh_authorized_keys:
- <your-ssh-public-key>
runcmd:
- [systemctl, enable, ssh]
- [systemctl, start, ssh]
package_update: true
package_upgrade: true
packages:
- avahi-daemon
- curl/boot/network-config:
network:
version: 2
ethernets:
eth0:
dhcp4: true
optional: falseNote: For Raspberry Pi OS Trixie, the
runcmdsection is required to enable SSH - it's not enabled by default.
Generate SSH key and add public key to cloud-init before first boot:
# Generate key
ssh-keygen -t ed25519 -f ~/.ssh/id_pihole -N "" -C "pihole-access"
# View public key (add this to cloud-init ssh_authorized_keys)
cat ~/.ssh/id_pihole.pub~/.ssh/config:
Host pihole
HostName pihole.local
User pihole
IdentityFile ~/.ssh/id_pihole
ssh pihole "echo '127.0.1.1 pihole' | sudo tee -a /etc/hosts"Created Pi-hole configuration for unattended install:
/etc/pihole/pihole.toml:
[dns]
upstreams = ["9.9.9.9", "149.112.112.112"]
dnssec = true
[ntp.sync]
server = "time.cloudflare.com"Note: Only non-default settings are specified. Pi-hole v6+ uses sensible defaults for rate limiting, caching, and blocking mode.
Ran unattended install:
ssh pihole "curl -sSL https://install.pi-hole.net | sudo bash /dev/stdin --unattended"ssh pihole "sudo pihole setpassword '<password>'"Configured router to use Pi-hole as DNS server:
- Logged into router at http://192.168.1.1
- Navigated to My HomeBox > DNS
- Enabled Static DNS Server Configuration
- Set Primary DNS Server to
192.168.1.118 - Left Secondary DNS Server empty (prevents bypass)
- Applied changes
- Navigated to My HomeBox > IPv6 Static DNS
- Enabled IPv6 Static DNS Server Configuration
- Set Primary DNS Server to
fdaa:bbcc:ddee:0:dea6:32ff:fe0d:d680 - Left Secondary DNS Server empty
- Applied changes
If IPv6 DNS is not being received from the router, check if IPv6 is enabled:
# Check current setting
nmcli connection show "<connection-name>" | grep ipv6.method
# If set to "ignore", enable IPv6 auto-configuration
sudo nmcli connection modify "<connection-name>" ipv6.method auto
sudo nmcli connection up "<connection-name>"# Check both IPv4 and IPv6 DNS
resolvectl status <interface>Expected output:
DNS Servers: 192.168.1.118 fdaa:bbcc:ddee:0:dea6:32ff:fe0d:d680
# Renew DHCP lease
sudo nmcli connection down "<connection-name>" && sudo nmcli connection up "<connection-name>"
# Check DNS settings
resolvectl status <interface># Should resolve (not blocked)
dig google.com +short
# Should be blocked (returns 0.0.0.0)
dig ads.google.com +short
dig doubleclick.net +short
# Test IPv6 blocking (returns ::)
dig AAAA doubleclick.net +shortIf ads are not being blocked after configuration:
# Flush DNS cache
resolvectl flush-caches
# Verify Pi-hole is blocking directly
dig @192.168.1.118 doubleclick.net +short # Should return 0.0.0.0
dig @fdaa:bbcc:ddee:0:dea6:32ff:fe0d:d680 doubleclick.net +short # Should return 0.0.0.0ssh piholessh pihole "sudo pihole -up"ssh pihole "pihole -g"ssh pihole "pihole -t"ssh pihole "sudo systemctl restart pihole-FTL"Add these via the Pi-hole web UI under Adlists or directly to the database.
| List | URL |
|---|---|
| AdAway | https://adaway.org/hosts.txt |
| AdGuard DNS | https://v.firebog.net/hosts/AdguardDNS.txt |
| Easylist | https://v.firebog.net/hosts/Easylist.txt |
| Anudeep ND | https://raw.githubusercontent.com/anudeepND/blacklist/master/adservers.txt |
| Peter Lowe | https://pgl.yoyo.org/adservers/serverlist.php?hostformat=hosts&showintro=0&mimetype=plaintext |
| List | URL |
|---|---|
| Easyprivacy | https://v.firebog.net/hosts/Easyprivacy.txt |
| Windows Spy Blocker | https://raw.githubusercontent.com/crazy-max/WindowsSpyBlocker/master/data/hosts/spy.txt |
| Android Trackers | https://raw.githubusercontent.com/Perflyst/PiHoleBlocklist/master/android-tracking.txt |
| SmartTV Domains | https://raw.githubusercontent.com/Perflyst/PiHoleBlocklist/master/SmartTV.txt |
| List | URL |
|---|---|
| DandelionSprout Anti-Malware | https://raw.githubusercontent.com/DandelionSprout/adfilt/master/Alternate%20versions%20Anti-Malware%20List/AntiMalwareHosts.txt |
| URLhaus | https://urlhaus.abuse.ch/downloads/hostfile/ |
| Phishing Army | https://phishing.army/download/phishing_army_blocklist_extended.txt |
| Spam404 | https://raw.githubusercontent.com/Spam404/lists/master/main-blacklist.txt |
Tip: Run
pihole -gafter adding blocklists to update gravity.
These are Pi-hole's default settings. Only override if needed.
| Setting | Description | Default |
|---|---|---|
dns.upstreams |
Upstream DNS servers | [] (must set) |
dns.dnssec |
DNSSEC validation | false |
dns.listeningMode |
Interface binding | LOCAL |
dns.blocking.mode |
Block response type | NULL |
dns.cache.size |
Cache entries | 10000 |
dns.rateLimit.count |
Queries per minute | 1000 |
dns.specialDomains.mozillaCanary |
Block Firefox DoH | true |
dns.specialDomains.iCloudPrivateRelay |
Block Apple Private Relay | true |
misc.privacylevel |
Stats detail (0-3) | 0 |
ntp.sync.server |
NTP server for time sync | pool.ntp.org |
Add custom DNS entries:
[dns]
hosts = [
"192.168.1.10 nas.local",
"192.168.1.20 printer.local"
]Forward local network queries to router for hostname resolution:
[dns]
revServers = ["192.168.1.0/24,192.168.1.1"]| File | Path |
|---|---|
| Pi-hole Config | /etc/pihole/pihole.toml |
| SSH Key (private) | ~/.ssh/id_pihole |
| SSH Key (public) | ~/.ssh/id_pihole.pub |
| OS Image | ~/Downloads/2025-12-04-raspios-trixie-arm64-lite.img.xz |