Fun with DNS over TLS (DoT)

Published: 2021-03-01
Last Updated: 2021-03-01 13:37:50 UTC
by Rob VandenBrink (Version: 1)
2 comment(s)

Going back a few weeks, we discussed how DNS over HTTPS (DoH) works (  - very much as an unauthenticated API over HTTPS.  But DNS over TLS (DoT) has been with us for a fair bit longer (May 2016), why haven't we heard about it so much?

After wrestling with it for a bit, I can tell you why!

DoH is easy to work with, since we have so many HTTPS tools at our disposal.  Plus DoH was first implemented in browsers, and the browser developers *live* in HTTPS, so DoH is a cake-walk for them.  DNSSEC is basically plain old unencrypted DNS, but with signature records.

DoT on the other hand is a whole 'nother beast.  It's still basic DNS, but encapsulated in TLS.  So to make DoT calls we need a toolset to create TLS packets, then send and validate them using the certificate at the server side.  So the first tool that came to my mind of course was scapy, but read on, I used an easier method ..

To allow all of the mentioned DNS protocols to live on one server, DoT lives on tcp/853.  This makes for an easy NMAP scan if you're looking for this service.  NMAP tags the port correctly, but an NMAP version scan (-sV) won't identify  the DoT service.  It will however find some critical strings in the fingerprint, things like "DNSVersionBindReqTCP" and "DNSStatusRequestTCP" - so a version scan will validate the service enough for your eyes to see it, without calling it out definitively.  You can also of course validate the certificate on port tcp/853 using NMAP's ssl-cert.nse script or openssl:

nmap -p853 --script ssl-cert

Starting Nmap 7.80 ( ) at 2021-03-01 07:55 Eastern Standard Time

Nmap scan report for

Host is up (0.012s latency).



853/tcp open  domain-s

| ssl-cert: Subject: LLC/stateOrProvinceName=California/countryName=US

| Subject Alternative Name:, DNS:*,,,, IP Address:2001:4860:4860:0:0:0:0:64, IP Address:2001:4860:4860:0:0:0:0:6464, IP Address:2001:4860:4860:0:0:0:0:8844, IP Address:2001:4860:4860:0:0:0:0:8888, IP Address:, IP Address:

| Issuer: commonName=GTS CA 1O1/organizationName=Google Trust Services/countryName=US

| Public Key type: rsa

| Public Key bits: 2048

| Signature Algorithm: sha256WithRSAEncryption

| Not valid before: 2021-01-26T08:54:07

| Not valid after:  2021-04-20T08:54:06

| MD5:   9edd 82e5 5661 89c0 13a5 cced e040 c76d

|_SHA-1: 2e80 c54b 0c55 f8ad 3d61 f9ae af43 e70c 1e67 fafd

Nmap done: 1 IP address (1 host up) scanned in 24.43 seconds

Me, I took the easy way out for DoT queries and installed the knot-dnsutils (sudo apt-get install knot-dnsutils), which installs kdig to do all the heavy lifting for me.  As the name implies, kdig does just about everything that dig does, but for this task gives you parameters to make DoT queries.

So an A record query over DoT from kdig looks just very much like DOS query outpuyt from dig:

$ kdig +tls-ca A

;; TLS session (TLS1.3)-(ECDHE-X25519)-(RSA-PSS-RSAE-SHA256)-(AES-256-GCM)

;; ->>HEADER<<- opcode: QUERY; status: NOERROR; id: 57540

;; Flags: qr rd ra; QUERY: 1; ANSWER: 2; AUTHORITY: 0; ADDITIONAL: 1



;; Version: 0; flags: ; UDP size: 512 B; ext-rcode: NOERROR

;; PADDING: 391 B


;;                IN      A

;; ANSWER SECTION:           4       IN      A           4       IN      A


;; Received 468 B

;; Time 2021-03-01 04:58:51 PST

;; From in 38.9 ms

Note all the TLS session info at the top, and the port number in the last line.

As you'd expect, if you're just after answers you can use the +short parameter:

# kdig +tls-ca +short AAAA

.. yup, I host my website on github, handiest github feature ever (ok, maybe not the handiest, but still pretty darned handy)

Other handy parameters in kdig?

  • Just as in dig, you can always tack on the "-d" parameter for debug output
  • +tls-hostname can be used to over-ride the server name during TLS negotiation.  This means you can even use the server's IP address when you use this parameter.
  • Related to tls-hostname, +tls-sni adds the Server Name Indication field to the request

Without constructing the TLS packet, how can I use DoT in an NMAP script?  I again took the easy way out and used kdig, in combination with the lua command os.execute.  Yup, in the time honoured tradition of coding laziness I shelled out and executed the matching OS command!  In the DoH script I wrote I did a quick check to make sure that the host was running HTTP services on port 443 with "shortport.http".  In the DoT script I changed this, to ensure that TLS is running on the scanned port, using the "shortport.ssl" check.  An example scan is shown below:

$ nmap -p853 --script dns-dot.nse --script-args,query=AAAA

Starting Nmap 7.80 ( ) at 2021-03-01 05:13 PST

Nmap scan report for (

Host is up (0.017s latency).



853/tcp open  domain-s

| dns-dot:





|   2607:f798:d04:189::b33

|_  2607:f798:d04:191::b33


Nmap done: 1 IP address (1 host up) scanned in 0.40 seconds

You can find the DoT script here: . Because is calls kdig, you'll need the knot-dnsutils package installed before this script will run.  If you're interested in combining NMAP scans with different OS commands you're welcome to review the source code and use whatever you need!

Do you have a handy nmap script that uses os.execute to do the "behind the scenes" work?  Please, share a link in our comment form!



Usage Profiles for DNS over TLS and DNS over DTLS:



Rob VandenBrink

2 comment(s)
ISC Stormcast For Monday, March 1st, 2021


Diary Archives