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!