0

I am trying to understand the DNS wire format used in DNS over HTTP:

ref: https://developers.cloudflare.com/1.1.1.1/encryption/dns-over-https/make-api-requests/dns-wireformat/

This page mentions the query for www.example.com:

curl -D - -X GET -H "accept: application/dns-json" "http://127.0.0.1:8553/dns-query?dns=AAABAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB"

I want to know how the AAABAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB was generated for www.example.com ?

echo "www.example.com" | base64
d3d3LmV4YW1wbGUuY29tCg==


echo "AAABAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB" | base64 -d
wwwexamplecom

Clearly, I am missing something here. It appears that the wire format is just not base64 encoded version of the domain name?

Bhakta Raghavan
  • 664
  • 6
  • 16

2 Answers2

1

You are right, the wire format is not just the base64 encoded version of the domain name. The wire format for DNS over HTTP is a little more complicated than that. It consists of the following parts:

The first 2 bytes are the flags. These bits indicate the type of query, whether it is recursive or not, and other options. The next 2 bytes are the number of questions. This is the number of domain names that are being queried. The next 2 bytes are the number of answers. This is the number of answers that are expected in the response. The next 2 bytes are the number of authority records. The next 2 bytes are the number of additional records. The questions are then listed, one per line. Each question consists of the following parts: The domain name, encoded in base64. The type of query, such as A for an IPv4 address or AAAA for an IPv6 address. The class of the query, such as IN for the Internet class. So, in the case of the query for www.example.com, the wire format would be:

  • 0001 0000 # Flags: Recursive query
  • 0001 0001 # Questions: 1
  • 0000 0000 # Answers: 0
  • 0000 0000 # Authority records: 0
  • 0000 0000 # Additional records: 0

AAABAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB # Question: www.example.com (base64 encoded) The AAABAAABAAAAAAAAA part is the base64 encoded version of the domain name, but it is prefixed with some padding bits. The padding bits are necessary to ensure that the length of the wire format is a multiple of 8 bytes.

I hope this explanation helps!

Here are some additional resources that you may find helpful:

0

I built on the answer/links from Denver's response.

Here is a python snippet to generate the wire format:

import base64
import dns.message

w = "AAABAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB"
b = base64.b64decode("AAABAAABAAAAAAAAA3d3dwdleGFtcGxlA2NvbQAAAQAB")
m = dns.message.from_wire(b)
print(str(m))

##The above should print:
#
# id 0
# opcode QUERY
# rcode NOERROR
# flags RD
# ;QUESTION
# www.example.com. IN A
# ;ANSWER
# ;AUTHORITY
# ;ADDITIONAL

# Now generate back the wire format
data = str(m)
wireBytes = dns.message.from_text(data).to_wire()
wire = base64.b64encode(wireBytes)
print(wire.decode("utf-8"))
print(w)
Bhakta Raghavan
  • 664
  • 6
  • 16