from Sebastian: 235-kill-named-flag.txt
[torspec.git] / proposals / 219-expanded-dns.txt
1 Filename: 219-expanded-dns.txt
2 Title: Support for full DNS and DNSSEC resolution in Tor
3 Authors: Ondrej Mikle
4 Created: 4 February 2012
5 Modified: 2 August 2013
6 Target: 0.2.5.x
7 Status: Draft
8
9 0. Overview
10
11   Adding support for any DNS query type to Tor.
12
13 0.1. Motivation
14
15   Many applications running over Tor need more than just resolving FQDN to
16   IPv4 and vice versa. Sometimes to prevent DNS leaks the applications have to
17   be hacked around to be supplied necessary data by hand (e.g. SRV records in
18   XMPP). TLS connections will benefit from planned TLSA record that provides
19   certificate pinning to avoid another Diginotar-like fiasco.
20
21 0.2. What about DNSSEC?
22
23   Routine DNSSEC resolution is not practical with this proposal alone,
24   because of round-trip issues: a single name lookup can require
25   dozens of round trips across a circuit, rendering it very slow. (We
26   don't want to add minutes to every webpage load time!)
27
28   For records like TLSA that need extra signing, this might not be an
29   unacceptable amount of overhead, but routine hostname lookup, it's
30   probably overkill.
31
32   [Further, thanks to the changes of proposal 205, DNSSEC for routine
33   hostname lookup is less useful in Tor than it might have been back
34   when we cached IPv4 and IPv6 addresses and used them across multiple
35   circuits and exit nodes.]
36
37   See section 8 below for more discussion of DNSSEC issues.
38
39 1. Design
40
41 1.1 New cells
42
43   There will be two new cells, RELAY_DNS_BEGIN and RELAY_DNS_RESPONSE (we'll
44   use DNS_BEGIN and DNS_RESPONSE for short below).
45
46 1.1.1. DNS_BEGIN
47
48   DNS_BEGIN payload:
49
50     FLAGS        [2 octets]
51     DNS packet data (variable length, up to length of relay cell.)
52
53   The DNS packet must be generated internally by Tor to avoid
54   fingerprinting users by differences in client resolvers' behavior.
55
56   [XXXX We need to specify the exact behavior here: saying "Just do what
57   Libunbound does!" would make it impossible to implement a
58   Tor-compatible client without reverse-engineering libunbound. - NM]
59
60   The FLAGS field is reserved, and should be set to 0 by all clients.
61
62   Because of the maximum length of the RELAY cell, the DNS packet may
63   not be longer than 496 bytes. [XXXX Is this enough? -NM]
64
65   Some fields in the query must be omitted or set to zero: see section 3
66   below.
67
68 1.1.2. DNS_RESPONSE
69
70   DNS_RESPONSE payload:
71
72     STATUS [1 octet]
73     CONTENT [variable, up to length of relay cell]
74
75   If the low bit of STATUS is set, this is the last DNS_RESPONSE that
76   the server will send in response to the given DNS_BEGIN.  Otherwise,
77   there will be more DNS_RESPONSE packets.  The other bits are reserved,
78   and should be set to zero for now.
79
80   The CONTENT fields of the DNS_RESPONSE cells contain a DNS record,
81   split across multiple cells as needed, encoded as:
82
83
84     total length (2 octets)
85     data         (variable)
86
87   So for example, if the DNS record R1 is only 300 bytes long, then it
88   is sent in a single DNS_RESPONSE cell with payload [01 01 2C] R1.  But
89   if the DNS record R2 is 1024 bytes long, it's sent in 3 DNS_RESPONSE
90   cells, with contents: [00 04 00] R2[0:495], [00] R2[495:992], and
91   [01] R2[992:1024] respectively.
92
93   [NOTE: I'm using the length field and the is-this-the-last-cell
94   field to allow multi-packet responses in the future. -NM]
95
96   AXFR and IXRF are not supported in this cell by design (see
97   specialized tool below in section 5).
98
99 1.1.3. Matching queries to responses.
100
101   DNS_BEGIN must use a non-zero, distinct StreamID.  The client MUST NOT
102   re-use the same stream ID until it has received a complete response
103   from the server or a RELAY_END cell.
104
105   The client may cancel a DNS_BEGIN request by sending a RELAY_END cell.
106   The server may refused to answer, or abort answering, a DNS_BEGIN cell
107   by sending a RELAY_END cell.
108
109 2. Interfaces to applications
110
111   DNSPort evdns - existing implementation will be updated to use
112   DNS_BEGIN.
113
114   [XXXX we should add a dig-like tool that can work over the socksport
115   via some extension, as tor-resolve does now. -NM]
116
117 3. Limitations on DNS query
118
119   Clients must only set query class to IN (INTERNET), since the only
120   other useful class CHAOS is practical for directly querying
121   authoritative servers (OR in this case acts as a recursive resolver).
122   Servers MUST return REFUSED for any for class other than IN.
123
124   Multiple questions in a single packet are not supported and OR will
125   respond with REFUSED as the DNS error code.
126
127   All query RR types are allowed.
128
129   [XXXX I originally thought about some exit policy like "basic RR types" and
130   "all RRs", but managing such list in deployed nodes with extra directory
131   flags outweighs the benefit. Maybe disallow ANY RR type? -OM]
132
133   Client as well as OR MUST block attempts to resolve local RFC 1918,
134   4193, or 4291 adresses (PTR). REFUSED will be returned as DNS error
135   code from OR.  [XXXX Must they also refuse to report addresses that
136   resolve to these? -NM]
137
138   [XXX I don't think so. People often use public DNS
139   records that map to private adresses. We can't effectively separate
140   "truly public" records from the ones client's dnsmasq or similar DNS
141   resolver returns. - OM]
142
143   [XXX Then do you mean "must be returned as the DNS error from the OP"?]
144
145   Request for special names (.onion, .exit, .noconnect) must never be
146   sent, and will return REFUSED.
147
148   The DNS transaction ID field MUST be set to zero in all requests and
149   replies; the stream ID field plays the same function in Tor.
150
151 4. Implementation notes
152
153   Client will periodically purge incomplete DNS replies. Any unexpected
154   DNS_RESPONSE will be dropped.
155
156   AD flag must be zeroed out on client unless validation is performed.
157
158   [XXXX libunbound lowlevel API, Tor+libunbound libevent loop
159
160   libunbound doesn't publicly expose all the necessary parts of low-level API.
161   It can return the received DNS packet, but not let you construct a packet
162   and get it in wire-format, for example.
163
164   Options I see:
165
166   a) patch libunbound to be able feed wire-format DNS packets and add API to
167   obtain constructed packets instead of sending over network
168
169   b) replace bufferevents for sockets in unbound with something like
170   libevent's paired bufferevents. This means that data extracted from
171   DNS_RESPONSE/DNS_BEGIN cells would be fed directly to some evbuffers that
172   would be picked up by libunbound. It could possibly result in avoiding
173   background thread of libunbound's ub_resolve_async running separate libevent
174   loop.
175
176   c) bind to some arbitrary local address like 127.1.2.3:53 and use it as
177   forwarder for libunbound. The code there would pack/unpack the DNS packets
178   from/to libunbound into DNS_BEGIN/DNS_RESPONSE cells. It wouldn't require
179   modification of libunbound code, but it's not pretty either. Also the bind
180   port must be 53 which usually requires superuser privileges.
181
182   Code of libunbound is fairly complex for me to see outright what would the
183   best approach be.
184   ]
185
186 5. Separate tool for AXFR
187
188   The AXFR tool will have similar interface like tor-resolve, but will
189   return raw DNS data.
190
191   Parameters are: query domain, server IP of authoritative DNS.
192
193   The tool will transfer the data through "ordinary" tunnel using RELAY_BEGIN
194   and related cells.
195
196   This design decision serves two goals:
197
198   - DNS_BEGIN and DNS_RESPONSE will be simpler to implement (lower chance of
199     bugs)
200   - in practice it's often useful do AXFR queries on secondary authoritative
201     DNS servers
202
203   IXFR will not be supported (infrequent corner case, can be done by manual
204   tunnel creation over Tor if truly necessary).
205
206 6. Security implications
207
208   As proposal 171 mentions, we need mitigate circuit correlation. One solution
209   would be keeping multiple streams to multiple exit nodes and picking one at
210   random for DNS resolution. Other would be keeping DNS-resolving circuit open
211   only for a short time (e.g. 1-2 minutes). Randomly changing the circuits
212   however means that it would probably incur additional latency since there
213   would likely be a few cache misses on the newly selected exits.
214
215   [This needs more analysis; We need to consider the possible attacks
216   here.  It would be good to have a way to tie requests to
217   SocksPorts, perhaps? -NM]
218
219 7. TTL normalization idea
220
221   A bit complex on implementation, because it requires parsing DNS packets at
222   exit node.
223
224   TTL in reply DNS packet MUST be normalized at exit node so that client won't
225   learn what other clients queried. The normalization is done in following
226   way:
227
228   - for a RR, the original TTL value received from authoritative DNS server
229     should be used when sending DNS_RESPONSE, trimming the values to interval
230     [5, 600]
231   - does not pose "ghost-cache-attack", since once RR is flushed from
232     libunbound's cache, it must be fetched anew
233
234 8. DNSSEC notes
235
236 8.1. Where to do the resolution?
237
238   DNSSEC is part of the DNS protocol and the most appropriate place for DNSSEC
239   API would be probably in OS libraries (e.g. libc). However that will
240   probably take time until it becomes widespread.
241
242   On the Tor's side (as opposed to application's side), DNSSEC will provide
243   protection against DNS cache-poisoning attacks (provided that exit is not
244   malicious itself, but still reduces attack surface).
245
246 8.2. Round trips and serialization
247
248   Following are two examples of resolving two A records. The one for
249   addons.mozila.org is an example of a "common" RR without CNAME/DNAME, the
250   other for www.gov.cn an extreme example chained through 5 CNAMEs and 3 TLDs.
251   The examples below are shown for resolving that started with an empty DNS
252   cache.
253
254   Note that multiple queries are made by libunbound as it tries to adjust for
255   the latency of network. "Standard query response" below that does not list
256   RR type is a negative NOERROR reply with NSEC/NSEC3 (usually reply to DS
257   query).
258
259   The effect of DNS cache plays a great role - once DS/DNSKEY for root and a
260   TLD is cached, at most 3 records usually need to be fetched for a record
261   that does not utilize CNAME/DNAME (3 roundtrips for DS, DNSKEY and the
262   record itself if there are no zone cuts below).
263
264   Query for addons.mozilla.org, 6 roundtrips (not counting retries):
265
266     Standard query A addons.mozilla.org
267     Standard query A addons.mozilla.org
268     Standard query A addons.mozilla.org
269     Standard query A addons.mozilla.org
270     Standard query A addons.mozilla.org
271     Standard query response A 63.245.217.112 RRSIG
272     Standard query response A 63.245.217.112 RRSIG
273     Standard query response A 63.245.217.112 RRSIG
274     Standard query A addons.mozilla.org
275     Standard query response A 63.245.217.112 RRSIG
276     Standard query response A 63.245.217.112 RRSIG
277     Standard query A addons.mozilla.org
278     Standard query response A 63.245.217.112 RRSIG
279     Standard query response A 63.245.217.112 RRSIG
280     Standard query DNSKEY <Root>
281     Standard query DNSKEY <Root>
282     Standard query response DNSKEY DNSKEY RRSIG
283     Standard query response DNSKEY DNSKEY RRSIG
284     Standard query DS org
285     Standard query response DS DS RRSIG
286     Standard query DNSKEY org
287     Standard query response DNSKEY DNSKEY DNSKEY DNSKEY RRSIG RRSIG
288     Standard query DS mozilla.org
289     Standard query response DS RRSIG
290     Standard query DNSKEY mozilla.org
291     Standard query response DNSKEY DNSKEY DNSKEY RRSIG RRSIG
292
293   Query for www.gov.cn, 16 roundtrips (not counting retries):
294
295     Standard query A www.gov.cn
296     Standard query A www.gov.cn
297     Standard query A www.gov.cn
298     Standard query A www.gov.cn
299     Standard query A www.gov.cn
300     Standard query response CNAME www.gov.chinacache.net CNAME www.gov.cncssr.chinacache.net CNAME www.gov.foreign.ccgslb.com CNAME wac.0b51.edgecastcdn.net CNAME gp1.wac.v2cdn.net A 68.232.35.119
301     Standard query response CNAME www.gov.chinacache.net CNAME www.gov.cncssr.chinacache.net CNAME www.gov.foreign.ccgslb.com CNAME wac.0b51.edgecastcdn.net CNAME gp1.wac.v2cdn.net A 68.232.35.119
302     Standard query A www.gov.cn
303     Standard query response CNAME www.gov.chinacache.net CNAME www.gov.cncssr.chinacache.net CNAME www.gov.foreign.ccgslb.com CNAME wac.0b51.edgecastcdn.net CNAME gp1.wac.v2cdn.net A 68.232.35.119
304     Standard query response CNAME www.gov.chinacache.net CNAME www.gov.cncssr.chinacache.net CNAME www.gov.foreign.ccgslb.com CNAME wac.0b51.edgecastcdn.net CNAME gp1.wac.v2cdn.net A 68.232.35.119
305     Standard query response CNAME www.gov.chinacache.net CNAME www.gov.cncssr.chinacache.net CNAME www.gov.foreign.ccgslb.com CNAME wac.0b51.edgecastcdn.net CNAME gp1.wac.v2cdn.net A 68.232.35.119
306     Standard query A www.gov.cn
307     Standard query response CNAME www.gov.chinacache.net CNAME www.gov.cncssr.chinacache.net CNAME www.gov.foreign.ccgslb.com CNAME wac.0b51.edgecastcdn.net CNAME gp1.wac.v2cdn.net A 68.232.35.119
308     Standard query response CNAME www.gov.chinacache.net CNAME www.gov.cncssr.chinacache.net CNAME www.gov.foreign.ccgslb.com CNAME wac.0b51.edgecastcdn.net CNAME gp1.wac.v2cdn.net A 68.232.35.119
309     Standard query A www.gov.chinacache.net
310     Standard query response CNAME www.gov.cncssr.chinacache.net CNAME www.gov.foreign.ccgslb.com CNAME wac.0b51.edgecastcdn.net CNAME gp1.wac.v2cdn.net A 68.232.35.119
311     Standard query A www.gov.cncssr.chinacache.net
312     Standard query response CNAME www.gov.foreign.ccgslb.com CNAME wac.0b51.edgecastcdn.net CNAME gp1.wac.v2cdn.net A 68.232.35.119
313     Standard query A www.gov.foreign.ccgslb.com
314     Standard query response CNAME wac.0b51.edgecastcdn.net CNAME gp1.wac.v2cdn.net A 68.232.35.119
315     Standard query A wac.0b51.edgecastcdn.net
316     Standard query response CNAME gp1.wac.v2cdn.net A 68.232.35.119
317     Standard query A gp1.wac.v2cdn.net
318     Standard query response A 68.232.35.119
319     Standard query DNSKEY <Root>
320     Standard query response DNSKEY DNSKEY RRSIG
321     Standard query DS cn
322     Standard query response
323     Standard query DS net
324     Standard query response DS RRSIG
325     Standard query DNSKEY net
326     Standard query response DNSKEY DNSKEY RRSIG
327     Standard query DS chinacache.net
328     Standard query response
329     Standard query DS com
330     Standard query response DS RRSIG
331     Standard query DNSKEY com
332     Standard query response DNSKEY DNSKEY RRSIG
333     Standard query DS ccgslb.com
334     Standard query response
335     Standard query DS edgecastcdn.net
336     Standard query response
337     Standard query DS v2cdn.net
338     Standard query response
339
340   An obvious idea to avoid so many roundtrips is to serialize them together.
341   There has been an attempt to standardize such "DNSSEC stapling" [1], however
342   it's incomplete for the general case, mainly due to various intricacies -
343   proofs of non-existence, NSEC3 opt-out zones, TTL handling (see RFC 4035
344   section 5).
345
346 References:
347
348   [1] https://www.ietf.org/mail-archive/web/dane/current/msg02823.html