Unbound DNS over HTTPS Trouble

Aaron D. Gifford anothernsduser at tambler.com
Thu Jun 17 16:17:14 UTC 2021


Hi,

I've been trying out DoH using Unbound 1.13.1 on a FreeBSD host and a 
Let's Encrypt TLS certificate.  Unbound starts and listens on my DoH 
port, and when I connect to it, the TLS session is established as 
expected.  I can send DNS queries and the server sends me a response, 
but it's one byte short and is simply a reply containing NO RR records, 
only the original question sent to the server, oddly truncated by a 
single byte.

For example, here's what happens when I query Cloudflare's 1.1.1.1 DoH 
server (using it like a control to compare Unbound's response) and then 
my local test Unbound server using the same query for an A record for 
google.com:

RAW QUERY, 28 BYTES:
   58, 102,                          # Query ID
   1,                                # qr=0 (request), opcode=0, aa=0,
                                     # tc=0, rd=1 (recursion desired)
   0,                                # ra=0, z=0, rcode=0
   0, 1,                             # Number of questions: 1
   0, 0,                             # Number of answers:   0
   0, 0,                             # Authority RRs:       0
   0, 0,                             # Additional RRs:      0
   --- QUESTION 1 of 1 ---
   6, 103, 111, 111, 103, 108, 101,  # label "google"
   3, 99, 111, 109,                  # Label "com"
   0,                                # End of labels
   0, 1,                             # Class "IN" (1)
   0, 1                              # Resource type "A" (1)

Cloudflare 1.1.1.1 using HTTP/2:
https://1dot1dot1dot1.cloudflare-dns.com/dns-query?dns=OmYBAAABAAAAAAAABmdvb2dsZQNjb20AAAEAAQ==

   HTTP/2 Response Headers:
     Content-Type:   application/dns-message
     Content-Length: 44

   RAW REPLY, 44 BYTES:
     58, 102,                        # Query ID (matches question ID)
     129,                            # qr=1 (answer), opcode=0, aa=0,
                                     # rc=0, rd=1 (recursion desired)
     128,                            # ra=1 (recursion available), z=0,
                                     # rcode=0
     0, 1,                           # Number of questions: 1
     0, 1,                           # Number of answers:   1
     0, 0,                           # Authority RRs:       0
     0, 0,                           # Additional RRs:      0
   --- QUESTION 1 of 1 ---
     6, 103, 111, 111, 103, 108, 101,# Label "google"
     3, 99, 111, 109,                # Label "com"
     0,                              # End of labels
     0, 1,                           # Class "IN" (1)
     0, 1                            # Record type "A" (1)
     --- ANSWER 1 of 1 ---
192, 12,                        # "google.com" by pointer to packet
                                     # data at index 12 (question start)
     0, 1,                           # Class "IN" (1)
     0, 1,                           # Resource type "A" (1)
     0, 0, 0, 182,                   # TTL=182
     0, 4, 216, 58, 220, 142         # Address (len=4) [216.58.220.142]


Local Unbound 1.13.1 test server using HTTP/2:
https://unbound.example.org/dns-query?dns=OmYBAAABAAAAAAAABmdvb2dsZQNjb20AAAEAAQ==

   HTTP/2 Response Headers:
     Content-Type:   application/dns-message
     Content-Length: 27

   RAW REPLY, 27 BYTES:
     58, 102,                        # Query ID (matches question ID)
     129,                            # qr=1 (answer), opcode=0, aa=0,
                                     # rc=0, rd=1 (recursion desired)
     1,                              # ra=0 (recursion NOT available),
                                     # z=0, rcode=1
                                     # rcode=1 (format error) WHAT??
     0, 1,                           # Number of questions: 1
     0, 0,                           # Number of answers:   0
     0, 0,                           # Authority RRs:       0
     0, 0,                           # Additional RRs:      0
     --- QUESTION 1 of 1 ---
     6, 103, 111, 111, 103, 108, 101,# Label "google"
     3, 99, 111, 109,                # Label "com"
     0,                              # End of labels
     0, 1,                           # Class "IN" (1)
     0, XXX MISSING BYTE XXX         # Record type ??? LENGTH TOO SHORT!!



So now my questions.

1) WHY is Unbound NOT liking the question's format ("format error" as 
seen in rcode=1) when it IS in application/dns-message format, URL-safe 
base 64 encoded as part of the GET query?

2) WHY is Unbound's reply ONE BYTE short, and thus most DNS response 
parsers will raise an exception attempting to parse the reply?  At first 
I thought perhaps the CURL library I was using to perform queries was 
truncating the reply, until I checked the HTTP/2 response headers and 
saw that the "Content-Length" header indeed contained the value 27.

Problem #2 looks like a BUG to me.  As for #1... I have NO idea.

3) Can Unbound accept DoH queries via HTTP/1.1 or HTTP/1.0?  When I 
attempt to query with these protocols, I don't even get a response at 
all.  The TLS connection just gets closed. Cloudflare's server happily 
accepts HTTP/1.0 and HTTP/1.1 queries.  I guess I can understand not 
supporting 1.0.


Thanks in advance for any and all answers, pointers, insights, or 
information regarding #1 and #2.

As for #3, it's not really too important to me.  I assume the HTTP 
library Unbound is using doesn't have 1.1 support--and modern 
apps/systems really are most likely to do DoH with HTTP/2. I'd still 
like to see 1.1 supported someday, though.

Thanks, Unbound devs, for some excellent software!


--Aaron out



More information about the Unbound-users mailing list