Switch branches/tags
Nothing to show
Find file History
Latest commit 8bffd0b Apr 11, 2018


Code written for the DoH (DNS-over-HTTPS) work during the hackathon

All the code here work with HTTP/2 and TLS.


doh-proxy written in Python, and using dnspython saw fixes and improvments.

Tony Finch's proxy (and the second day), as a Nginx module in Lua. doh101 is available at Github and at his Gitlab.

Presentation of DNSproxy

quart-doh.py is a server written in Python with the Quart framework for HTTP/2. It uses the dnspython library to send the request to a full resolver. You can start it with ./quart-doh.py -r YOURESOLVER (-h for other options. With -c, you have a checking mode, for interoperability testing.

Work under way for CoreDNS


JavaScript code using the dns-packet library. A test Web page is under development.

Firefox has now a DoH client

dns-client.py is a Python client using the pycurl, which itself depends on pycurl.

doh-nghttp.c is a C client, using the nghttp2 asynchronous HTTP/2 library and the getdns library to encode and decode DNS messages. You can compile it with cc -c doh-nghttp.c and link it with cc -odoh-nghttp doh-nghttp.o getdns-git/src/parseutil.o -lnghttp2 -lhttp_parser -levent -lssl -lcrypto -levent_openssl -lgetdns.


Work is under way for the C library getdns. The development branch for this work is here. It relies on the new upstream server management code. Once finished, this is how DoH upstreams can be configured in a Stubby YAML configuration file:

# Specify the list of upstream recursive name servers to send queries to
# Manu Bretelle's DNS over HTTPS server:
  - uri: "https://dns.dnsoverhttps.net/dns-query"
# The google DNS over HTTPS server:
  - uri: "https://dns.google.com/experimental"
# The cloudflare DNS over HTTPS server:
  - uri: "https://dns.cloudflare.com/.well-known/dns-query"
# The Stephane Bortzmeyer's DNS over HTTPS server:
  - uri: "https://dns.bortzmeyer.fr"
# The quad9 DNS over TLS server
  - name: "dns.quad9.net"

Go DNS now has DoH. The plan and the report

Public DoH servers

It is interesting to know that each uses a different code base.

Ideas for interoperability testing

Client side tests are tests that would be run from the client to test the server conformance

Server side tests are errors that would be logged if a client was to send invalid content

Client side

  • correct MIME type
  • return code should be 415 when the content type is invalid
  • return code should be 405 when the method is not accepted (check that Allow header is set). What about HEAD? if the server does not accept GET, then HEAD is pointless . doh-proxy fail the HEAD handling: https://github.com/facebookexperimental/doh-proxy/issues/37
  • return code should be 406 when the content type is not accepted by the server: does the server returns a list of accepted content type?
  • does server supports GET
  • does server supports POST
  • Invalid certificates should be rejected
  • "intelligent" use of the cache-control and expires headers
  • send Base64 with padding

Server Side

  • ID set to 0
  • if GET, check that ct= and dns= exist and that ct= has a proper value
  • check the MIME type


Manu Bretelle's test system. To install dependencies: pip install -e .[integration_tests]. To run the test: PYTHONPATH=. python3 ./dohproxy/integration.py --domain dohserver.example.com. See -h for more options.

This is using the unittest framework and basically will print the result for individual tests and then spit out the exceptions.

Also, the test-servers.py (requires dnspython and pycurl) tests several servers:

WARNING: Impossible content type requested and accepted

ERROR: HTTP error in reply to HEAD 400
WARNING: Impossible content type requested and accepted

INFO: GET not implemented
INFO: HEAD not implemented
WARNING: Impossible content type requested and accepted

WARNING: Impossible content type requested and accepted

Questions/notes about the current draft

Wire format specification should explicitly say that length preambule is not part of the DNS wireformat blob, just to be explicit? No implementor included it (it is useless for HTTP).

Should we use GET, POST or both? (see the Cloudflare test above)

Bug fixes

As always during a hackathon, some bugs were discovered in the libraries used, and sometimes fixed even before the end of the hackathon