Intra doesn't seem to pad queries
The size of DNS queries and their responses are among the most important features that can be used to classify encrypted DNS traffic.
To mitigate this, implementing padding is essential. This is also mentioned in the security considerations of the current DoH draft.
HTTP/2 frames can include padding. This mechanism can be leveraged by DoH clients and servers.
Briefly looked into this yesterday. It looks like DoH (RFC8484) padding can be accomplished either with HTTP/2 padding (RFC7540 § 6.1) or at the DNS level with the EDNS padding option (RFC7830).
@bemasc : Any recommendation on the best strategy here?
Option 1: HTTP/2 Padding
I figured HTTP/2 padding is the easiest to implement, so I dug into the code. StandardServerConnection.performDnsRequest uses the OkHttp3 library to forward the intercepted DNS requests, but AFAICT, OkHttp3 callers cannot configure HTTP/2 padding! It does, however, have the ability to read frames that have padding.
Possible next steps, if we go this route:
- Implement padding for outgoing frames in OkHttp3 and submit a PR.
- Switch out the HTTP library for one that already supports HTTP/2 padding.
Option 2: EDNS Padding
To implement EDNS padding, we would have to intercept, parse, and rewrite queries. One thing to consider is that we might intercept a query that is already padded, perhaps to a different length than we want. To choose the padding length, we would consult RFC8467: Padding Policies for Extension Mechanisms for DNS (EDNS(0)).
Before implementing this, I'd like to verify that DoH servers in the wild can understand queries with EDNS padding.
I consulted with Chromium's resident DNS expert (Eric Orth), who tells me that Chromium already sends requests with EDNS padding, and that at least Cloudflare should support it. That's sounds like a good reason to go with Option 2 to me.
I agree, Option 2 is probably the right way.
FYI, we are planning to move to a new forwarder implementation in a different repo: https://github.com/Jigsaw-Code/outline-go-tun2socks/blob/master/tunnel/intra/doh/doh.go. That would probably be the right place to implement padding.
Is the plan to make outline-go-tun2socks a git submodule of this repo?
That's not something we've planned, but it's an interesting idea. One way or another it would be nice to improve the build system.