There’s a saying that goes: “Show me your friends, I’ll tell you who you are”. A slight variation of this is: “Show me the websites you visit, I’ll tell you who you are”. A lot can be learned about an individual just by examining the websites they visit, the search queries they run, and the apps they use on a regular basis. A trove of information about a user’s online activity can be gleaned from their DNS traffic. Have you ever wondered why practically all Internet Service Providers (ISPs) pre-configure consumer routers with their own DNS servers?
In this article, we’ll learned a bit about DoH with a quick refresher on DNS and how it works, and go over a few strategies to improve online privacy by securing DNS.
The Domain Name System (DNS) is the system used to identify computers on the internet. Computers can only communicate with one another if they know each other’s IP addresses. But IP addresses, which are basically a bunch of numbers bundled together, are hard to memorize. If we had to use IP addresses to access websites, the web wouldn’t have taken off the way it did and you wouldn’t be reading this article online today. DNS was invented to accommodate humans, not machines.
Every time you type a URL in the browser, it issues a DNS a query to your DNS server in order to resolve the IP address of the website you’re trying to visit. The same thing happens when you open an app on your mobile device, when your smart light bulb phones home to fetch the most up-to-date brightness level it should shine at, and when you add a new show to your list on your smart TV Netflix app. Basically, every single action you make online triggers one or more DNS queries.
However, DNS was not built with privacy in mind. All DNS queries are routed through the internet in plain text. This means that anyone sniffing traffic on a network, or acting as a proxy to the internet, like an ISP or an enterprise router, can see the web locations that everyone on that network is visiting. While watching DNS traffic alone doesn’t give out information about the interactions between a client and a given website, it does paint a detailed picture of the web locations that a user has visited, an estimate of how long they have been on each website, the apps they’re using, and the type of Internet-of-Thing (IoT) devices they have installed in their homes, if any. It goes without saying that this is extremely detrimental to one’s online privacy. Fortunately, there are solutions to this problem.
One way of protecting one’s DNS queries from snooping eyes is to use encryption, like with DNS over TLS (DoT) or DNS over HTTPS (DoT). In this article we’ll focus on DoH which routes DNS traffic in an encrypted HTTPS tunnel. The client establishes a secure connection with the DNS server and funnels all DNS queries through it. This effectively encrypts DNS communications and renders them inaccessible to spying third parties. Now, let’s explore a few options of leveraging DoH to protect online activities1 and improve privacy.
Many browsers2 nowadays offer the option to configure a custom DoH server. However, this kind of configuration only applies to the activity happening in the browser and as mentioned previously, not all web requests originate from a browser. If we want to protect all DNS traffic emerging from a network, say a user’s home network, we should configure the network to use a local DNS server under our control that will turn around and delegate DNS resolution to a trusted upstream provider using DoH. First, let’s see how we can build this local DNS server.
Local DNS Server
Cloudflare built a nice little application called
cloudflared that converts
plain DNS queries to DoH. It’s free, open-source and easy to run. If you’ve
read any other post on this blog you must’ve realized how much I love
containers. So let’s build a
cloudflared Docker image to run as a local DNS
server. Unfortunately, Cloudflare doesn’t offer an official Docker image for
cloudflared but we can make our own fairly easily. To do so, in a file named
Dockerfile put the following content:
FROM alpine:3.15 RUN apk add --no-cache bash RUN wget -q https://github.com/cloudflare/cloudflared/releases/download/2022.1.2/cloudflared-linux-arm \ && chmod +x cloudflared-linux-arm \ && mv /cloudflared-linux-arm /usr/local/bin/cloudflared
Here, we’re using
alpine version 3.15 and
cloudflared version 2022.1.2 but
more versions might have been released since this article was published. Feel
free to update these versions to the latest.
In order to use this Docker image we can build a
docker-compose service to run
cloudflared. Alongside the previously created
Dockerfile, let’s make a new
docker-compose.yml with this content:
version: "3.8" services: cloudflared: build: . ports: - "53:5053" # replare <UPSTREAM SERVER> with the URL for the upstream DoH server # e.g.: https://doh.libredns.gr/dns-query entrypoint: bash -c "cloudflared proxy-dns --port 5053 --address 0.0.0.0 --upstream <UPSTREAM SERVER>" restart: unless-stopped
Make sure to replace
<UPSTREAM SERVER> in the
entrypoint command with your
DoH server of choice. PrivacyGuides lists a few options
you can pick from if you don’t already have a favourite DNS server. At this
point, you have everything you need to convert all DNS queries in your network
into DoH. Here are the steps to accomplish this:
docker-compose up cloudflaredfrom the folder where you put the
docker-compose.ymlfiles to spin up a
cloudflaredcontainer. Ideally, this should be done on a machine that’s constantly running on your network with a static IP address. A Raspberry Pi or a home server are great candidates for this.
- Configure your network’s DHCP server to use the machine where
cloudflaredis running as its default DNS server. This will automatically instruct all devices on the network to use the
cloudflaredcontainer for DNS resolution. If you don’t have control over your DHCP server, or it’s too complicated to reconfigure at the moment, you can always start off by manually editing the DNS configuration on your most-used devices.
DoH in Pihole
If you already have a Pihole docker container running in your network and
serving DNS queries, you can now set the
cloudflared container as an upstream
DNS server in Pihole and automatically upgrade all DNS queries to DoH. We’ve
seen in a previous article how to set up Pihole using Docker. We’ll use the same
docker-compose file here to illustrate how to integrate
First we need to place the
Dockerfile file we created in the previous section
inside a folder called
cloudflared. Then, using our previous Pihole
docker-compose file, we can add a new service for
cloudflared as shown
version: "3.8" services: pihole: # ... environment: # ... - PIHOLE_DNS_=172.31.0.200#5350 # ... depends_on: - cloudflared - dhcphelper # ... dhcphelper: # ... cloudflared: build: ./cloudflared environment: # set UPSTREAM_PROVIDER to the URL for the upstream DOH server # e.g.: https://doh.libredns.gr/dns-query - UPSTREAM_PROVIDER= entrypoint: bash -c "cloudflared proxy-dns --port 5053 --address 0.0.0.0 --upstream $$UPSTREAM_PROVIDER" networks: backend: ipv4_address: '172.31.0.200' restart: unless-stopped networks: # ... volumes: # ...
You’ll notice that the
cloudflared service looks similar to the one we built
in the previous section. Here, we don’t need to expose the port 53 to the host
because the only client connecting to the
cloudflared container is the Pihole
container running in the same Docker network. Also, we have to set a static IP
address for the
cloudflared container and add it to the
environment variable of Pihole in order for it to be used as an upstream DNS
With the modifications above, restart your Pihole container by running
docker-compose down and bringing it back up with
docker-compose up pihole,
and you should have a
cloudflared container running alongside Pihole, ready to
Congratulations, you made it! You now understand why protecting your DNS traffic
is paramount to improving your online privacy and have in your toolbox 3
strategies for doing so, some more potent than others. In case you can’t run a
full-fledged Pihole and
cloudflared setup on your network, or don’t have the
time to set that up yet, at least configure your most-frequently-used browser to
resolve DNS through DoH. It takes almost no time, and goes a long way in getting
you to a better place when it comes to your online privacy.