Cloudflare Service

It is the 1st of April, 2018. The people have awoken, ready to discover the most cringeworthy April Fools day “jokes” from the usual tech giants. It looks like Cloudflare has decided to join in this year – “Secure, privacy focused, incredibly fast DNS? Who are they trying to fool?”

But alas, it was not a joke.

Cloudflare have released, which completely blows away all previous attempts at a global DNS service out of the water.

  • It is super fast (in my location it is 40x faster than Google’s DNS).
  • It is privacy focused, writing no query data to disk and wiping all logs every 24 hours (Google sells DNS data for the purposes of advertising)
  • It supports a myriad of DNS options such as DNSSEC, DNS-over-TLS and DNS-Over-HTTPS, all of which are much more secure and reduce the potential for your ISP or other entities to snoop on your data.

What is DNS-Over-HTTPS?

DNS-Over-HTTPS is a protocol for performing DNS lookups via the same protocol you use to browse the web securely: HTTPS. (If you are not aware of what DNS is, please read this primer before continuing).

With regular DNS, requests are sent in plain-text, with no method to detect tampering or misbehaviour. This means that not only can a malicous actor look at all the DNS requests you are making (and therefore what websites you are visiting), they can also tamper with the response and redirect your device to resources in their control (such as a fake login page for internet banking).

DNS-Over-HTTPS prevents this by using standard HTTPS requests to retrieve DNS information. This means that the connection from the device to the DNS server is secure and can not easily be snooped, monitored, tampered with or blocked.

Configuring DNS-Over-HTTPS

As part of releasing, Cloudflare implemented DNS-Over-HTTPS proxy functionality in to one of their tools: cloudflared, also known as argo-tunnel.

In the following sections we will be covering how to install and configure this tool on PiHoleDebian/RHEL/Fedora devices which use dnsmasq forwarding.

PiHole and Linux

NOTE: I have created an Ansible Role and sample playbook that can be used to automate the following steps. Please find links below:

Installing cloudflared

The installation is fairly straightforward, however be aware of what architecture you are installing on (amd64 or arm).

AMD64 architecture (most devices)

Download the installer package, then use apt-get to install the package along with any dependencies. Proceed to run the binary with the -v flag to check it is all working.

sudo apt-get install ./cloudflared-stable-linux-amd64.deb
cloudflared -v

ARM architecture (Raspberry Pi)

Here we are downloading the precompiled binary and copying it to the /usr/local/bin/ directory to allow execution by the cloudflared user. Proceed to run the binary with the -v flag to check it is all working.

tar -xvzf cloudflared-stable-linux-arm.tgz
cp ./cloudflared /usr/local/bin
chmod +x /usr/local/bin/cloudflared
cloudflared -v

Configuring cloudflared to run on startup

It is good practice to have a configuration file to contain options. Proceed to create a configuration file by copying the following in to /etc/default/cloudflared. This contains the command-line options that get passed to cloudflared on startup.

# Commandline args for cloudflared
CLOUDFLARED_OPTS=--port 5053 --upstream --upstream

Then create the systemd script by copying the following in to /lib/systemd/system/cloudflared.service. This will control the running of the service and allow it to run on startup.

Description=cloudflared DNS over HTTPS proxy

ExecStart=/usr/local/bin/cloudflared proxy-dns $CLOUDFLARED_OPTS


Enable the systemd service to run on startup, then start the service and check its status.

sudo systemctl enable cloudflared
sudo systemctl start cloudflared
sudo systemctl status cloudflared

Now test that it is working! Run the following dig command, a response should be returned similar to the one below

; <<>> DiG 9.9.5-9+deb8u15-Debian <<>> @localhost -p 554
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 37242
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

; EDNS: version: 0, flags:; udp: 1452
; IN A


;; Query time: 36 msec
;; WHEN: Wed Jul 18 12:18:44 WIB 2018
;; MSG SIZE rcvd: 65

Configuring DNS

If you have gotten to this point, you now have a working DNS-over-HTTPS service. But unfortunately, it’s only running locally on the device. The next steps will cover how to implement the service for network-wide DNS lookups via PiHolednsmasq or direct.

PiHole and dnsmasq

Create a file /etc/dnsmasq.d/50-cloudflared.conf and fill it with the following:


Look through all other files within the /etc/dnsmasq.d/ directory, and add a # in front of any lines starting with server=, like so


This step does not need to be completed if you are not using Pihole. PiHole will automatically regenerate the dnsmasq configuration files when reloaded. To prevent this from conflicting with our manually made changes, we can edit the PiHole configuration file and remove all references to DNS servers. To do this, open /etc/pihole/setupVars.conf in an editor and add a # in front of any lines starting with PIHOLE_DNS, like so


After restarting Dnsmasq (and PiHole if applicable), queries should now be fulfilled using the Cloudflare DNS service. This can be verified by visiting the DNSSEC test service.

Original Posting from