Hi,
I've updated the Tor DNS/DNSSEC draft from what was said in this thread. Short summary of changes:
- drop IDs (use StreamID), drop length from DNS_RESPONSE, keep just uint16_t total_length - separate tool for AXFR so that server can be specified - validation always on client side by default - full DNS packets sent in DNS_BEGIN (generated by libunbound)
Other changes (mostly minor):
- IXFR not supported (rare corner case) - "common" DNS policy - if updates between Tor versions change this "allowed set" (e.g. new RR type), exit node with old Tor version simply returns REFUSED - specified the algorithm of TTL normalization
Link to full text (diff is pasted at the end of this mail):
https://github.com/hiviah/torspec/blob/master/proposals/ideas/xxx-dns-dnssec...
Ondrej
Diff:
diff --git a/proposals/ideas/xxx-dns-dnssec.txt b/proposals/ideas/xxx-dns-dnssec.txt index 865e06d..ea711ce 100644 --- a/proposals/ideas/xxx-dns-dnssec.txt +++ b/proposals/ideas/xxx-dns-dnssec.txt @@ -33,26 +33,22 @@ Status: Draft
DNS_BEGIN payload:
- RR type (2 octets) - RR class (2 octets) - ID (2 octets) - length (1 octet) - query (variable) + DNS packet data (variable length)
- The RR type and class match counterparts in DNS packet. ID is for - identifying which data belong together, since response can be longer than - single cell's payload. The ID MUST be random and MUST NOT be copied from - xid of request DNS packet (in case of using DNSPort). + The DNS packet must be generated internally by libunbound to avoid + fingerprinting users by differences in client resolvers' behavior.
DNS_RESPONSE payload:
ID (2 octets) - data length (2 octets) - total length (4 octets) + total length (2 octets) data (variable)
- Data contains the reply DNS packet. Total length describes length of - complete response packet. + Data contains the reply DNS packet or its part if packet would not fit into + the cell. Total length describes length of complete response packet. + + AXFR and IXRF are not supported in this cell by design (see specialized tool + below).
2. Interfaces to applications
@@ -80,11 +76,9 @@ Status: Draft for asking authoritative servers.
For client side, full validation would be optional described by option - DNSValidation (0|1). (TODO: what is a sensible default? Validation is not - much useful in A/AAAA case, but for instance SRV, TXT and TLSA are a - different case. Only reason for turning validation off is a faster - round-trip. We can also leave it to validating resolver that uses DNSPort as - forwarder.) + DNSValidation (0|1). By default validation is turned on, otherwise it would + be easy to fingerprint people who turned it on and asked for not-so-common + records like SRV.
4. Changes to directory flags
@@ -93,9 +87,12 @@ Status: Draft - CommonDNS - reflects "common" DNSQueryPolicy - FullDNS - reflects "full" DNSQueryPolicy
- (TODO: how do we handle adding new RR types to "common" as they are created? - One option would be to create CommonDNS_1 ... CommonDNS_N such that - CommonDNS_{N-1} is subset of CommonDNS_N.) + Exit node asked for a RR type not in CommonDNS policy will return REFUSED in + as status in the reply DNS packet contained in DNS_RESPONSE cell. + + If new types are added to CommonDNS set (e.g. new RFC adds a record type) + and exit node's Tor version does not recognize it as allowed, it will send + REFUSED as well.
5. Implementation notes
@@ -105,8 +102,7 @@ Status: Draft Client will periodically purge incomplete DNS replies. Any unexpected DNS_RESPONSE will be dropped.
- Request for special names (.onion, .exit, .noconnect) will return SERVFAIL - (for NXDOMAIN we'd have to implement NSEC/NSEC3). + Request for special names (.onion, .exit, .noconnect) will return REFUSED.
RELAY_BEGIN would function "normally", there is no need for returning DNS data. In case of malicious exit, client can't check he's really connected to @@ -116,21 +112,52 @@ Status: Draft
AD flag must be zeroed out on client unless validation is performed.
-6. Security implications +6. Separate tool for AXFR
- Client as well as exit MUST block attempts to resolve local RFC 1918, 4193, - 4291 adresses (PTR) or local names (e.g. "*.local") in order not to leak - unnecessary information about home network. (TODO: TLD whitelist instead of - filtering "*.local" names? That would require exit node to periodically - update list from ICANN.) + The AXFR tool will have similar interface like tor-resolve, but will + return raw DNS data. + + Parameters are: query domain, server IP of authoritative DNS.
- An exit resolving names SHOULD use libunbound for all types of resolving so - that an attacker eavesdropping will have it harder to distinguish which - names were queried by connect command and which using the DNS subsystem - (TODO: will this really help, since attacker can guess from RR type and - whether or not a TCP connection follows?) + The tool will transfer the data through "ordinary" tunnel using RELAY_BEGIN + and related cells. + + This design decision serves two goals: + + - DNS_BEGIN and DNS_RESPONSE will be simpler to implement (lower chance of + bugs) + - in practice it's often useful do AXFR queries on secondary authoritative + DNS servers + + IXFR will not be supported (infrequent corner case, can be done by manual + tunnel creation over Tor if truly necessary). + +7. Security implications + + Client as well as exit MUST block attempts to resolve local RFC 1918, 4193, + 4291 adresses (PTR).
- TTL in reply DNS packet MUST be somehow normalized at exit node so that - client won't learn what other clients queried. Transaction ID is provided - randomly by libunbound, no need to modify. This affects only DNSPort and + An exit node resolving names will use libunbound for all types of resolving, + including lookup of A/AAAA records when connecting stream to desired + server. Ordinary streams will gain a small benefit of defense against DNS + cache poisoning on exit node's network. + + Transaction ID is provided randomly by libunbound, no + need to modify. This affects only DNSPort and SOCKS interfaces. + +8. TTL normalization idea + + Complex on implementation, because it requires parsing DNS packets at exit + node. + + TTL in reply DNS packet MUST be normalized at exit node so that client won't + learn what other clients queried. The normalization is done in following + way: + + - for a RR, the original TTL value received from authoritative DNS server + should be used when sending DNS_RESPONSE, trimming the values to interval + [5, 600] + - does not pose "ghost-cache-attack", since once RR is flushed from + libunbound's cache, it must be fetched anew +