With much of the web switching to HTTPS and at least some people becoming more concerned about privacy, DNS has recently come into the spotlight because it provides an ISP with the ability to monitor which websites a user visits. Multiple mitigations have been proposed – Android for example is going to support DNS Over TLS, which tunnels good old DNS payload over TLS. And now there is a working group at the IETF developing DNS Over HTTPS (DoH), which layers DNS on top of HTTP/2.
The idea of using HTTP/2 is certainly appealing from a technical perspective. It enables an application to multiplex multiple independent streams over a single TCP connection, avoiding the head-of-line blocking that plagues HTTP/1.1’s rarely used pipelining feature. HTTP/2 has gained traction as a transport in gRPC and libraries are available for many programming languages even though it’s a relatively young protocol.
In DoH, DNS queries and responses are mapped to HTTP/2 streams and the draft also defines caching semantics, mapping DNS TTLs to HTTP’s Cache-Control headers. Thanks to the fact that we’re in normal HTTP territory, caching proxies can be used.
I’ve played around with two things: I’ve set up cloudflared in my local network which acts as a DNS server listening on UDP port 53 and passing on DNS queries to Cloudflare’s new 126.96.36.199 service using DOH. That seems to work fine.
The second thing I tried is building a DOH client myself in Python that queries a name server and prints the result. It was a relatively quick and easy task using an HTTP/2 client and a library for generating and parsing DNS queries. I was able to query test servers provided by Google and Cloudflare, but it became clear to me that things are still very much in the experimental stage.
For example, Google’s server doesn’t like when the base64 padding on the “dns” parameter is removed, even though that’s required by the specification. It’s also still on draft version 04 and requires the “ct” parameter. Cloudflare’s server only seems to support HTTP POST at the moment and doesn’t respond to “ANY” queries – other types like “A” and “AAAA” work fine though.
Anyway, it was fun thing to play around with. But does this solve our privacy problems? I’m not so sure.
If you don’t trust your network operator, a VPN is still the only viable option to prevent them from building a traffic profile. Even if you use HTTPS for everything and you have found a trustworthy DOH service, it’s still relatively easy to just profile you by snooping on IP destinations or the SNI extension during the TLS handshake. I’m afraid proper regulation is the only thing that’s going to help us here.