If you’re looking for an easy setup, checkout my review of NextDNS: DoT and DoH provider for easy ADBlocking.

This guide will help you reuse your setup for DNS-over-HTTPS (DoH) to add support for DNS-over-TLS (DoT). The best part ? You won’t need new tools after you’ve followed my previous guides: DNS-over-HTTPS or Pihole and DoH.

Introduction

DNS-over-TLS (DoT) is different to DNS-over-HTTPS (DoH).

DoH is used in different application like DNScrypt, Intra, etc … In other words, there isn’t any OS implementation of it. You always need a separate app to use it.

DoT is used directly in Android 9 (Pie).

It’s important to note that in both case the traffic will be encrypted and your ISP or any company between you and the server won’t be able to see what are your DNS request. It’s only 2 different ways to do the same thing.

Disclaimer

This tutorial relies heavily on using Letsencrypt certificate. However, if you have an old Android device (before 10) it might not work because their CA certificate has been rotated. Your android device won’t recognize it and won’t let you use your Private DNS.

If it’s the case, you’ll need to find another provider for the certificate. Or use an updated application like Intra.

DNS-over-HTTPS (DoH)

In DoH, you’re using an HTTPS server to relay the DNS request to your DNS server. The request are encoded in a specific format, usually in JSON.
For more information, I advise you to check my DNS-over-HTTP Tutorial.

DNS-over-TLS (DoT)

DNS over TLS (DoT) is a security protocol for encrypting and wrapping Domain Name System (DNS) queries and answers via the Transport Layer Security (TLS) protocol. The goal of the method is to increase user privacy and security by preventing eavesdropping and manipulation of DNS data via man-in-the-middle attacks.

Wikipedia

Basically, you’re going to encapsulate DNS traffic into a TLS stream to encrypt the request and use TCP instead of UDP. The default port is 853.

Tutorial

If you’ve followed already my guide on how to setup DoH, you have everything you need.

If you didn’t, I advise you to follow it to be able to easily generate an HTTPS certificate with Certbot. If you already have a certificate, great, you’re good to go.

If you don’t have a certificate ready, I recommend you to set it up with Certbot and DNS validation (like with CloudFlare) or to follow the DoH guide.

NGINX

NGINX is an amazing tool, not only it’s an HTTP server but can be used to encapsulate any stream into a TLS stream. This is exactly what we want.

Streams

First, you’ll need to create a new directory in your NGINX install directory to store the stream configuration.

sudo mkdir /etc/nginx/streams/

TLS

Now get from the DoH NGINX’s site configuration file the path to your HTTPS key and certificate.

If you used Certbot, it’s gonna look like this where dns.aaflalo.me will be your domain.

ssl_certificate /etc/letsencrypt/live/dns.aaflalo.me/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/dns.aaflalo.me/privkey.pem; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

Now that you have the SSL configuration, we’re gonna create the stream configuration to redirect DoT traffic to your DNS server.

DNS-over-TLS

We create the dns-over-tls configuration and then you’ll use your favourite editor to set the content.

/etc/nginx/streams/dns-over-tls
upstream dns-servers {
     	server    127.0.0.1:53;
}

server {
	listen 853 ssl; # managed by Certbot
	ssl_certificate /etc/letsencrypt/live/dns.aaflalo.me/fullchain.pem; # managed by Certbot
	ssl_certificate_key /etc/letsencrypt/live/dns.aaflalo.me/privkey.pem; # managed by Certbot
	ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot


	ssl_protocols        TLSv1.2 TLSv1.3;
	ssl_ciphers          HIGH:!aNULL:!MD5;
        
	ssl_handshake_timeout    10s;
	ssl_session_cache        shared:SSL:20m;
	ssl_session_timeout      4h;

	proxy_pass dns-servers;

}

I’ve highlighted the lines (2, 7, 8) you need to change for your own configuration. The server in dns-servers need to point to the DNS server you want to use. May it be your Pihole, or your DNSCrypt server, etc … You can put multiple server as well.

Activate Streams

Now the last step, is to tell NGINX to look into our /etc/nginx/streams folder to activate the stream.

Edit the file /etc/nginx/nginx.conf

And add the following piece of code into the file, after the HTTP block (or just at the end of the file)

stream {
        include /etc/nginx/streams/*;
}

Now you just need to restart NGINX, and you’ll have a DoT server listening on the port 853.

sudo systemctl restart nginx

Firewall

Don’t forget to open the TCP port 853 on your firewall to be able to access the server.

Test

To test your DoT server, you can use the service provided by GetDNS.

GetDNS Interface

How to use the Querier

  1. Set Transport order

    Set it to TLS

  2. Set TLS resolver IP

    To the Public IP of your server

  3. TLS auth name

    To the FQDN (full name) of your server certificate. The one you used to generate the TLS certificate.

  4. Query

    Put the domain you want to query, like aaflalo.me or google.com and select A query.

  5. Push the button

    And check that there is a result