Re: [tor-dev] Extending BridgeDB to reallocate bridges from a blocked country to others that do not block.
On Sun, Jan 15, 2012 at 09:34:49AM -0800, Aaron wrote: This proposal outlines the required changes for BridgeDB to reallocate bridges from a blocked country to others that do not block. I guess I'll be the grumpy one here, but: doesn't bridgedb already do that, just based on how it picks its answers? Or are we trying to load balance by giving out bridges-blocked-in-China more commonly to Saudi users? I'm missing the big picture goals here. Current Status: Presently, BridgeDB does not allocate bridges to specific countries. The HTTPS distributor divides bridges into a cluster of rings. Requests for bridges are mapped to a single ring in the cluster using the class C network of the client, so that the IPv4 space is divided amongst the rings in the cluster (presently 4 rings). For an attacker to obtain the complete set of bridges she must control a number of IP addresses in diverse networks. The email based distributor uses a single ring, and bridge buckets are dumped from a single pool of unallocated bridges. Ok. Required modifications: 1. BridgeDB must be able to produce an unblocked set of bridges for a specific country, if these bridges are available. Ok. Though I'd be nervous about enabling this functionality for normal users, since it makes ask for some bridges, block them; wait for bridgedb to notice; ask for new bridges, block them easier. 2. If a bridge is blocked in a country, it must be available to users in other countries. Why does this need a modification? It is already the case, right? BridgeDB could be modified to assign bridges to geographic regions. To do so, the cluster concept must be extended to support 'geographic clusters' of bridges that correspond to a set of country codes, so that requests will be directed to a corresponding cluster, by either automatic geoip detection or by client choice. If the client can specify what country he wants to ask about, that makes the above enumeration attack even more effective. Alternately, BridgeDB could be modified to guarantee that a client requesting unblocked bridges for a region would receive these bridges, if unblocked bridges exist. Presently, patches exist for BridgeDB that mark known blocked bridges as Might be blocked, but makes no further effort to respond with unblocked bridges, even if those bridges exist. Right -- I thought we considered that a feature. We are telling the user that we think the bridges we're giving them won't work, and we're not giving them replacements because that would accelerate the defeat of the rate limiting goals. Proposed Solution 1 Modify BridgeDB to assign bridges to geographic regions. Regions are designated by a list of country codes. Regions should be balanced in size, or proportional to the number of bridge users. If a bridge is blocked in a region, the bridge should be reallocated to another region. Bridges for a region are stored in a cluster of rings. Pitfalls Bridges assigned to one geographic area are not available to clients requesting bridges from other regions. Possible Solution 2 Modify BridgeDB to dynamically produce rings of bridges 'Not blocked in' a specified country. Bridges are not mapped to a specific country or region, but BridgeDB's response would contain only unblocked bridges (if available). Again, some security analysis would be good here: in what situations are we expecting this to be a good idea? --Roger ___ tor-dev mailing list tor-dev@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-dev
Re: [tor-dev] Tor and DNS
On 01/30/2012 07:59 AM, Roger Dingledine wrote: On Thu, Jan 19, 2012 at 05:13:19PM -0500, Nick Mathewson wrote: But I think the right design is probably something like allowing clients to request more DNS info via exit nodes' nameservers, and get more info back. We should think of ways to do this that avoid extra round trips, but that should be doable. So Nick, are you thinking we want a way for exit relays to receive an already-formatted dns query inside the Tor protocol, and get it onto the network somehow heading towards their configured nameservers? Or did you have something else in mind? I wonder if we want a begin_dns relay command, sort of like the current begin and begin_dir commands, and then just let them talk TCP to one of our nameservers? Or is that too much like the previous hacks? In GNUnet, we simply send the raw DNS payload over the mesh network to the exit node (in what for you would be a new cell type), the exit node sends it out via UDP to whatever DNS server the user provided, and the exit sends the response back to the initiator. So the exit never parses the DNS request or response at all. From what I've seen so far, 512 byte cells might do just fine 90% of the time, unless of course DNSSEC somehow takes off. However, GNUnet's message size limit is 64k, so this is not something I've been studying extensively. In cases where we need to parse DNS queries (likely outside of Tor's scope), we have our own library to do so, but even there we never parse DNS queries that did not originate from our own system. In summary, I think begin_dns is a good idea, but I'm not sure you need to then talk TCP to the nameserver -- UDP ought to suffice. My 2 cents Happy hacking! Christian ___ tor-dev mailing list tor-dev@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-dev
Re: [tor-dev] DNS/DNSSEC resolving in Tor (PoC implementation)
On 01/30/2012 07:34 AM, Roger Dingledine wrote: On Thu, Jan 26, 2012 at 10:42:53PM +0100, Ondrej Mikle wrote: I decided to give it a shot in implementing full DNS/DNSSEC resolution support for Tor, here's the branch: https://github.com/hiviah/tor So it looks like Tor would get two new libraries linked in, and exit relays would inherit whatever security/stability issues libunbound has since clients can basically hand them packets that they have to parse and deal with. In my implementation, client sends only query string and RR-type (16-bit integer), relay builds the actual query packet. Thus no funny multiple queries, leaking of transaction IDs or other corner cases. Flags are set to default recursive query when relay makes the query (if anyone wants to e.g. query an authoritative server directly, he needs to make a normal TCP connection over Tor). Note that libunbound links with ldns itself. I understand your concern about adding additional binary dependencies. I can try fuzzing libunbound and ldns - I've found some issues in Knot DNS server this way. It's no model-checking, but it has the capacity to unveil weird bugs. (So far I've bent libunbound quite hard while using in various tools and from experience I can say it's pretty solid - not a single segfault or abort due to memory corruption.) The previous hack recommendation had been for the client to use ttdnsd to run dns queries as normal Tor TCP flows: https://gitweb.torproject.org/ioerror/ttdnsd.git https://gitweb.torproject.org/ioerror/ttdnsd.git/blob_plain/HEAD:/README.TorDNS which resolves the what about answers bigger than Tor's cell size question, as well as the are we really sure we want a whole dns server implementation inside Tor question, but leaves such niggling issues as so do you direct the streams to 8.8.8.8, or what? It also has the advantage that 8.8.8.8 runs a single known version of its nameserver, rather than a collection of exit relays that each offer whichever version they linked. There are few open recursive DNS (also validating) resolvers besides Google's I know of: 149.20.64.20 (DNS-OARC) 217.31.204.130 (CZ.NIC - my employer, just saying to get conflict-of-interest out of the way) Concerning Google's resolvers: I am pretty sure that there are many machines running different software hidden behind a load-balancer of 8.8.8.8 and 8.8.4.4 IPs. While I was testing DNSSEC over Tor with unbound+socat, sometimes validation worked and sometimes it didn't. What do you think about the tradeoffs here? I'd like Tor to support more of dns, but I also think it's important to avoid needing exit relays to know all the details. Short answer: at this point, I'd go for libunbound (seems good enough for the job). Long answer: we need to gather all the requirements. The Tor and DNS thread raised some important points, like masking client's transaction IDs. (lib)unbound should employ randomized IDs (in my proto-design I accidentally side-stepped the issue ;-) ) I looked at the proposals in torspec, references to DNS were mostly related to IPv6. I can write new spec for DNS resolution, and also fix/rewrite the PoC code to use begin_dns so that we can have responses longer than cell size. Little over-engineering: Having unbound server running accessible as exit-enclave in chroot on relay (with PIE, grsecurity/SELinux/AppArmor or other hardening) would be really nice, but it would also be a major pain for operators. Ondrej ___ tor-dev mailing list tor-dev@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-dev
Re: [tor-dev] Tor and DNS
On 01/30/2012 11:18 AM, Jacob Appelbaum wrote: On 01/30/2012 01:09 AM, Christian Grothoff wrote: In summary, I think begin_dns is a good idea, but I'm not sure you need to then talk TCP to the nameserver -- UDP ought to suffice. I think begin_dns is a good idea as well. Seconded, I also find it as a good idea. It seems to me that there are a few ways to do it: send the query and the type send a raw packet that is then forwarded send a variable query and a fixed type (what we do now) I think that even if DNSSEC dies tomorrow, we'd be silly to stick with the way we do things now. I also think that sending a raw packet is a bit sketchy as it basically means that you're sending client side crafted data - this usually isn't good news from an anonymity perspective. I'd suggest that client sends query string, RR type and class in the cell. The class is almost always INTERNET, but CHAOS can be useful for debugging which server of anycast cluster are you actually talking to. You'll almost never need the class CHAOS, but when you do, it will come in handy (see TXT hostname.bind and version.bind). DNSSEC: it will become very useful once DANE protocol is standardized (see https://datatracker.ietf.org/doc/draft-ietf-dane-protocol/). DANE is a certificate-pinning protocol, saying which site should have which TLS certificate or which CA should have issued it (maybe Sovereign Keys or Auditable CAs will catch on first, but there's no way of knowing yet). If begin_dns worked by sending the query and the type, we'd remove almost all possibilities of client side DNS fingerprinting but we'd add attack surface to the exit nodes... I agree. How do we evaluate exit nodes' attack surface? (I suggested fuzzing libunbound/ldns as one method). How could we hide the CHAOS queries? However, I imagine that if we wanted, we could add a new flag 'dns' that would allow various exit nodes to declare themselves open for begin_dns cells. When a user opens the DNSPort, they could select nodes flagged with 'dns' to query directly. If none existed or the query was of a generic CNAME, PTR or A record type, we could use any normally available node. With current code of relays, CNAME, A and PTR for in-addr.arpa would work. These three RR types have an advantage that they can be easily checked for resolution of private adresses (like Tor does now; though banning resolution of .local FQDNs might be added, it's a damn special case). I'd add NS, DNAME and to the default-allowed set (DNAME is quite rare, nevertheless used, there's also BNAME RFC draft that seems expired). If we want to support DNSSEC, then DS, DNSKEY, RRSIG, NSEC, NSEC3 should be allowed as well. On the 'dns' flagged exit nodes, a client could begin_dns and then we'd parse the query and the type, generate the DNS query and then ask the our locally configured name server. In an ideal world, we'd use something like unbound to do the parsing and perhaps even to do caching. libunbound as well as unbound do caching. ldns can do parsing (libunbound uses ldns). Ondrej ___ tor-dev mailing list tor-dev@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-dev
Re: [tor-dev] Tor and DNS
On 01/30/2012 06:07 PM, Ondrej Mikle wrote: On 01/30/2012 11:18 AM, Jacob Appelbaum wrote: On 01/30/2012 01:09 AM, Christian Grothoff wrote: In summary, I think begin_dns is a good idea, but I'm not sure you need to then talk TCP to the nameserver -- UDP ought to suffice. I think begin_dns is a good idea as well. Seconded, I also find it as a good idea. Glad to hear it. It seems to me that there are a few ways to do it: send the query and the type send a raw packet that is then forwarded send a variable query and a fixed type (what we do now) I think that even if DNSSEC dies tomorrow, we'd be silly to stick with the way we do things now. I also think that sending a raw packet is a bit sketchy as it basically means that you're sending client side crafted data - this usually isn't good news from an anonymity perspective. I'd suggest that client sends query string, RR type and class in the cell. The class is almost always INTERNET, but CHAOS can be useful for debugging which server of anycast cluster are you actually talking to. You'll almost never need the class CHAOS, but when you do, it will come in handy (see TXT hostname.bind and version.bind). I think that almost any record type is fine. DNSSEC: it will become very useful once DANE protocol is standardized (see https://datatracker.ietf.org/doc/draft-ietf-dane-protocol/). DANE is a certificate-pinning protocol, saying which site should have which TLS certificate or which CA should have issued it (maybe Sovereign Keys or Auditable CAs will catch on first, but there's no way of knowing yet). Agreed. DANE is an important nail in the CA Racket's coffin. :) If begin_dns worked by sending the query and the type, we'd remove almost all possibilities of client side DNS fingerprinting but we'd add attack surface to the exit nodes... I agree. How do we evaluate exit nodes' attack surface? (I suggested fuzzing libunbound/ldns as one method). How could we hide the CHAOS queries? Well - first off, we'd want to determine the places where new code is added - if we don't change current things and only add a cell type, I think that's quite easy to do. Secondly, I'd imagine that we'd want to audit the underlying library quite extensively. However, I imagine that if we wanted, we could add a new flag 'dns' that would allow various exit nodes to declare themselves open for begin_dns cells. When a user opens the DNSPort, they could select nodes flagged with 'dns' to query directly. If none existed or the query was of a generic CNAME, PTR or A record type, we could use any normally available node. With current code of relays, CNAME, A and PTR for in-addr.arpa would work. These three RR types have an advantage that they can be easily checked for resolution of private adresses (like Tor does now; though banning resolution of .local FQDNs might be added, it's a damn special case). Right. We could certainly enable inspection at DNSPort time - it can check for RFC1918 addresses. I personally want a way to know what a server replied with - even if it might be harmful, I want a true, verifiable answer. I also want a way to ensure that it doesn't shoot people in the foot. So, perhaps we can do both? I'd add NS, DNAME and to the default-allowed set (DNAME is quite rare, nevertheless used, there's also BNAME RFC draft that seems expired). I'd like to see - TXT, SSHFP, CHAOS, NS, DNAME, , A, PTR, CNAME, DS, DNSKEY, RRSIG, NSEC, NSEC3, CERT, IPSECKEY, KEY, SOA, MX, SRV, SPF It's becoming very difficult to use Tor without native SRV record for say, Jabber and the same is true for MX and other types. Basically, the entire list: http://en.wikipedia.org/wiki/List_of_DNS_record_types If we want to support DNSSEC, then DS, DNSKEY, RRSIG, NSEC, NSEC3 should be allowed as well. Agreed. On the 'dns' flagged exit nodes, a client could begin_dns and then we'd parse the query and the type, generate the DNS query and then ask the our locally configured name server. In an ideal world, we'd use something like unbound to do the parsing and perhaps even to do caching. I think it's reasonable to separate it into two tasks - 'dns' flagged exits would require supporting begin_dns - caching is something we should probably have but a full unbound cache is something perhaps huge to put into the same process. libunbound as well as unbound do caching. ldns can do parsing (libunbound uses ldns). I think that seems OK. I think the first step is a proposal, the second step is likely to implement whatever begin_dir means, a third step is another proposal where we add the dns flag to the Tor spec; likely we'd find that the second step requires a cache... Thanks for hacking on this! All the best, Jacob ___ tor-dev mailing list tor-dev@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-dev