Pi-hole DNS-over-HTTPS using Cloudflared

The problem:


This tutorial is for educational purposes only!

Even if you are visiting a site using HTTPS, your DNS query is sent over an unencrypted connection. That means that even if you are browsing https://cloudflare.com, anyone listening to packets on the network knows you are attempting to visit cloudflare.com.
The second problem with unencrypted DNS is that it is easy for a Man-In-The-Middle to change DNS answers to route unsuspecting visitors to their phishing, malware or surveillance site. DNSSEC solves this problem as well by providing a mechanism to check the validity of a DNS answer, but only a single-digit percentage of domains use DNSSEC.
To combat this problem, Cloudflare offers DNS resolution over an HTTPS endpoint. If you build a mobile application, browser, operating system, IoT device or router, you can choose for your users to use the DNS over HTTPS endpoint instead of sending DNS queries over plaintext for increased security and privacy of your users.
— https://developers.cloudflare.com/

I assume that you have installed Pi-hole on your system and want to use cloudflare’s DNS-over-HTTPS client to secure* the network. * If you trust cloudflare.
This article is based on the official Pi-hole guide on ‘Configuring DNS-Over-HTTPS on Pihole’ (https://docs.pi-hole.net/guides/dns-over-https/).
Read that article for the complete and updated information about DoH on Pi-hole.

This are the commands needed to configure DoH on Pi-Hole.

Install cloudflared:
The download links can be found here: https://developers.cloudflare.com/argo-tunnel/downloads/

If you are using ARM CPU, open up terminal session and execute the following (do not include $):

$ wget -c https://bin.equinox.io/c/VdrWdbjqyF/cloudflared-stable-linux-arm.tgz
$ tar -xvzf cloudflared-stable-linux-arm.tgz
$ sudo cp ./cloudflared /usr/local/bin
$ sudo chmod +x /usr/local/bin/cloudflared  

$ sudo useradd -s /usr/sbin/nologin -r -M cloudflared

Create a new file and add the configuration of cloudflared:

$ sudo nano /etc/default/cloudflared

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

Change the permissions to cloudflared from root:

$ sudo chown cloudflared:cloudflared /etc/default/cloudflared
$ sudo chown cloudflared:cloudflared /usr/local/bin/cloudflared

Create a systemd service configuration:

$ sudo nano /lib/systemd/system/cloudflared.service

Description=cloudflared DNS over HTTPS proxy
After=syslog.target network-online.target

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


Enable and start cloudflared systemd service:

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

Test DoH:

$ dig @ -p 5053 cloudflare.com

; <> DiG 9.10.3-P4-Raspbian <> @ -p 5053 cloudflare.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 46075
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

; EDNS: version: 0, flags:; udp: 1452
;cloudflare.com.			IN	A

cloudflare.com.		232	IN	A
cloudflare.com.		232	IN	A

;; Query time: 203 msec
;; WHEN: Fri Feb 15 09:02:26 PST 2019
;; MSG SIZE  rcvd: 103

Change Pi-hole’s upstream DNS:
Login to your Pi-hole admin site, go to the settings > DNS, uncheck the DNS servers and add a custom DNS with the value

Click save and logout.

If you did not activate the web interface, just login to SSH and edit the ff. files, remove the other DNS server or replace with:

$ sudo nano /etc/pihole/setupVars.conf

$ sudo nano /etc/dnsmasq.d/01-pihole.conf

Restart pi-hole and dnsmasq:

$ sudo pihole restartdns

Here are the output of the commands:

$ wget -c https://bin.equinox.io/c/VdrWdbjqyF/cloudflared-stable-linux-arm.tgz
Resolving bin.equinox.io (bin.equinox.io)...,,, ...
Connecting to bin.equinox.io (bin.equinox.io)||:443... connected.
HTTP request sent, awaiting response... 200 OK                          
Length: 8128269 (7.8M) [application/octet-stream]                     
Saving to: ‘cloudflared-stable-linux-arm.tgz’                                                  
cloudflared-stable-linux 100%[================================>]   7.75M   390KB/s    in 51s
2019-02-12 21:12:46 (157 KB/s) - ‘cloudflared-stable-linux-arm.tgz’ saved [8128269/8128269]

$ tar -xvzf cloudflared-stable-linux-arm.tgz

$ sudo cp ./cloudflared /usr/local/bin

$ cloudflared -v
cloudflared version 2019.2.0 (built 2019-02-11-2010 UTC)    

$ sudo systemctl enable cloudflared
Created symlink /etc/systemd/system/multi-user.target.wants/cloudflared.service → /lib/systemd/system/cloudflared.service.

$ sudo systemctl start cloudflared

$ sudo systemctl status cloudflared
● cloudflared.service - cloudflared DNS over HTTPS proxy
   Loaded: loaded (/lib/systemd/system/cloudflared.service; enabled; vendor preset: enabled)
   Active: active (running) since Thu 2019-02-12 21:15:08 PST; 295ms ago
 Main PID: 6551 (cloudflared)
   CGroup: /system.slice/cloudflared.service
           └─6551 /usr/local/bin/cloudflared proxy-dns --port 5053 --upstream

Feb 12 21:15:08 raspbian systemd[1]: Started cloudflared DNS over HTTPS proxy.
lines 1-8/8 (END)



Except where otherwise noted, this work is licensed under Creative Commons Attribution-ShareAlike 4.0 International License (http://creativecommons.org/licenses/by-sa/4.0/).
I hope that this post is useful to you, if you liked this post you may support me via liberapay or patreon. Thank you for your support.