Implementing DNS-Over-TLS

Hi. I wonder how I can implement DNS-Over-TLS together with Pi-Hole. Are there any tutorials / recipes for doing this? I have Pi-Hole installed on a RPi device. With DoT set up will this encrypt all DNS requests from within my network?

Note that this would also require your upstream DNS resolvers to support DoT. While becoming more and more common, you still want to verify that your chosen DNS resolver does support DoT.

You might want to search the forums for this.
There are a few topics around that deal with DoT and its implications for Pi-hole (e.g. Implement DNS-over-TLS capability in Pi-hole has a vivid discussion why DoT won’t become an integral part of Pi-hole soon, and Pi-hole for DNS-over-TLS - the Simplest Way has a short example for using a third party package).

The easiest way to enable DoT in a standard Pi-hole setup would be if your router supports DoT:
Set your router as upstream DNS for Pi-hole, and let your router handle DoT traffic to its upstream DNS servers.

Yes, my goal is actually to have a local recursive DNS server (like Unbound), but for now I wanted first to try to implement a DoT connection to Cloudflare for instance. As I understand they support DoT. However, with regards to DoT encryption there is something I have not quite understood; is the encryption only between the local resolver inside your network and the recursive DNS server (in which case would one need DoT as long as the recursive DNS server was also inside the local network?) or is it also between the recursive DNS server and the root-, TLD-, and authoritative DNS servers?

Thanks for your input. I’ll check out the threads you suggested :slight_smile:

Yes. And typically only if the recursive DNS resolver is somewhere on the internet. If the recursive resolver is on your network, encryption to that resolver serves little purpose.

No - see above.

No. Traffic to/from the nameservers is not encrypted.

What is your goal with encrypted DNS. Security, privacy, etc.?

Another question related to this; I have now read several threads about implementation of Unbound as a recursive DNS server, but in many of these setups the Unbound is also configured to forward DNS requests upstream to Google/Cloudflare. What would be the purpose of this? Isn’t the whole point of setting up Unbound as a local recursive server to “cut out” the external recursive resolver? Am I missing something?

These users want to use encrypted DNS, instead of running unbound in recursive mode. There is a difference of opinion regarding whether encrypted DNS increases privacy - I contend that it does not and encrypting your DNS traffic to an upstream resolver who gathers all your DNS history requires you to trust that upstream service. In return, you gain no privacy since your ISP can see the plain-text request for any IP acquired through an encrpted DNS tunnel.

In my opinion, yes. Encrypted DNS provides less privacy, in my opinion. In addition, you get unfiltered replies - you are getting the IP address from the authoritative phone book of the internet, with no intermediaries to filter anything. You are in complete control and only have to trust yourself.

I have found several discussions on the Pi-hole userspace for DoT including a link to a Cloudflare package that is way too complicated for most. This is a simple way to add DoT with Stubby/Pi-hole.
I have successfully done this procedure on a Pi3B+ with Rasbian Buster and Ubuntu 18.04 and 20.04 server images. For this I'll stick with Buster.

  1. Install Pi-hole on your system. When asked for an Upstream DNS Server choose anything you want. I entered a custom server with my router LAN IP address. This will be modified later. Make sure Pi-hole is working.
  2. Install Stubby and its dependencies.
    sudo apt install stubby
  3. Make a directory for the DNSSEC keys
    sudo mkdir /var/cache/stubby
  4. Make a backup of the default stubby.yml
    sudo cp /etc/stubby/stubby.yml /etc/stubby/stubby.yml.bak
  5. Edit stubby.yml
    sudo nano /etc/stubby/stubby.yml
    Here is an example of my stubby.yml

resolution_type: GETDNS_RESOLUTION_STUB
dns_transport_list:
- GETDNS_TRANSPORT_TLS
tls_authentication: GETDNS_AUTHENTICATION_REQUIRED
tls_query_padding_blocksize: 128
edns_client_subnet_private : 1
round_robin_upstreams: 1
idle_timeout: 10000
tls_connection_retries: 5
tls_ca_path: "/etc/ssl/certs/"
listen_addresses:
- 127.0.0.1@5453
- ::1@5453
dnssec: GETDNS_EXTENSION_TRUE
appdata_dir: "/var/cache/stubby"
upstream_recursive_servers:
- address_data: 9.9.9.9
tls_auth_name: "dns.quad9.net"
- address_data: 149.112.112.112
tls_auth_name: "dns.quad9.net"

  1. In the Pi-hole Admin Console - Settings - DNS - remove any prior entries.
    In Custom 1 (IPV4) enter 127.0.0.1#5453
    If you use IPV6 in Custom 3 (IPV6) enter ::1#5453
    Note: You can use any loopback port you want but I would avoid port 53.
  2. Restart Stubby
    sudo service stubby restart

You can check that stubby is working by watching it after entering:
stubby -l
Cancel logging with CTRL c

The stubby.yml example is set to use Quad9. Other upstream resolvers are avaliable. See the stubby.yml.bak file.
This example has DNSSEC via stubby enabled. If you test with the 1.1.1.1 help page DoT will show as failed. This is a known issue when DNSSEC is enabled and is a Cloudflare problem.
Be careful with the stubby.yml as mistakes in the file will cause problems.

1 Like

Great guide, thanks bbunge! Just to check, will this have DNSSEC enabled during the process? It looks like it from the stubby.yml file but I'd be unsure about what to put in the PiHole interface. I'm guessing the Stubby config will supercede the PiHole DNS page settings?

Yes, the stubby.yml in the example (the same as I use) does enable DNSSEC.
Changes to Pi-hole:
Settings - DNS Uncheck any pre-loaded upstream DNS servers (on left) and under Custom 1 (IPV4) enter 127.0.0.1#5453 If you use IPV6 under Custom 3 (IPV6) enter ::1#5453