Encrypted Cloudflare DNS on UniFi
I wanted to ensure all my home network traffic was using encrypted DNS to a DNS provider I control, one with filtering and logging capabilities. I talked about the advantages and disadvantages of encrypted DNS a few years ago at Black Hat.
This is increasingly supported in various hardware and software, however it is still not natively supported in everything, and I also didn’t want to have to go around and configure every single device in my place. So I wanted to use traditional DNS in my home network but proxy it at my router, and convert upstream requests to an encrypted DNS protocol.
Proxies like this exist and can be pointed at just about any upstream provider, and more vendor-specific software also exists. But I had a couple of constraints1: Use Cloudflare’s Gateway product2, use their vendor-specific software, run this directly on my UniFi Dream Router (UDR), and I wanted to use their Cloudflare-specific proxy.
The UDR runs on a version of Debian – Cloudflare generally pushes for DNS proxying like this to be done with their WARP tool. However that tool appeared to only be available in binary form, and not compiled for the UDR’s aarch64
architecture. However I remembered that originally they advertised doing this with the cloudflared
tool which is available for aarch64
. It is rarely referenced as such in their documentation these days other than here. So it seems like even if it is officially supported, it’s not the recommended path.
But, I decided to go ahead – you can download the cloudflared binary and run it normally. So I enabled SSH on my UDR, and downloaded cloudflared
and put it in /root
. The UDR also uses systemd
to run services so I needed to make a configuration file so that it would run automatically.
First, I needed my Cloudflare Gateway DoH endpoint. I’d already signed up for a free tier Cloudflare account account, and logged into the Cloudflare One dashboard and grabbed the URL for DNS over HTTPS. This URL is specific to my deployment, so it’ll log and filter according to the rules I’ve set in my Gateway settings.
Once I had that, on the UDR I created the file /etc/systemd/system/cloudflare-dns-proxy.service
and added the relevant configuration details.
Once that file existed, I ran:
systemctl daemon-reload
systemctl enable cloudflare-dns-proxy.service
systemctl start cloudflare-dns-proxy.service
This will add the service, set it to run at boot, and go ahead and turn it on. The service will launch a DNS server running on 127.0.0.53
. That’ll be a local service that the UDR can access internally. From there I set that as the “upstream” DNS provider in the UDR’s Internet settings.
Once that’s done and the settings are saved and changes applied, the network should be encrypting all DNS traffic to Cloudflare! To verify, Cloudflare has a DNS test page, and so before you’re using Cloudflare it may look like this.
Afterwards, it should look like this!
For mobile devices such as my phone and laptop I use a combination of Firefox’s encrypted DNS settings and the WARP tool so that those devices always send DNS traffic to my Cloudflare Gateway account. THis means they usually skip my UDR’s system at home, but they’re getting the same filtering and logging regardless of what network they’re on.
You can also use this method to leverage other Cloudflare services such as Cloudflare Tunnels. I do that and will write that up at some point too.
I have not tested this, but this method should also work fine with other providers, such as NextDNS other excellent DNS provider with their own vendor tool.
Somewhat arbitrary ones to be honest. It was mostly about what made my life easiest the day I was working on this.