Pi-hole is awesome for blocking ads, but what if you want to encrypt your DNS queries too? That’s where DNS over HTTPS (DoH) with cloudflared comes in.
Let’s see Pi-hole talking to Cloudflare over DoH.
# On your Pi-hole machine
sudo apt update && sudo apt install cloudflared -y
# Configure cloudflared to listen on a local port
sudo tee /etc/cloudflared/config.yml > /dev/null <<EOF
proxy-dns: true
proxy-dns-upstream:
- https://1.1.1.1/dns-query
- https://1.0.0.1/dns-query
proxy-dns-port: 5353
EOF
sudo systemctl enable cloudflared
sudo systemctl start cloudflared
# Now, tell Pi-hole to use cloudflared
# Log into your Pi-hole web interface
# Go to Settings -> DNS
# Uncheck "Listen on all interfaces" if checked
# Check "Custom 1" (or any available custom upstream DNS server)
# In the text box next to "Custom 1", enter: 127.0.0.1#5353
# Click "Save"
Now, when your devices send DNS queries to Pi-hole, Pi-hole forwards them to cloudflared on port 5353. cloudflared then encrypts these queries using HTTPS and sends them to Cloudflare’s DoH resolver. The response comes back encrypted, cloudflared decrypts it, and sends it back to Pi-hole, which then forwards it to your device.
The primary problem this solves is privacy. Your ISP or anyone else on your local network can’t see which websites you’re visiting by snooping on your DNS traffic. It also prevents DNS hijacking and man-in-the-middle attacks on your DNS queries.
cloudflared acts as a local DoH client. It listens on a specified port (we used 5353) for incoming DNS requests. When it receives one, it formats it as a DoH request and sends it to an upstream DoH server (like Cloudflare’s https://1.1.1.1/dns-query). The upstream server processes the request and sends back an encrypted DNS response. cloudflared decrypts this response and sends it back to the original requester (in this case, Pi-hole).
The key configuration for cloudflared is in /etc/cloudflared/config.yml.
proxy-dns: true enables the DNS proxy functionality.
proxy-dns-upstream: lists the DoH servers cloudflared will use. We’ve included Cloudflare’s primary and secondary IPs for redundancy.
proxy-dns-port: 5353 is the local port cloudflared will listen on for DNS requests.
In Pi-hole, you point your "Custom upstream DNS server" to 127.0.0.1#5353. This tells Pi-hole to send its upstream DNS queries to the cloudflared service running on the same machine, on port 5353.
A common misconception is that DoH makes your entire internet traffic encrypted. This is false. DoH only encrypts the DNS queries themselves. The actual website traffic (HTTP/HTTPS) is handled separately by your browser or application. However, by encrypting DNS, you prevent eavesdroppers from knowing which domains you’re resolving, which is a significant privacy improvement.
The next step in enhancing your privacy and security is often exploring DNSSEC validation, which ensures the authenticity of DNS responses.