How to Set Up Pi-hole DNS-over-HTTPS on Ubuntu Server 24.04

For Pi-hole on Ubuntu Server 24.04, route its upstream requests through dnscrypt-proxy and point Pi-hole to the local listener at 127.0.0.1#5053. This encrypts DNS traffic between your server and the selected upstream resolver with DNS-over-HTTPS (DoH), while Pi-hole continues to answer your LAN clients and apply its blocklists. Pi-hole itself does not provide DoH transport to its upstream by default; the local proxy supplies that encrypted connection.

There is a current-version detail to know first: Cloudflare removed the cloudflared proxy-dns command from new releases starting February 2, 2026. Older tutorials that install that command may not work with a current cloudflared release. The steps below use dnscrypt-proxy, following Pi-hole’s current DoH guide. This setup is suitable when Pi-hole and the proxy run on the same Ubuntu host. A Docker or multi-host setup needs different listener addressing and firewall rules.

What this setup does and what it does not do

Normal DNS usually sends queries from your resolver to an upstream DNS provider without transport encryption. DoH carries DNS requests inside HTTPS, making it harder for a network observer between your Pi-hole server and the resolver to read or alter those requests. Pi-hole remains the DNS server advertised to devices on your local network; only its upstream path changes.

DoH does not make DNS activity invisible to the resolver you choose. The upstream provider still receives queries from your server, and Pi-hole may retain client query history according to its privacy and logging settings. HTTPS also does not encrypt unrelated web traffic. If your goal is to use a particular resolver, check its privacy policy and choose its DoH entry from the supported resolver list.

Before you begin

  • Confirm that Pi-hole is already installed and working on Ubuntu Server 24.04. This walkthrough configures an existing Pi-hole rather than installing it.
  • Make sure the server has a stable LAN address. If the address changes, router DHCP clients may lose their DNS server.
  • Have administrator access and a way to reach the Pi-hole host if DNS temporarily stops working. Avoid making this change remotely over a connection that depends on the same Pi-hole for name resolution.
  • Record the current Pi-hole upstream settings so you can restore them during rollback.

The proxy will bind only to loopback on port 5053, leaving port 53 for Pi-hole. This avoids competing with Pi-hole’s DNS service and Ubuntu’s local resolver. Do not disable systemd-resolved just to make this design work; the proxy’s separate loopback port avoids that conflict.

1. Install dnscrypt-proxy from Ubuntu’s package repositories

The dnscrypt-proxy project documents an Ubuntu package installation route. Check that your configured Ubuntu repositories offer a candidate before installing:

sudo apt update
apt-cache policy dnscrypt-proxy

If the output shows a candidate version, install it:

sudo apt install dnscrypt-proxy

If no candidate is shown, do not add an unrelated third-party repository just to proceed. Use the installation method linked from the dnscrypt-proxy project’s official Linux guide, verify the release and architecture, and adapt the service setup to that installation. The systemd socket unit and configuration paths below apply to the Ubuntu package setup documented by Pi-hole.

2. Move the proxy listener to localhost port 5053

Pi-hole already uses the standard DNS port 53. Configure the proxy’s socket to listen on both TCP and UDP at 127.0.0.1:5053, reachable only from the same host. Create a systemd drop-in:

sudo systemctl edit dnscrypt-proxy.socket

Enter these lines in the editor and save:

[Socket]
ListenStream=
ListenDatagram=
ListenStream=127.0.0.1:5053
ListenDatagram=127.0.0.1:5053

The empty ListenStream= and ListenDatagram= lines clear the package defaults before setting the replacement addresses. Do not omit them: systemd can otherwise keep the default port in addition to the custom listener.

3. Select a DoH resolver

Open the package configuration file:

sudoedit /etc/dnscrypt-proxy/dnscrypt-proxy.toml

For systemd socket activation, use an empty listener list in the proxy configuration. Choose a resolver name from the current signed public resolver list. For example, the following selects the standard Cloudflare resolver; the Pi-hole guide also shows cloudflare-security as an example when malware filtering at the upstream resolver is wanted:

listen_addresses = []
server_names = ['cloudflare']

Keep the rest of the package’s configuration intact. The names in server_names are registry identifiers, not arbitrary hostnames or URL paths. If you prefer another provider, verify that its current resolver entry supports DoH and copy its exact name. A resolver that filters malware or other categories may produce different results from an unfiltered resolver.

4. Point Pi-hole to the local proxy

Set Pi-hole’s upstream DNS address to the local listener:

sudo pihole-FTL --config dns.upstreams '["127.0.0.1#5053"]'

The #5053 suffix is Pi-hole’s notation for the nonstandard DNS port. You can also check the Pi-hole Admin interface under Settings > DNS. Clear the preset public upstream selections and leave the custom server 127.0.0.1#5053 as the upstream. Keeping a public resolver checked as an additional upstream can allow queries to bypass the encrypted proxy, so remove those entries if you require all Pi-hole upstream queries to use DoH.

5. Restart the services and verify resolution

Restart the socket, proxy service, and Pi-hole FTL daemon so they load the new configuration:

sudo systemctl restart dnscrypt-proxy.socket
sudo systemctl restart dnscrypt-proxy.service
sudo systemctl restart pihole-FTL.service

Review service status:

sudo systemctl status dnscrypt-proxy.socket
sudo systemctl status dnscrypt-proxy.service
sudo systemctl status pihole-FTL.service

Each should be active without a bind error or resolver startup failure. Test the proxy directly over its local DNS listener:

dig @127.0.0.1 -p 5053 example.com

A DNS answer indicates that the local proxy is responding. Then test Pi-hole on port 53:

dig @127.0.0.1 example.com

Check the Pi-hole Query Log or dashboard to confirm the request reached Pi-hole, and review the proxy’s journal if the test fails:

sudo journalctl -u dnscrypt-proxy.service -b --no-pager

For an extra check, look in the proxy startup or journal output for the selected resolver and a DoH protocol status. A successful dig alone proves that DNS resolution works; it does not, by itself, prove that the request used HTTPS.

Common issues and safe recovery

  • “Address already in use”: another process may already occupy port 5053, or the socket override was not loaded. Check listeners with sudo ss -lntup, review the drop-in with systemctl cat dnscrypt-proxy.socket, and confirm that the empty reset lines precede the 5053 entries.
  • Proxy is active but lookups time out: check outbound HTTPS access, the resolver name, and the proxy logs. Some networks block DNS-over-HTTPS connections or restrict TCP port 443.
  • Proxy test works but Pi-hole has no upstream response: confirm Pi-hole is set to exactly 127.0.0.1#5053, then restart pihole-FTL. Make sure the standard upstream checkboxes are not silently providing an alternate route.
  • Ubuntu itself cannot resolve names after the change: this setup changes Pi-hole’s upstream, not the host’s /etc/resolv.conf. Avoid replacing that file or disabling systemd-resolved as a troubleshooting shortcut.

For rollback, restore the upstream DNS setting you recorded in Pi-hole and restart pihole-FTL. Once Pi-hole no longer points to the proxy, you can disable or remove dnscrypt-proxy using the package manager. If this server also resolves its own DNS through Pi-hole, keep a local recovery path available before changing services.

Which option fits your network?

Use this single-host proxy arrangement when you want centralized DNS filtering in Pi-hole and encrypted traffic from Pi-hole to one selected resolver. It is relatively easy to inspect because the proxy has one local address and port. If you run Pi-hole in Docker, on another server, or across multiple networks, you may need a container-network address rather than loopback, and you must restrict the proxy listener so it is not exposed as an open resolver. If you need policy-based filtering, per-device identity, or encrypted DNS for roaming devices outside the home, configure those clients or a managed gateway separately; Pi-hole’s upstream DoH connection does not automatically encrypt each client’s path to Pi-hole.

Finally, remember that a router or client can bypass Pi-hole if it advertises a second DNS server. For network-wide filtering, give clients only the Pi-hole address through DHCP and account for IPv6 DNS advertisements as well as IPv4. Verify with multiple devices after changing router settings, since a correct proxy setup on the server cannot prevent a client from using another resolver directly.

Official references

Leave a Comment

How to Record Speaker Output on Linux with Audacity

How to Record Speaker Output on Linux with Audacity

Capture Linux desktop audio in Audacity by routing its recording stream to your output device’s monitor source. Follow PulseAudio and PipeWire steps, export tips, and fixes for silent tracks.

How to Use Dropbox on Linux: Install and Sync Your Files

How to Use Dropbox on Linux: Install and Sync Your Files

Install Dropbox on Linux from the official package, sign in, sync a local folder, manage selective sync, and check status from the command line.

How to Install Inkscape on Linux: Ubuntu, Fedora, Arch, and More

How to Install Inkscape on Linux: Ubuntu, Fedora, Arch, and More

Install Inkscape from your Linux distribution’s repositories, the Ubuntu stable PPA, Snap, or Flathub, with current commands and notes for choosing a package source.

How to Find and Remove Duplicate Files on Linux With FSlint

How to Find and Remove Duplicate Files on Linux With FSlint

Use FSlint to scan selected Linux folders, review duplicate groups, and safely delete redundant files or learn when hard-link merging is appropriate.

How to Install SABnzbd on Linux and Configure It

How to Install SABnzbd on Linux and Configure It

Install SABnzbd on Ubuntu or Debian, or run it in Docker on another Linux host. Then open the web interface and configure your provider and download folders.

How to Install the Paper GTK Theme on Linux

How to Install the Paper GTK Theme on Linux

Install the Paper GTK theme from supported Linux repositories, enable it for GTK apps in GNOME Tweaks, and see what the legacy theme can and cannot change.

How to Install and Set Up Plex on OpenMediaVault with Compose

How to Install and Set Up Plex on OpenMediaVault with Compose

The old OpenMediaVault Plex plugin is archived. Set up Plex on OMV 8 with OMV-Extras, the Compose plugin, persistent storage, and Plex’s official container.

How to Clean and Speed Up Ubuntu Safely

How to Clean and Speed Up Ubuntu Safely

Clean and speed up Ubuntu with safe APT cleanup, storage checks, and startup controls that help free space and troubleshoot a sluggish desktop.

How to Install the Hiri Email Client on Linux

How to Install the Hiri Email Client on Linux

Install Hiri on Linux with its Snap package or official tarball, add a desktop launcher, and check supported accounts plus a warning about Hiri’s old Snap release.

How to Get System Specifications for a Linux PC

How to Get System Specifications for a Linux PC

Use Fastfetch and built-in Linux commands to check your distro, kernel, CPU, memory, graphics, storage, and connected devices, then save a clear report.