How to Install Pi-hole on Ubuntu: Network-Wide Ad Blocker

By 

•

Published on

•

12 min read

Pi-hole filtering unwanted DNS requests before they reach devices on a home network

If you want to block advertising and tracking domains on devices that cannot run a browser extension, you can filter their DNS requests with Pi-hole. It runs on one computer on your network and checks domain names against your blocklists before forwarding allowed queries to an upstream DNS server.

Because Pi-hole works at the DNS level, it can block a domain but cannot remove individual elements from a page. Ads served from the same domains as the content, including many YouTube ads, cannot reliably be blocked this way.

This guide explains how to install Pi-hole on Ubuntu, configure the admin dashboard, and direct your network’s DNS traffic to the new server. We will use Pi-hole v6 on Ubuntu 26.04; the same installation method also applies to Ubuntu 24.04 and 22.04.

Prerequisites

Before you begin, you need an Ubuntu host with a user account with sudo privileges , internet access, and an IP address that does not change. Pi-hole requires at least 512 MB of RAM and 2 GB of free disk space, with 4 GB of disk space recommended. Allow additional resources for Ubuntu itself, especially if you are using the desktop edition.

The computer must stay powered on and connected to the network while other devices use it for DNS. A small server or an always-on computer is a better choice than a laptop that regularly sleeps.

We will use 192.168.1.10 as the Pi-hole address and 192.168.1.0/24 as the local subnet throughout this guide. Replace these values with the address and subnet of your own network.

Step 1: Prepare the Ubuntu Host

Pi-hole needs a stable IP address because clients reach the DNS server by address. The easiest way to provide one is to reserve the Ubuntu host’s current address in your router’s DHCP settings. The host continues to use DHCP, but the router assigns it the same address each time.

You can find the current IPv4 address with the following command:

Terminal
ip -4 addr show

Look for the inet address on the interface connected to your local network. Reserve that address in your router, or follow our guide on setting a static IP address on Ubuntu if you need to configure it on the host instead. Do this before installing Pi-hole.

Next, refresh the package index and install the tools used in this guide:

Terminal
sudo apt update
sudo apt install curl ca-certificates dnsutils

The dnsutils package provides dig, which we will use to test DNS resolution after the installation.

Check which services are listening on the host:

Terminal
sudo ss -lntup

Pi-hole uses TCP and UDP port 53 for DNS and normally uses TCP ports 80 and 443 for its web interface. Ubuntu’s systemd-resolved service commonly listens on 127.0.0.53:53. The current Pi-hole installer disables its stub listener automatically, so you do not need to disable the entire service before installing. If another DNS server, such as BIND or dnsmasq, is using port 53, resolve that conflict first.

Allow Access Through UFW

If you use UFW , check whether it is active:

Terminal
sudo ufw status

For an active firewall, allow DNS and web access from your local subnet:

Terminal
sudo ufw allow from 192.168.1.0/24 to any port 53
sudo ufw allow from 192.168.1.0/24 to any port 80 proto tcp
sudo ufw allow from 192.168.1.0/24 to any port 443 proto tcp

The first rule allows both TCP and UDP DNS traffic. These rules cover the example IPv4 subnet; if clients connect over IPv6, add equivalent rules for your local IPv6 prefix. Do not forward Pi-hole’s DNS or admin ports from your router to the public internet.

Step 2: Install Pi-hole

Pi-hole provides an official installer that installs its dependencies, web interface, and DNS service. Download the script so you can review it before running it:

Terminal
curl -fSL https://install.pi-hole.net -o basic-install.sh
less basic-install.sh

Press q to leave less. The installer needs root privileges and makes system changes, so run it only after you are comfortable with the script:

Terminal
sudo bash basic-install.sh

The installer opens a text-based setup wizard. Use the arrow keys and Tab to move between choices, Space to select radio buttons, and Enter to confirm.

  1. Continue past the welcome and donation screens.
  2. At Static IP Needed, select Continue after confirming that your address is fixed or reserved. The default choice is Exit.
  3. If you have more than one active network interface, select the one connected to your local network.
  4. Choose an upstream DNS provider. This is the resolver Pi-hole asks for domains it does not block or already have cached. We use Quad9 (filtered, DNSSEC) in this guide; you can change the choice later.
  5. Accept StevenBlack’s Unified Hosts List to start with the default blocklist.
  6. Enable query logging if you want to see requests in the dashboard.
  7. Select a privacy mode. Logs and statistics can reveal which domains devices access, so choose a level appropriate for your network. Show everything is useful while testing.

Pi-hole v6 includes its own web server in the pihole-FTL service. You do not need to install lighttpd or PHP separately.

When the installation finishes, the final screen shows the DNS server address, web interface URL, and a randomly generated admin password. Save the password in your password manager. Use the URL shown by your installation, normally http://192.168.1.10/admin/.

Step 3: Open the Dashboard and Set a Password

Open the admin URL from a device on the same network and log in with the generated password. The dashboard shows query totals, blocked requests, and the clients using Pi-hole:

Pi-hole v6 dashboard showing DNS query totals, blocked requests, and client activity

To change the password, run the following command on the Ubuntu host:

Terminal
sudo pihole setpassword

Enter and confirm your new password when prompted. Using the interactive prompt keeps the password out of your shell history. Do not leave it blank, because a blank password removes password protection from the web interface.

You can check the installed component versions and blocking status from the terminal:

Terminal
pihole -v
sudo pihole status

The version command lists Pi-hole Core, Web, and FTL. The status command reports whether the DNS service is listening and whether blocking is enabled.

Step 4: Point Clients at Pi-hole

Installing Pi-hole does not change the DNS settings on your router or other devices. You need to configure them to send their queries to the new server.

Configure DNS on the Router

The simplest option is to set Pi-hole as the DNS server distributed by your router’s DHCP server. Log in to the router, open its LAN or DHCP settings, and set the DNS server address to 192.168.1.10. The exact field names depend on the router.

These are the settings handed to local clients. Changing only a router’s WAN or Internet DNS setting can leave clients using the router as their resolver, with all queries appearing under the router’s address in Pi-hole.

Do not add a public resolver as a secondary DNS server if you want consistent filtering. Clients may use either advertised server, rather than treating the second one only as a backup. For redundancy, use a second Pi-hole server.

If your router also advertises DNS over IPv6, configure it to advertise a stable IPv6 address belonging to Pi-hole rather than your ISP’s resolver. Clients can use Pi-hole over IPv4 to resolve both IPv4 and IPv6 domain records, but an alternative DNS server advertised over IPv6 can bypass filtering.

Save the settings and reconnect a test device or renew its DHCP lease so it receives the new DNS server. Existing leases do not necessarily change immediately.

If your router cannot distribute a custom DNS server, Pi-hole also includes an optional DHCP server under Settings > DHCP. Disable the router’s DHCP server before enabling Pi-hole’s, and configure a suitable address range and gateway. You can also set DNS on individual clients, as shown below.

Configure an Ubuntu Desktop Client

On an Ubuntu client managed by NetworkManager, first list the active connections:

Terminal
nmcli connection show --active

Use the connection name from the NAME column in the following command. In this example, it is Wired connection 1:

Terminal
sudo nmcli connection modify "Wired connection 1" \
  ipv4.dns "192.168.1.10" ipv4.ignore-auto-dns yes \
  ipv6.dns "" ipv6.ignore-auto-dns yes

This sets Pi-hole as the IPv4 DNS server and ignores automatically supplied DNS servers for both address families. It keeps IPv6 connectivity enabled; DNS queries go to Pi-hole over IPv4. If you want to reach Pi-hole over IPv6 too, set ipv6.dns to its stable IPv6 address instead of an empty string.

Activate the updated connection:

Terminal
sudo nmcli connection up "Wired connection 1"

The connection may briefly drop, so run this locally if you are concerned about losing an SSH session. These commands apply to a NetworkManager connection; Ubuntu Server installations using systemd-networkd need DNS configured through Netplan instead.

Check the result with the following command:

Terminal
resolvectl status

Under the active interface, look for 192.168.1.10 in the DNS server list. Check any other active connections or VPNs too, since they can supply their own DNS settings.

The Pi-hole host does not have to use itself for DNS. Keeping an independent resolver on the host can make repairs easier if Pi-hole stops working. Do not apply the client settings to the server unless you intentionally want its own lookups filtered too.

Step 5: Verify DNS Filtering

Run the following commands from a client that can reach the Pi-hole host. Install dnsutils on that client if dig is unavailable.

First, ask Pi-hole to resolve a normal domain directly:

Terminal
dig @192.168.1.10 example.com +short

You should receive one or more public IP addresses. This checks that Pi-hole can answer an allowed query using its cache or upstream resolver.

Next, query a domain included in the default blocklist:

Terminal
dig @192.168.1.10 doubleclick.net +short

With the default list and blocking mode, the response is:

output
0.0.0.0

Pi-hole returns an unspecified address instead of the domain’s real address. Other blocking modes can return a different response, so use the dashboard’s Query Log to confirm whether a query was blocked.

The @192.168.1.10 argument sends the request directly to Pi-hole and bypasses the client’s configured DNS server. To check the normal DNS path, run the query again without it:

Terminal
dig doubleclick.net +short

Confirm that this query also appears in Pi-hole’s Query Log. On Ubuntu, if you run the query without +short, the SERVER line may show 127.0.0.53 because dig is talking to the local resolver stub; resolvectl status shows the upstream servers that stub uses.

Finally, open a few sites on the client and watch the query log. This checks the browser’s DNS path as well, since browsers using a separate DNS-over-HTTPS provider can bypass the operating system’s resolver.

Step 6: Manage Blocklists

The default StevenBlack list is a useful starting point. You do not need to add several overlapping lists immediately. More lists can also block domains that applications need.

To add a list in Pi-hole v6, open Lists in the dashboard sidebar, enter the list URL, and add it as a blocklist. Use a list published for DNS filtering rather than assuming that every browser ad-blocking subscription will work in Pi-hole.

Pi-hole v6 Lists page showing the default StevenBlack blocklist and list management controls

After adding or changing subscribed lists, rebuild the gravity database on the Ubuntu host:

Terminal
sudo pihole -g

Gravity downloads the subscribed lists and combines their domains into the blocking database. Check the output for download errors; the number of domains depends on your lists and when you update them.

If an application stops working, open Query Log, reproduce the problem, and inspect the blocked requests from that client. Allow the specific domain needed by the application rather than disabling all filtering permanently.

Updating and Managing Pi-hole

Before updating Pi-hole, download a configuration backup from Settings > Teleporter. Then run the update command on the Ubuntu host:

Terminal
sudo pihole -up

This updates Pi-hole’s components. It is different from pihole -g, which refreshes blocklist data.

For troubleshooting a website, you can temporarily turn off blocking for two minutes:

Terminal
sudo pihole disable 2m

Pi-hole resumes blocking automatically after the interval. To enable it sooner, run:

Terminal
sudo pihole enable

You can also watch incoming DNS requests from the terminal:

Terminal
sudo pihole tail

Press Ctrl+C to stop following the log. This requires query logging to be enabled.

Troubleshooting

Pi-hole cannot listen on port 53
Check sudo ss -lntup to identify the service holding the port and sudo journalctl -u pihole-FTL -b --no-pager for startup errors. The current installer handles the standard systemd-resolved stub listener, but another DNS service or a custom configuration may still conflict. Resolve the conflict, then restart Pi-hole with sudo systemctl restart pihole-FTL.

The admin page does not open
Use the URL printed by the installer and check sudo systemctl status pihole-FTL. If ports 80 or 443 were already in use, the web interface may be listening on another port, such as 8080. Check sudo ss -lntup and your firewall rules. Pi-hole v6 serves the dashboard through FTL, so restarting lighttpd will not fix it.

Direct DNS queries work, but clients still see ads
Check whether the client appears in Query Log. Renew its DHCP lease, remove unintended secondary DNS servers, and check IPv6 DNS, VPN settings, and browser secure DNS. On Ubuntu clients using systemd-resolved, run sudo resolvectl flush-caches to clear cached answers. Pi-hole cannot block ads served from the same domains as the content you want to keep.

DNS queries time out from another device
Check that the client can reach the Pi-hole address and that both TCP and UDP port 53 are allowed from its subnet. A guest Wi-Fi network may isolate devices. Pi-hole normally accepts queries from local subnets; routed VLANs may require a different listening mode under Settings > DNS, together with firewall rules restricting access to your trusted networks.

Blocklist downloads fail
Read the error next to the failed list in sudo pihole -g. Confirm that its URL still exists and that the host can resolve names. For certificate errors, check the system clock with timedatectl status and the installed CA certificates. Do not disable certificate verification to work around a failed download.

Conclusion

Once clients use Pi-hole for DNS, check the query log before adding more blocklists or changing settings. For a closer look at the DNS tests used here, see our guide to the dig command .

Linuxize Weekly Newsletter

A quick weekly roundup of new tutorials, news, and tips.

About the authors

Dejan Panovski

Dejan Panovski

Dejan Panovski is the founder of Linuxize, an RHCSA-certified Linux system administrator and DevOps engineer based in Skopje, Macedonia. Author of 1000+ Linux tutorials with 20+ years of experience turning complex Linux tasks into clear, reliable guides.

View author page