DNS-Over-HTTPS (DoH) is a protocol for performing DNS lookups via HTTPS.
With regular DNS, requests are sent in plain-text, with no method to detect tampering.
This means that not only can a malicous actor look at all the DNS requests you are making,
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).
Nowadays in a lot of countries the ISP's have an obligation to record all traffic of their clients. Because more and more sites use HTTPS, it is impossible for ISP's to see which sites you visited. But because all DNS request are made in plain text, they still know what sites you looking at. Even if you don't use your ISP's DNS servers.
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. The DNS requests in your network are still in plain text, but as soon as it passes the Pi-Hole server it is transported via a secure tunnel to the Cloudflare DoH server.
I think it is good to know that there is another encryption method. DNS over TLS (DoT).
cloudflared(also known as argo-tunnel). In the following sections we will be covering how to install and configure this tool on Pi-hole.
wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-arm
sudo mv -f ./cloudflared-linux-arm /usr/local/bin/cloudflared
sudo chmod +x /usr/local/bin/cloudflared
Proceed to run the binary with the -v flag to check it is all working:
$ cloudflared -v
sudo useradd -s /usr/sbin/nologin -r -M cloudflared
Proceed to create a configuration file for cloudflared:
sudo nano /etc/default/cloudflared
Edit configuration file by copying the following in to /etc/default/cloudflared.
This file contains the command-line options that get passed to cloudflared on startup:
# Commandline args for cloudflared, using Cloudflare DNS
CLOUDFLARED_OPTS=--port 5053 --upstream https://1.1.1.1/dns-query --upstream https://1.0.0.1/dns-query
Update the permissions for the configuration file and cloudflared binary to allow access for the cloudflared user:
sudo chown cloudflared:cloudflared /etc/default/cloudflared
sudo chown cloudflared:cloudflared /usr/local/bin/cloudflared
sudo nano /etc/systemd/system/cloudflared.service
[Unit]
Description=cloudflared DNS over HTTPS proxy
After=syslog.target network-online.target
[Service]
Type=simple
User=cloudflared
EnvironmentFile=/etc/default/cloudflared
ExecStart=/usr/local/bin/cloudflared proxy-dns $CLOUDFLARED_OPTS
Restart=on-failure
RestartSec=10
KillMode=process
[Install]
WantedBy=multi-user.target
sudo systemctl enable cloudflared
sudo systemctl start cloudflared
sudo systemctl status cloudflared
$ dig @127.0.0.1 -p 5053 google.com
A response should be returned similar to the one below:
pi@raspberrypi:~ $ dig @127.0.0.1 -p 5053 google.com
; <<>> DiG 9.11.5-P4-5.1-Raspbian <<>> @127.0.0.1 -p 5053 google.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 12157
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: 22179adb227cd67b (echoed)
;; QUESTION SECTION:
;google.com. IN A
;; ANSWER SECTION:
google.com. 191 IN A 172.217.22.14
;; Query time: 0 msec
;; SERVER: 127.0.0.1#5053(127.0.0.1)
;; WHEN: Wed Dec 04 09:29:50 EET 2019
;; MSG SIZE rcvd: 77
127.0.0.1#5053
sudo cloudflared update
sudo systemctl restart cloudflared
sudo nano /etc/cron.weekly/cloudflared-updater
#!/bin/bash
sudo chmod +x /etc/cron.weekly/cloudflared-updater
sudo chown root:root /etc/cron.weekly/cloudflared-updater
The system will now attempt to update the cloudflared binary automatically, once per week.
The output must be something like the one below: