CODEX

Pi-Hole and DNS over HTTPS

Scott Jones
CodeX
Published in
5 min readJan 22, 2021

--

Photo by Philipp Katzenberger on Unsplash

The technical landscape recently has been all about security and the protection of data. You will have noticed that most websites now run solely over HTTPS. But did you know that people can still track what you do by looking at your DNS queries? Today we take a look at what DNS over HTTPS is, why you need it, and how you can set it up.

What is DoH?

DNS over HTTPS (DoH) is a protocol for performing remote Domain Name System (DNS) resolution via the HTTPS protocol (Wikipedia)

DoH leverages the same encryption afforded to data transfer between you and websites which secures all of your data. It is backed by the same trusted certificate chains and protects against the same attacks.

Why do I need DoH?

To answer this, let's take a look at the potential problems for regular DNS.

Data Protection —We’ve already touched on this in this article, but given DNS queries are essentially plain text, they are visible to any node they pass through on the way to and from the destination DNS server. Your ISP knows what you are looking to, any switch or router along the chain has the capability to inspect the contents and log it. Perhaps you are not one that cares about this, but there are many people nowadays that really want to have control over who sees anything about them. DNS over HTTPS ensures that all contents about what you are requesting and the response you get is secured and safe from prying eyes.

DNS Spoofing — As described by Imperva:

Domain Name Server (DNS) spoofing (a.k.a. DNS cache poisoning) is an attack in which altered DNS records are used to redirect online traffic to a fraudulent website that resembles its intended destination.

This attack leaves people open to further attack such as stealing credentials or installing malicious software. This can be accomplished by either exploiting flaws in a providers DNS software or by performing a man-in-the-middle attack and getting their own DNS server in your upstream chain. While we can’t help upstream servers defend themselves, by utilising HTTPS we can prevent against the MITM attack by verifying identity and encrypting payloads.

DNS Manipulation — Aside from cache poisoning, there are other reasons you may get modified results. As an example, ISP censorship often revolves around either the blocking or manipulation of certain DNS results. You quite often have no way of knowing what you are receiving has been modified. As Richard Chirgwin says in The Register:

DOH’s encryption (via HTTPS) hides the traffic from the provider, on a port the ISP can’t block.

This means you know what you get has not been tampered with, and you know the service will not be removed by your ISP.

How Can I Use DoH?

If you’ve gotten this far, you are sold on the need for DoH, at least for your personal circumstances. I’m now going to show you how you can set up your own DoH server for your network. This is going to be on a Kubernetes cluster, so please make sure you have one before trying to follow the instructions. If you have a couple of RPi’s lying around you would be willing to run Kubernetes on, drop into my series on getting a RPi K3S cluster setup.

The image we are going to be using for this is one that I have built. You can take a look at the docker image over at https://hub.docker.com/r/scottjones4k/pihole-doh as well as the source code for it at https://github.com/scottjones4k/pihole-doh. As a matter of principle I suggest for this- and any other container you want to run on your system- that you take a look at what is actually happening in them. It is very easy for someone to get something nefarious in images and into peoples clusters.

The first thing you want to do is to create your pihole.yaml:

apiVersion: v1
kind: Namespace
metadata:
name: pihole
labels:
app: pihole
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: pihole
namespace: pihole
labels:
app: pihole
spec:
replicas: 1
selector:
matchLabels:
app: pihole
template:
metadata:
labels:
app: pihole
name: pihole
spec:
containers:
- name: pihole
image: scottjones4k/pihole-doh:latest
imagePullPolicy: Always
env:
- name: TZ
value: "Europe/London"
- name: WEBPASSWORD
value: "<<YOURSECRETPASSWORD>>"
- name: DNS1
value: "127.1.1.1#5153" #DoH
- name: DNS2
value: "127.1.1.1#5153" #DoH
---
apiVersion: v1
kind: Service
metadata:
name: pihole
namespace: pihole
spec:
selector:
app: pihole
ports:
- port: 80
name: pihole-admin
protocol: TCP
targetPort: 80
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: pihole-route
namespace: pihole
spec:
entryPoints:
- websecure
routes:
- match: Host(`pihole.yourdomainhere.com`)
kind: Rule
services:
- name: pihole
port: 80
tls:
certResolver: cloudflare
---
apiVersion: v1
kind: Service
metadata:
name: pihole-dns-tcp
namespace: pihole
spec:
type: LoadBalancer
selector:
app: pihole
ports:
- port: 53
targetPort: 53
protocol: TCP
name: dns-tcp
externalIPs:
- <<YOUR-DNS-IP>>
---
apiVersion: v1
kind: Service
metadata:
name: pihole-dns-udp
namespace: pihole
spec:
type: LoadBalancer
selector:
app: pihole
ports:
- port: 53
targetPort: 53
protocol: UDP
name: dns-udp
externalIPs:
- <<YOUR-DNS-IP>>

The above yaml file contains a few key items.

The Deployment section contains a web password setting that you need to put your own password in. This is the password used when viewing the web interface. It also specifies DNS1 & 2 as going to 123.0.0.1#5153 . This is where the container image is running cloudflared (the local DoH services which proxies through to the Cloudflare DoH servers). This means anything not resolved by Pi-Hole is passed up the chain through DoH.

The yaml also contains an IngressRoute . This is how Traefik routes anything that comes in on one of its entry points. If you don't wish to expose the web UI you can remove this section. If you do want to (and you have Traefik running as per my previous series) you need to ensure you update the Hostsection to match your DNS entry.

Finally, two load balancer services are created. They are necessary to expose the DNS resolution capabilities to your network. The externalIPssection is where you specify what IP you wish to use to expose it to your network. It is not strictly necessary since your load balancer provisioner is capable of assigning it an IP, but it is highly recommended to specify it so it is consistently the same IP address. Both external IPs in the two services should match.

Once you have set it up, you should apply it as you would any other manifest

$ sudo kubectl apply -f pihole.yaml

To check it is up and running, check the pods in the pihole namespace

$ sudo kubectl get pods -n pihole

Assuming it has all worked, you will get output like this

Successfully running Pi-Hole instance

All that remains now is to set your network’s DNS settings. How to do this varies greatly amongst router providers, so you will have to look for and update your own DNS/DHCP settings.

Congratulations! You now have a more secure internet browsing experience, with all DNS requests leaving your network secured and encrypted. If you so wish you can then take this further and host a VPN too so that you can use this DNS server externally, but that's out of scope for now!

--

--

Scott Jones
CodeX

Home automation enthusiast. Self titled k8s Guru. RPi cluster god