[tor-dev] Tor and DNS - draft finalized into proposal

Nick Mathewson nickm at alum.mit.edu
Mon Mar 12 18:08:15 UTC 2012

On Sat, Mar 10, 2012 at 9:22 AM, Ondrej Mikle <ondrej.mikle at gmail.com> wrote:
> Hi all,
> the DNS/DNSSEC resolving draft for seems to be finished.

Hi, Ondrej!  I've got a few questions and comments.  I might have more
once I've thought a little more about the issues on this.

> I added a few thoughts on mitigating circuit correlation (mentioned in proposal
> 171). Somebody could look at those if they are not totally stupid (last two
> paragraphs of section 7).
> A note is added about the "DNSSEC stapling" [1] (extremely difficult, won't be
> implemented).
> The draft is here (full text pasted at the end of this mail):
> https://github.com/hiviah/torspec/blob/master/proposals/ideas/xxx-dns-dnssec.txt
> The draft could probably be given a "proposal number" and merged into torspec
> proposals directory unless there is an objection.
> I'll leave few weeks (2-3) in case someone finds a vulnerability or has an
> objection. After that I could slowly begin implementing it in a separate branch.
> [1] https://lists.torproject.org/pipermail/tor-dev/2012-February/003285.html
> Ondrej
> ---- pasted proposal (hopfully will wrap well) ----
> Filename: xxx-dns-dnssec.txt
> Title: Support for full DNS and DNSSEC resolution in Tor
> Authors: Ondrej Mikle
> Created: 4 February 2012
> Modified: 10 March 2012
> Status: Draft
> 0. Overview
>  Adding support for any DNS query type to Tor, as well as DNSSEC support.
> 0.1. Motivation
>  Many applications running over Tor need more than just resolving FQDN to
>  IPv4 and vice versa. Sometimes to prevent DNS leaks the applications have to
>  be hacked around to be supplied necessary data by hand (e.g. SRV records in
>  XMPP). TLS connections will benefit from planned TLSA record that provides
>  certificate pinning to avoid another Diginotar-like fiasco.
>  DNSSEC is part of the DNS protocol and the most appropriate place for DNSSEC
>  API would be probably in OS libraries (e.g. libc). However that will
>  probably take time until it becomes widespread.
>  On the Tor's side (as opposed to application's side), DNSSEC will provide
>  protection against DNS cache-poisoning attacks (provided that exit is not
>  malicious itself, but still reduces attack surface).
> 1. Design
> 1.1 New cells
>  There will be two new cells, RELAY_DNS_BEGIN and RELAY_DNS_RESPONSE (we'll
>  use DNS_BEGIN and DNS_RESPONSE for short below).
>  DNS_BEGIN payload:
>    DNS packet data (variable length)
>  The DNS packet must be generated internally by libunbound to avoid
>  fingerprinting users by differences in client resolvers' behavior.

Have you looked at the ldns API?  From what I can tell, it is what
libunbound uses internally, and is what actually generates and handles
the queries.

Also, from a spec POV, it's better to say "The format must match that
used by"... than "the packet must be generated by"

Last time we talked about this, we mentioned that some fields (like
the request ID) that we wanted to clean up, and some flags we wanted
to disallow.  Did we decide not to do that?

>  DNS_RESPONSE payload:
>    total length (2 octets)
>    data         (variable)
>  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).

As noted in the last mail, total_length is needless here; RELAY
packets already have a length field.

> 2. Interfaces to applications
>  DNSPort evdns - existing implementation will be updated to use DNS_BEGIN.
>  SOCKS proxy - new command will be added, containing RR type, class and
>  query.  Response will simply contain the DNS packet.

This would need an actual specification.

> 3. New options in configuration file
>  libunbound takes couple of parameters, e.g. trust anchors and cache-size. In
>  order not to put them all into torrc, there will be only one option,
>  configuration file name. Tor will be distributed with some sensible
>  defaults.  New option will be named UnboundConfig and value will be
>  filename.
>  An option DNSQueryPolicy will determine what query types and classes are
>  permitted:
>   - common - class INTERNET, RR types listed on
>     https://en.wikipedia.org/wiki/List_of_DNS_record_types#Resource_records
>   - full - any query type and class is allowed
>  Class CHAOS in "common" would not be of much use, since its prevalent use is
>  for asking authoritative servers.
>  For client side, full validation would be optional described by option
>  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
>  Exit nodes will signal their resolving capability by two flags:
>   - CommonDNS - reflects "common" DNSQueryPolicy
>   - FullDNS - reflects "full" DNSQueryPolicy
>  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
>  There will be one instance of ub_ctx (libunbound resolver structure) in Tor,
>  libunbound is thread-safe.

Hm. Looking at the libunbound codebase, it makes me pretty sad that
Libunbound wants to open up a separate thread so that it can do its
own libevent-based event loop.  Is there no way we can make libunbound
(or ldns) integrate with our own event loop?

Also, for the record, I'm a little confused about the feature sets
here.  What does libunbound add to ldns here that we need?

>  Client will periodically purge incomplete DNS replies. Any unexpected
>  DNS_RESPONSE will be dropped.
>  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
>  whatever IP is in A/AAAA. We won't send any NSEC/NSEC3 back in case FQDN
>  does not exist, it would needlessly complicate things. Client can check by
>  extra query on DNSPort.

What fraction of clients actually use DNSPort as opposed as to just
doing everything via SOCKS connect requests?  I worry that, by leaving
RELAY_BEGIN users out of this entirely, we're making a feature that
most clients just won't wind up using.  I wonder whether the earlier
idea of having a RELAY_BEGIN_DNS that does both the lookup and a
connect wouldn't be a good idea -- both to save the round-trip, and to
give the client the appropriate dnssec information.

And I *do* think that the dnssec information would be useful to the
client: Even though we can't check whether the exit really connected
to the requested IP or not, we're going to cache that IP, and perhaps
ask other exits to connect to it when we want to connect to the
corresponding hostname.


In a final version of this document, I'd like to see a more rigorous
(pseudocode?) description of what the client and the exit node need to
check when, and what they do in response.  (e.g., "upon receiving a
FOO cell, the exit node verifies that Bar.  If not, ...") This would
make the implementation easier to check against the spec, and the spec
easier for dns gurus to audit.


More information about the tor-dev mailing list