Configuring DNS-Over-HTTPS on RaspberryPi running Pi-Hole

In this article I will show you all the steps you will need to set up DNS-over-HTTPS to Cloudflared on a Raspberry Pi that’s running Pi-Hole on RaspBian Stretch OS. This is called an Argo Tunnel. Now you might think to yourself; What does all this even mean? Let me explain…

A Raspberry Pi is a really cheap tiny computer that has very low power consumption. These tiny computers costs between 30 to 50 euro’s/dollars and are ideal for people who often mess around with computers and everything related to it, like me for example. But they’re also interesting for people who want to keep their power consumption at home as low as possible, but still want certain services to run 24/7. I’m also one of those people. Especially when I saw my most recent electricity bill from the energy provider. It showed that I use more power than a family of five people averagely does. I live alone…

One of the reasons I want certain devices to run 24/7 is because they are hosting some services that I want to be available at all times. Like a DNS server for example. Pi-Hole is basically a DNS server that also blocks adds, for all the devices in your home network. Technically it’s actually not a DNS server but a local DNS resolver but that’s not important right now. I started using Pi-Hole about two years ago and nowadays my network feels incomplete without a Pi-Hole running in it. It also keep statistics that you can view in a simple web interface as shown below. Read more about it here.

pretty-stats
pretty-stats

Pi-Hole will resolve all DNS queries for every device in your home network. And to resolve queries and send the answer back to the clients Pi-Hole uses several upstream DNS server like 1.1.1.1 or 8.8.8.8. DNS queries from my Pi-Hole to the upstream DNS servers are not encrypted in any way. This means that my internet provider can monitor all these queries that I send out to the internet. In other words, they know what websites I visit and they monitor this and save the logs files for a certain amount of time. I’ve never really cared much about this, and I use VPN when I don’t want them to see what I’m doing. But with all the things that are going on right now in the realm of the world wide web, and with all the changes that have happened that I disagree with, I have become more aware of the benefits of securing as much as you can against preying eyes. Having said this just now, I started to nostalgically think back to the early days when the internet still felt like a playground for people like me, in anarchy, and it was completely free and it opened so many possibilities that we couldn’t even predict back then. Good days, good days. I miss those.

Recently I stumbled upon an article that explained the benefits of using HTTPS to secure DNS queries. This caught my interest so I did all the things the article suggested and within a couple of minutes a functional Pi-Hole with DNS-over-HTTPS was up and running. I figured that I might want to build this setup again at some point in the future, so I documented what I did, and since I was doing that, it was little effort to also post it here.

The upstream DNS servers we will be using are hosted by Cloudfare. They revolutionized the way we think of DNS when they went public on April fool’s day 2018, and their DNS servers are several times faster as the public Google DNS servers. I wrote something about this earlier that you might want to read also.

I’m assuming that you have already set up RaspBian on your Raspberry Pi yourself and that you are connected to the internet. I used RaspBian Lite but this works exactly the same on the full desktop version of RaspBian. Since I use the root account there’s no need for me to enter ‘sudo’ before the commands. So forgive me if I have forgotten to include sudo in some of the command-line instructions below. You should never use the root account but a regular account that has sudo rights. So if you see that a command is not working correctly for you, try it again but add sudo to the command.

We’re going to begin with the installation of Pi-Hole on a freshly new installed system. When this is running we install a tiny client-daemon from Cloudflare for the communication with the upstream DNS queries. I choose to use Cloudflare’s really fast servers 1.1.1.1 and 1.0.0.1, but you can use any of these servers that supports DNS over HTTPS. Eventually we will configure Pi-Hole and Cloudflared to work together hand in hand.

To continue reading the full article and the instructions, click on read more. Enough chatter, that barely anybody will read anyways, so let’s get started!

cd /tmp
wget -O basic-install.sh https://install.pi-hole.net
sudo bash basic-install.sh

Just follow all the steps of the installer and ask some simple questions. I’ve found that accepting all the defaults works good for me. Now it is very important to do a full reboot of the system before continuing or else you will encounter an issue later on. Afterwards you should be able to open the Pi-Hole control panel at this address:

cd /opt
wget https://bin.equinox.io/c/VdrWdbjqyF/cloudflared-stable-linux-arm.tgz
tar -xvzf cloudflared-stable-linux-arm.tgz
cp ./cloudflared /usr/local/bin
sudo chmod +x /usr/local/bin/cloudflared
cloudflared -v
useradd -s /usr/sbin/nologin -r -M cloudflared

We need to create a new file cloudflared and add the following line;

Sudo nano /etc/default/cloudflared

## args for cloudflared ##
## 5353 is localhost:5353. This is where dns queries are sent by pi-hole ##
## 1.1.1.1 and 1.0.0.1 are Cloudflare DNS servers ##
CLOUDFLARED_OPTS=--port 5353 --upstream https://1.1.1.1/dns-query --upstream https://1.0.0.1/dns-query

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

Now we’re going to create a file that allows cloudflared to run as a service. Create file /lib/systemd/system/cloudflared.service and enter what you see below.

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

[Unit]
Description=cloudflared DoH 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

Now we can enable and start the cloudflared service.

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

You should now be able to do a DNS query on port 5053 and see that it will resolve through the secured connection to a cloudflare DNS server. To test this use:

dig @127.0.0.1 -p 5053 google.com

Or when you run it on port 5353 try:

dig -p 5353 google.com @127.0.0.1

It should show you show you some results including the google ip address. Similar to what you see in the image below.

Now all we have to do is to change a setting in Pi-Hole to stop using the DNS servers it was using untill now and have it send it’s queries to the cloudflared service port that is running on the same device but a different port. Open the webpage that was presented to you when we installed Pi-Hole. In my case it was . Go to the settings page and open the DNS tab. Clear all the enabled servers and enter 127.0.0.1#5053 as only server as is shown in the screenshot.

dns-over-hhtps2

The very last thing to do is create/edit the file /etc/dnsmasq.d/50-cloudflared.conf  and add “server=127.0.0.1#5053”

sudo nano /etc/dnsmasq.d/50-cloudflared.conf

server=127.0.0.1#5053

or

server=127.0.0.1#5353

Now reboot your Raspberry Pi and your secure addblocker should be live. Next step for you will be to configure your clients to use our new DNS resolver as their primary DNS. Good luck and enjoy a life without adds!