Install Pi-hole for Network-Wide Ad Blocking
Install Pi-hole on Linux to block ads and trackers network-wide via DNS. Covers install, blocklists, router DNS setup, whitelisting, and keeping it updated.
Before you start
- ▸A Linux host with a stable connection to your LAN and internet access
- ▸Root or sudo privileges on the host
- ▸Static IP address assigned to the host (via router reservation or OS configuration)
- ▸Basic familiarity with your router's admin panel to change DHCP DNS settings
Pi-hole turns any Linux machine into a network-wide DNS sinkhole. Every device on your LAN — phones, TVs, game consoles — benefits without touching them individually. It works by resolving DNS queries locally and returning a blank response for known ad and tracking domains. A Raspberry Pi is the classic host, but any spare Linux machine or VM works fine.
What You Need
- A dedicated or semi-dedicated Linux host with a static IP address on your LAN
- A supported OS: Debian/Ubuntu, Fedora, or any Raspberry Pi OS release
- Port 53 (DNS) free — nothing else can be listening on that port
- Root or sudo access
Step 1: Assign a Static IP
Pi-hole must have a fixed LAN address or your router's DHCP entry will break after a lease renewal. Set a DHCP reservation in your router admin panel using the host's MAC address, or configure a static address in the OS itself.
On Debian/Ubuntu with NetworkManager (most desktop installs and Ubuntu Server 20.04+):
nmcli con show
nmcli con mod "Wired connection 1" ipv4.addresses 192.168.1.10/24 \
ipv4.gateway 192.168.1.1 ipv4.dns 127.0.0.1 ipv4.method manual
nmcli con up "Wired connection 1"
Replace the connection name and addresses to match your network. On a headless server you may instead edit /etc/netplan/*.yaml (Ubuntu) or /etc/network/interfaces (Debian without NetworkManager).
Step 2: Free Port 53 if Needed
On Ubuntu 17.10+ and Debian 12+, systemd-resolved binds to port 53 on the loopback interface. Check first:
ss -tulnp | grep ':53'
If systemd-resolved appears, disable its stub listener:
sudo sed -i 's/#DNSStubListener=yes/DNSStubListener=no/' /etc/systemd/resolved.conf
sudo systemctl restart systemd-resolved
On Fedora/RHEL, systemd-resolved may not be active by default, but verify with the same ss command. If you're running a local caching resolver like dnsmasq, stop and disable it before proceeding.
Step 3: Run the Pi-hole Installer
Pi-hole ships a single curl-pipe-bash installer. Read through the script at github.com/pi-hole/pi-hole if you prefer to audit it first — that's a reasonable precaution.
curl -sSL https://install.pi-hole.net | bash
The installer is an interactive TUI. Key choices:
- Upstream DNS provider — pick any (Cloudflare, Quad9, etc.); you can change this later in the web UI
- Block lists — accept the default StevenBlack list to start; more can be added post-install
- Web interface & lighttpd — say Yes unless you have a strong reason not to
- Log queries — Yes is recommended for troubleshooting
- Privacy level — level 0 (show everything) is most useful for a home network
When finished, the installer prints the web admin URL and a temporary password. Copy that password immediately.
Step 4: Change the Admin Password
pihole -a -p
You'll be prompted to enter and confirm a new password. The web interface lives at http://<pi-hole-ip>/admin.
Step 5: Add Blocklists
Log into the web interface, go to Adlists, and paste additional list URLs one per line. A few reliable sources:
https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts— already included by defaulthttps://blocklistproject.github.io/Lists/ads.txt— focused ad domainshttps://blocklistproject.github.io/Lists/tracking.txt— tracking pixels and beaconshttps://raw.githubusercontent.com/hagezi/dns-blocklists/main/adblock/multi.txt— well-maintained comprehensive list
After adding lists, update the gravity database (the compiled blocklist):
pihole -g
This can take a minute or two. Output will show how many domains were loaded. A healthy starting gravity is 100,000–300,000 entries depending on your lists.
Step 6: Point Your Router at Pi-hole
This is how every device on the network benefits without individual configuration. In your router's admin panel, find the DHCP server settings and set the Primary DNS to your Pi-hole's static IP. Set the secondary DNS to the Pi-hole IP again, or leave it blank — setting a fallback public DNS like 8.8.8.8 defeats the blocking for any client that gets a DHCP renewal while Pi-hole is unreachable.
After saving, existing devices won't pick up the change until their DHCP lease renews. To force it immediately on a Linux client:
sudo dhclient -r && sudo dhclient
On Windows: ipconfig /release then ipconfig /renew. On Android/iOS, toggle Wi-Fi off and back on.
Step 7: Allow Exceptions (Whitelisting)
Some legitimate sites or services get caught by aggressive blocklists. Whitelist from the command line or via the web UI under Whitelist.
# Whitelist a domain
pihole -w example.com
# Whitelist with regex (for subdomain patterns)
pihole --white-regex '(^|\.)example\.com$'
# Remove from whitelist
pihole -w -d example.com
The web UI Query Log page makes it easy to spot blocked domains that are causing breakage — look for red entries when something stops working, then whitelist selectively rather than disabling Pi-hole entirely.
Step 8: Keep Pi-hole Updated
Pi-hole has its own updater that handles all components (core, FTL DNS resolver, web interface):
pihole -up
Run this periodically or add it to a cron job or systemd timer. To update the gravity blocklists on a schedule, add a weekly cron entry:
sudo crontab -e
# Update gravity every Sunday at 3 AM
0 3 * * 0 pihole -g
Pi-hole also has a built-in update checker in the web dashboard — the version numbers at the bottom of the page show green when everything is current.
Verification
From any device using Pi-hole as its DNS, check that blocking is working:
dig doubleclick.net @192.168.1.10
A blocked domain returns 0.0.0.0 (or the Pi-hole's own IP if you enabled the block page). A legitimate domain returns a real address. You should also see the query appear in the Pi-hole web UI's Query Log within seconds.
Check that Pi-hole's own services are healthy:
pihole status
Expected output shows DNS service is running and Pi-hole blocking is enabled.
Troubleshooting
Nothing is being blocked
Verify the client is actually using Pi-hole's IP as its DNS server: cat /etc/resolv.conf on Linux or check Network details on mobile. If the router change didn't propagate, set the DNS directly on the test device temporarily.
Pi-hole blocks something it shouldn't
Open the Query Log, find the blocked domain, and click the whitelist button next to it. If an entire site category is broken (e.g., a payment processor), check which list is responsible under Blacklist → search for the domain.
Port 53 conflict after reboot
If the installer succeeded but DNS breaks after a reboot, systemd-resolved may have re-enabled its stub. Confirm your /etc/systemd/resolved.conf change persisted and that /etc/resolv.conf is a symlink pointing to /run/systemd/resolve/resolv.conf (not the stub at /run/systemd/resolve/stub-resolv.conf).
ls -la /etc/resolv.conf
pihole -up fails on Fedora/RHEL
Pi-hole's official support for RPM-based distros has been inconsistent. If the updater fails, re-running the install script is safe — it detects an existing installation and updates in place.
Frequently asked questions
- Do I need a Raspberry Pi, or can I run Pi-hole on a VM or existing server?
- Any Linux machine works — a Raspberry Pi, a spare PC, a VirtualBox/KVM VM, or an LXC container. The only hard requirement is that the host has a stable static IP and port 53 available. A VM with bridged networking on an always-on machine is a common and reliable setup.
- Will Pi-hole break websites or cause problems?
- Aggressive blocklists occasionally catch legitimate domains — payment processors, CDNs, and single sign-on providers are common false positives. The Query Log makes it straightforward to find and whitelist the specific domain causing the issue. Start with fewer lists and add more once you're confident in the baseline.
- What happens to the network if Pi-hole goes down?
- Devices will lose DNS resolution and appear to lose internet access, even though routing still works. To mitigate this, either run two Pi-hole instances (Pi-hole supports a sync tool called Gravity Sync), set a DHCP fallback DNS on your router, or ensure the Pi-hole host is on reliable hardware with automatic reboots.
- Can I use Pi-hole alongside a VPN on the same host?
- Yes, but it requires care. If the host runs WireGuard or OpenVPN, configure the VPN's DNS setting to point to Pi-hole's LAN IP (127.0.0.1 or the static LAN address) so VPN clients also benefit from blocking. Routing and firewall rules must allow DNS traffic from the VPN interface to reach Pi-hole's port 53.
- How do I temporarily disable Pi-hole without changing router settings?
- The web UI has a Disable button with timed options (10 seconds, 30 seconds, 5 minutes, custom, or permanent). From the command line: pihole disable and pihole enable. This is useful when diagnosing network issues without tearing down the whole configuration.
Related guides
Configure Prometheus Alertmanager
Configure Prometheus Alertmanager with routing trees, receivers, inhibition rules, grouping, Go templates, and PagerDuty/Slack on-call integrations.
Build an Intranet Server on Linux
Set up a complete small-office intranet on one Linux box: Nginx web server, dnsmasq local DNS, Samba file sharing, and a Wiki.js team wiki.
Build an nftables Firewall Script
Build a complete nftables firewall from scratch: tables, chains, sets, default-deny input policy, service allowlisting, and persistent systemd configuration.
Caddy as a Reverse Proxy
Set up Caddy as a reverse proxy with automatic HTTPS, load balancing, WebSocket passthrough, reusable snippets, and header control — no certbot required.