Hey everyone,
This is an advisory for anyone running an exit node, but it also applies to any Linux setup where you don't trust your DNS server. TL;DR: this is a guide for switching unsecured DNS to DNSCrypt + Unbound, which prevents a network host from monitoring DNS lookups, thus increasing privacy for everyone using Tor.
A few weeks ago I set up some exits and I recently discovered that the host was using 8.8.8.8, Google's DNS, as a resolutions service. As in, they had "nameserver 8.8.8.8" in /etc/resolv.conf. Convenient for them, but it meant that every request was sent to Google for resolution. This is bad because Google can then track DNS lookups and so can anyone watching unencrypted DNS as it travels across the country. In fact, DNS is specifically mentioned in the "Tor Sucks" NSA slides. Compounding this, most Linux boxes don't use a DNS cache, so literally every lookup is sent to Google, so this didn't exactly inspire confidence.
After talking with cacahuatl, ncl, and pskosinski on IRC, I switched to DNSCrypt, a FOSS protocol that encrypts DNS lookups across the wire. I also set up the Unbound DNS cache, thus accelerating queries while also preventing the DNSCrypt server from observing every lookup. Then I redirect /etc/resolv.conf to use Unbound, which itself used DNSCrypt. This protected Google or my host from watching DNS lookups. Here's how I did it:
1) I installed "unbound". I have confirmed that this package is available in the Ubuntu and Fedora repositories, so most distributions probably have it. 2) I installed "dnscrypt-proxy". I installed the libsodium-dev dependency then used https://download.dnscrypt.org/dnscrypt-proxy/ to compile and install dnscrypt-proxy from source. https://github.com/jedisct1/dnscrypt-proxy#installation may be helpful here. 3) I modified Unbound's configuration per the instructions in https://www.dnscrypt.org/#dnscrypt-proxy. For the sake of convenience, you can find my configuration here: https://gist.github.com/Jesse-V/675b7ec87eca864887e6 I then reloaded Unbound to apply the updated configuration. 4) I reviewed https://github.com/jedisct1/dnscrypt-proxy/blob/master/dnscrypt-resolvers.cs... to find a provider geographically close to me. I recorded the resolver's address, provider name, and provider public key for use in the next step. 5) I ran "/usr/local/sbin/dnscrypt-proxy --resolver-address=<address> --provider-key=<publicKey> --provider-name=<name> --ephemeral-keys --local-address=127.0.53.1" in a terminal, where <address>, <publicKey>, and <name> were substituted for the information I found in step 4. 6) I ran "host torproject.org 127.0.53.1" to confirm that dnscrypt-proxy was working. 7) I ran "host torproject.org 127.0.53.53" to confirm that Unbound + dnscrypt-proxy was working. 8) I then ran the command from step 5 with the --daemonize flag so that the proxy ran in the background. 9) I added the command from step 8 to crontab, with the @reboot macro. 10) I modified /etc/resolv.conf to "nameserver 127.0.53.53".
At this point "host torproject.org" should work out of the box using DNSCrypt + Unbound and nobody but you and the DNSCrypt resolver can see your query. Be sure to review https://gist.github.com/Jesse-V/675b7ec87eca864887e6 to avoid any SERVFAIL headaches. Enjoy!
On 12/19/2015 11:23 PM, Jesse V wrote:
Hey everyone,
This is an advisory for anyone running an exit node, but it also applies to any Linux setup where you don't trust your DNS server. TL;DR: this is a guide for switching unsecured DNS to DNSCrypt + Unbound, which prevents a network host from monitoring DNS lookups, thus increasing privacy for everyone using Tor.
A few weeks ago I set up some exits and I recently discovered that the host was using 8.8.8.8, Google's DNS, as a resolutions service. As in, they had "nameserver 8.8.8.8" in /etc/resolv.conf. Convenient for them, but it meant that every request was sent to Google for resolution. This is bad because Google can then track DNS lookups and so can anyone watching unencrypted DNS as it travels across the country. In fact, DNS is specifically mentioned in the "Tor Sucks" NSA slides. Compounding this, most Linux boxes don't use a DNS cache, so literally every lookup is sent to Google, so this didn't exactly inspire confidence.
After talking with cacahuatl, ncl, and pskosinski on IRC, I switched to DNSCrypt, a FOSS protocol that encrypts DNS lookups across the wire. I also set up the Unbound DNS cache, thus accelerating queries while also preventing the DNSCrypt server from observing every lookup. Then I redirect /etc/resolv.conf to use Unbound, which itself used DNSCrypt. This protected Google or my host from watching DNS lookups. Here's how I did it:
[snip]
At this point "host torproject.org" should work out of the box using DNSCrypt + Unbound and nobody but you and the DNSCrypt resolver can see your query. Be sure to review https://gist.github.com/Jesse-V/675b7ec87eca864887e6 to avoid any SERVFAIL headaches. Enjoy!
Tor relay operators should agree on a threat model, that effectively would be the the whole Tor networkp's threat model. From the initial Tor design documents [1] we know for example that Tor does not try to protect from a "global passive adversary". We could/should elaborate on that.
Coming to your suggestion, running DNSCrypt in Tor relays. DNS is inherently problematic being neither encrypted nor authenticated (okay there is DNSSEC for authentication, but...). Using DNSCrypt will encrypt DNS queries and responses from your Tor relay to the DNSCrypt resolver.
From that point on you do not know and cannot control how the resolver
is going to do with DNS queries. And you don't know if that resolver uses Google or is compromised or is malicious etc.
So I would say that DNSCrypt basically protects you from the hosting provider of your Tor relay. And given that nature of Tor network, its threat model, the various available attacks to relays and users, I don't think there is a benefit of using DNS encryption against your ISP. Remember, your ISP is the one who routes your relay's traffic and can do all sort's of nasty things, eg traffic correlation.
On the other hand, I would say using a local DNS cache can increase both your relay's performance and perhaps offers a slight privacy gain to tor clients, given that a cached DNS response will be served directly to a tor client rather than querying an external resolver for the 2nd time.
Hope it makes sense, Cheers
Using DNSCrypt will encrypt DNS queries and responses from your Tor relay to the DNSCrypt resolver. From that point on you do not know and cannot control how the resolver is going to do with DNS queries. And you don't know if that resolver uses Google or is compromised or is malicious etc.
Why not route all DNS queries through Tor for "Plausible Deniability". The nuts and bolts are already there in the client.
On 12/19/2015 04:06 PM, Job Pfeiffer wrote:
Why not route all DNS queries through Tor for "Plausible Deniability". The nuts and bolts are already there in the client.
Tor clients already do that. Tor exits can't do that, as the client traffic has to reach the clearnet somewhere. It's probably not a good idea to build infinite loops through the Tor network.
On the other hand, I would say using a local DNS cache can increase both your relay's performance and perhaps offers a slight privacy gain to tor clients, given that a cached DNS response will be served directly to a tor client rather than querying an external resolver for the 2nd time.
Note that, whenever possible, Tor relay operators using a local DNS resolver should enable qname mininisation [1], so that the resolver only sends to the authoritative servers what they need to know to respond. Support for qname minimisation has recently been added in unbound [2] 1.5.7, and is planned in the future Knot resolver [3].
[1]: https://tools.ietf.org/html/draft-ietf-dnsop-qname-minimisation-08 [2]: https://www.nlnetlabs.nl/bugs-script/show_bug.cgi?id=648 [3]: https://github.com/CZ-NIC/knot-resolver
2015-12-20 17:21 GMT+01:00 Remi Gacogne listes+tor-relays@valombre.net:
On the other hand, I would say using a local DNS cache can increase both your relay's performance and perhaps offers a slight privacy gain to tor clients, given that a cached DNS response will be served directly to a tor client rather than querying an external resolver for the 2nd time.
Note that, whenever possible, Tor relay operators using a local DNS resolver should enable qname mininisation [1], so that the resolver only sends to the authoritative servers what they need to know to respond. Support for qname minimisation has recently been added in unbound [2] 1.5.7, and is planned in the future Knot resolver [3].
It should be noted that on Debian unbound is v. 1.4.17 and support for qname minimisation has been added in v. 1.5.7
C
On 19.12.15 16:23, Jesse V wrote:
- I modified /etc/resolv.conf to "nameserver 127.0.53.53".
Good guide, which I implemented on my exit node. But one thing I noticed from researching. Editing /etc/resolv.conf on Debian will not persist through a reboot. I followed the instructions here: http://www.bytelinux.com/make-permanent-changes-to-resolv-conf-file-on-ubunt...
To make them permanent, or at least that's what I think.
Hi,
Although I cannot say how secure this configuration is but you can run this kind of setup client side as well. So:
Bind --> DNSCrypt Proxy --> Tor --> DNSCrypt Compatible Server
The secret here is to force DNSCrypt to run over TCP only which can then be redirected through a Tor TransPort. This allows you to do several types of queries that tors own DNS port cannot do (such as SRV for xmpp). Dual stackers beware as you will default to IPv6 if you use this setup. You will need to block UDP port 443 as DNSCrypt proxy checks if it is available annoyingly leaving you exposed.
Again I cannot provide analysis as to whether this is secure as DNSCrypt could be sending personally identifiable information without my knowledge as I haven't read the source code for DNSCrypt.
Regards, spaceman
On 12/20/2015 03:04 PM, spaceman wrote:
Hi,
Although I cannot say how secure this configuration is but you can run this kind of setup client side as well. So:
Bind --> DNSCrypt Proxy --> Tor --> DNSCrypt Compatible Server
You can do this, but Tor doesn't support all types of DNS queries.
Weasel and velope on #tor-project suggested that I remove DNSCrypt entirely and let Unbound be a recursive resolver against the root DNS servers, which I have now done. This way, I'm not using a third-party DNS server and Unbound is using a large cache and DNSSEC. Although DNSSEC doesn't provide confidentiality for DNS queries, it does provide authentication and integrity checks. Unbound with a large cache and DNSSEC re-enabled is probably superior to Unbound+DNSCrypt without DNSSEC. The point still stands though; you can secure and optimize an exit's DNS using Unbound.
On 12/20/2015 03:47 PM, Green Dream wrote:
Weasel and velope on #tor-project suggested that I remove DNSCrypt entirely and let Unbound be a recursive resolver against the root DNS servers, which I have now done.
Jesse would you mind sharing how you configured this?
Certainly. My configuration files are here: https://gist.github.com/Jesse-V/66fe794bf1b9e4ccf852 Unbound does most of the hard work already and by default queries authoritative DNS servers. My configuration is based on the manpage, Fedora's default Unbound configuration, and the optimization suggestions on the Arch wiki. However, the Gist above is for Ubuntu 14.04, so feel free to merge and adapt it with your distribution.
I just realized that the word "Unbound" is the opposite of "BIND", the default DNS software. How clever of them.
On 12/20/2015 04:11 PM, Jesse V wrote:
On 12/20/2015 03:47 PM, Green Dream wrote:
Weasel and velope on #tor-project suggested that I remove DNSCrypt entirely and let Unbound be a recursive resolver against the root DNS servers, which I have now done.
Jesse would you mind sharing how you configured this?
Certainly. My configuration files are here: https://gist.github.com/Jesse-V/66fe794bf1b9e4ccf852
For some reason, the original configuration I listed there caused Unbound to take 10-15 seconds to resolve queries that it didn't have in its cache. I suspect some of the hardening flags or perhaps some of the other restrictions. This horrible performance was triggering warnings in my Tor log and many notifications in syslog. I did notice that Unbound was querying more servers than seemed necessary, which may have had something to do with it.
After several hours of trying to diagnose the issue, I replaced the configuration with the performance-enhanced one recommended in http://wiki.sysadminblog.net/Unbound and applied some of the optimization tips suggested in https://unbound.net/documentation/howto_optimise.html. I've updated the Gist to reflect the current, working, and fast configuration. Unbound now takes about 650 ms to resolve something not in its cache!
Running an exit? Check to make sure you have at least one backup DNS nameserver.
If you're using Unbound/DNS Caching AND/OR DNSCrypt-proxy/DNS Proxy with a Tor Exit node, you should read on:
--- start super tl;dr: Have a backup DNS nameserver if your cache/proxy/whatever fails.
If you run an exit node and don't do anything with DNS, it's not a bad idea to be sure you have at least one backup DNS nameserver. --- stop super tl;dr:
I've been tinkering with this Unbound and DNSCrypt stuff myself. I've certainly deviated with my own prototype setups. But let me just add a really important bit that I've found that anyone who does this should certainly know of:
Your currently-posted system has zero redundancy, which disrupts DNS lookups for your traffic if just one thing hiccups, which, if it's a fatal error in DNSCrypt OR Unbound, you just fatally terminated all DNS queries for your node. This applies to anyone, even if you're just running Unbound, Bind, or dnsmasq, if you mark your cache as primary and it fails, and you didn't name a valid secondary nameserver, your exit node just lost DNS service, and so did everyone on your circuits.
---- Start tl;dr:
Jessie's currently-posted system: You cache encrypted DNS info, which if anything fails, your clients don't get DNS info.
My system: I cache encrypted DNS info, if caching fails on a query, I bypass it until it works. If encryption fails, I bypass it until it works again (non-encryption non-caching is normal for an exit node)
I set Unbound to use 6 DNSCrypt-Proxies (Sorted by ping in case a proxy goes down temporarily or permanently). I just added more instances in Forward-zone in unbound.conf.
I set Unbound as my primary nameserver. I set a lowest-ping DNS-Crypt proxy as my secondary nameserver. I set my ISP default nameserver as my tertiary nameserver. All set in /etc/resolvconf/resolv.conf.d/head
If you're just caching and not proxying DNS queries, you should mark your secondary and tertiary as non-cached backups such as an ISP DNS or Google DNS nameserver.
If your just proxying queries, you should mark your secondary as either a proxy or non-proxy backup such as ISP or Google DNS, and regardless, your tertiary should be said non-proxy backup.
--- End tl;dr:
First, I was having problems with DNSCrypt where a lag in the DNS server would cause a DNS timeout for my client/traffic/circuit/node. So, I added more DNSCrypt-proxies (6 of them actually, in order from lowest ping to highest), and bound them to unbound.conf through multiple entries in forward-zone:. This also protects the node in case one or more of those DNSCrypt servers goes offline.
That solved 95% of my nameserver failures. So, in addition to adding my unbound local DNS interface IP to my etc/resolvconf/resolv.conf.d/head so I'd use Unbound (which is configured to only accept DNSCrypt-proxy info), I also added the primary DNSCrypt-proxy server (DNSSEC-enabled of course) on there as the secondary nameserver, so a fault in Unbound would send requests directly to the DNSCrypt-proxy server and bypass Unbound, maintaining DNS service and encryption, albeit with normal non-cached performance. The next request would reattempt on the primary nameserver, which is Unbound like I said, so each request only bypasses if Unbound fails for any reason or for any length of time.
No nameserver failures since then. However, just because, I added a tertiary nameserver, which is my ISP's default nameserver. So if everything goes up in smoke, my clients can still have normal DNS info.
Jessie, Also, in your current configuration. You have no unbound forward-zones. Which, to my understanding, is a fatal error if you're using DNSCrypt. Tor interfaces with Unbound on your 127.5.3.53, but how does Unbound know where to forward queries to DNSCrypt-proxy?
I was also playing around with "edns0" in etc/resolvconf/resolv.conf.d/head to enable extended DNS queries, particularly since we're both increasing our buffer sizes, but I'm not sure how that works with DNSCrypt servers, and that's what I'm currently playing with.
I also get notices from Tor about ignoring resolve requests because they've already been resolved. Which is funny because you'd think Tor would not be able to distinguish the difference between resolves from Unbound vs. any other "nameserver." Perhaps it's just a dnsevent that is forwarded from Unbound to Tor?
If people have questions, I might end up making a github of my own setup for them to reference. There's no point in encrypting and caching DNS if we just end up causing DNS failures on the network.
On 12/26/2015 10:33 PM, 12xBTM wrote:
Also, in your current configuration. You have no unbound forward-zones. Which, to my understanding, is a fatal error if you're using DNSCrypt. Tor interfaces with Unbound on your 127.5.3.53, but how does Unbound know where to forward queries to DNSCrypt-proxy?
Yes, because I'm no longer using DNSCrypt, just Unbound, which queries authoritative DNS servers. I'm caching as much as I can but I'm out of RAM at this point, so Unbound does have to do some recursions. I'm tempted to re-apply DNSCrypt in order to forward queries to another server that can do more caching, but I haven't done that yet.
Thanks again to the folks on IRC who correctly pointed out that DNSCrypt has the same security model as a VPN: it only protects client-server traffic and the server has to be trustworthy. Currently, I'm better to use DNSSEC and query against authoritative DNS servers than I am to turn off DNSSEC and use Unbound. If I get a second server set up, it will use DNSSEC and I'll chain the two Unbound instances together with DNSCrypt. That should give me better performance.
I'll look into setting up a fallback nameserver for redundancy as you pointed out.
Found this post about compiling and running DnsCrypt which is rather easy. https://gist.github.com/kafene/9699074
Just need to grab the newer libsodium and dnscrypt versions.
It also includes an init script.
Eran
On Sun, Dec 27, 2015 at 9:46 AM Jesse V kernelcorn@riseup.net wrote:
On 12/26/2015 10:33 PM, 12xBTM wrote:
Also, in your current configuration. You have no unbound forward-zones. Which, to my understanding, is a fatal error if you're using DNSCrypt. Tor interfaces with Unbound on your 127.5.3.53, but how does Unbound know where to forward queries to DNSCrypt-proxy?
Yes, because I'm no longer using DNSCrypt, just Unbound, which queries authoritative DNS servers. I'm caching as much as I can but I'm out of RAM at this point, so Unbound does have to do some recursions. I'm tempted to re-apply DNSCrypt in order to forward queries to another server that can do more caching, but I haven't done that yet.
Thanks again to the folks on IRC who correctly pointed out that DNSCrypt has the same security model as a VPN: it only protects client-server traffic and the server has to be trustworthy. Currently, I'm better to use DNSSEC and query against authoritative DNS servers than I am to turn off DNSSEC and use Unbound. If I get a second server set up, it will use DNSSEC and I'll chain the two Unbound instances together with DNSCrypt. That should give me better performance.
I'll look into setting up a fallback nameserver for redundancy as you pointed out.
-- Jesse V
tor-relays mailing list tor-relays@lists.torproject.org https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-relays
Bind --> DNSCrypt Proxy --> Tor --> DNSCrypt Compatible Server
You can do this, but Tor doesn't support all types of DNS queries.
This particular setup never uses Tors DNSPort. DNSCrypt runs over Tor TransPort instead as mentioned and supports all queries that DNSCrypt supports. Tors DNSPort would never support DNSCrypt.
Regards, spaceman
tor-relays@lists.torproject.org