Pi-hole with dns-over-https

In the previous blog entry [Pi-hole with DNS-over-TLS] I set up stubby for dns-over-tls on the pi-hole. I want to do the same now for DNS-over-HTTPS (DoH), but neither Stubby nor Unbound support the young protocol which answers DNS queries via HTTPS. Some browsers have now integrated DoH, but I would like to protect all DNS queries from my home network. Therefore I use the client of cloudflare written in Go: cloudflared.

More about the pi-hole and installation instructions can be found here:

Installation

Basically there is an existing documentation at pi-hole.net how to set up DNS-over-HTTPS with cloudflared, but I would like to optimize the installation for me so that I can use multiple clients at the same time.
cloudflared can be downloaded at Cloudflare as binary and is ready for use after a small configuration.

On the Raspberry Pi:

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

For the service we use our own user:

sudo useradd -s /usr/sbin/nologin -r -M cloudflared
sudo chown cloudflared:cloudflared /usr/local/bin/cloudflared # auto-update the binary

Configuration

Your DNS Choose
Carefully choose your DNS provider because you are exposing your data to it. Who you trust is your decision.
There are many alternatives and probably better options than Quad9.

Cloudflare also offers DNS-over-HTTPS, but I would rather use the service of Quad9, so I use the IP 9.9.9.9 as upstream.

sudo vi /lib/systemd/system/cloudflared.service

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

[Service]
Type=simple
User=cloudflared
ExecStart=/usr/local/bin/cloudflared proxy-dns --address 127.0.3.3 --port 5353 --upstream https://9.9.9.9/dns-query
Restart=on-failure
RestartSec=10
KillMode=process

[Install]
WantedBy=multi-user.target

And activate and restart the restart service:

sudo systemctl daemon-reload
sudo systemctl enable cloudflared
sudo systemctl start cloudflared

To make the pi-hole statistics easier to see which DNS queries are now answered via stubby or unbound or cloudflared, the IP of the service can be entered in /etc/hosts. Thus cloudflared appears instead of 127.0.3.3. The same, can of course, be done for all other clients.

echo "127.0.3.3 cloudflared" >> /etc/hosts

The active cloudflared service can now be configured in the pi-hole as custom DNS server. To do this, enter the local IP of the service and the port of the service under “Settings > DNS” for Upstream DNS Servers under “custom”: e.g. 127.0.3.3#5353.
After saving, the pi-hole should now forward DNS requests that are not cached or blocked to cloudflared:

Query Client Service Names

Test

pi@pi-hole:~ $ dig @127.0.3.3 -p 5353 blog.sandchaschte.ch

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

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;blog.sandchaschte.ch.		IN	A

;; ANSWER SECTION:
blog.sandchaschte.ch.	900	IN	CNAME	sandchaschte.ch.
sandchaschte.ch.	900	IN	A	159.100.248.212

;; Query time: 245 msec
;; SERVER: 127.0.3.3#5353(127.0.3.3)
;; WHEN: Fri Jan 18 15:54:23 UTC 2019
;; MSG SIZE  rcvd: 129

It works. ๐ŸŽ‰

Maybe I’ll do an evaluation which of the clients (Unbound with DoT, Stubby with DoT or Cloudflared with DoH) has a better performance, so I can continue surfing fast as possible ๐Ÿ™‚.