Hacking public DNS providers for Total Privacy

Omer Zohar
Apr 20, 2018 · 5 min read

The competition in the free DNS service has became more fierce as Cloudflare with 1.1.1.1 had joined google’s 8.8.8.8, Cisco’s OpenDns, Quad9’s 9.9.9.9 and many more Providers and ISPs resolvers out there.

Cloudflare main claim to fame is their speed, and indeed recent benchmarks had shown that other than your own ISP servers, they’re true to their word.

Another often disregarded feature that was emphasized with this release is the support for DNS over TLS and DNS over HTTPS (DOH), which allows for increased privacy from anyone snooping on your queries, either the local internet cafe or your own ISP (or state?). It also provides protection from attacks such as the all-too-easy DNS Man-In-the-Middle, cache poisoning and many others.

But what is the price for these services? No free service is actually free. As the saying goes “When you don’t know what is the product, YOU are the product”. Even though in its privacy policy Cloudflare promise it will not keep any identifiable data, they do save some aggregated data. Of course, Cloudflare is not alone in this. All vendor collect some of their data to their usage, see the below table or read this comparison to dig deeper:

Comparison between the main free public DNS Services

It is apparent that no service is fully TNO (Trust No One) compliant. So what does one who wants to keep his full DNS usage from reaching one of these vendors? There are few options that comes to mind:

  1. Use a local ISP DNS Resolver. This of course will put all data in hands of the ISP, which might or not use that data. It is certainly been the case in recent years that ISPs use this data as a mean of added income, like placing ads and redirects on non existing lookups, or just sell the data to other vendors.
  2. Run your own DNS Resolver. This will probably put your mind at ease in regards to the usage of data of the local resolver, but keep in mind as that as a sole user on that server the DNS Resolvers upstream will still get your queries. It is also quite difficult technically to properly and securely maintain a DNS resolver (think hosting, bandwidth, security updates, configurations…)
  3. Split your queries across multiple vendors. This way, none of them will have your entire DNS activity. For the paranoid: create some background queries of random domains to further skew your profile.

Obviously we prefer № 3. But how is it done? It is actually quite easy to do using DNScrypt-Proxy — A flexible DNS proxy, with support for modern encrypted DNS protocols such as DNSCrypt v2 and DNS-over-HTTPs.

Once installed and configured as our main DNS resolver, we’ll use DNScrypt to randomly select a different DNS server for every query we make. The resolvers will be selected from a list of vetted DNS list according to a criteria that we’ll select: Resolvers who claim not to save any logs, does not filter any data and are either using DNSCrypt, DoT or DoH.

Sounds easy right? it surprisingly is.

Lets get started by installing DNScrypt-Proxy by following the instruction on their wiki page. They provide a list of binaries to choose from according to the platform you’re using on.

Once that’s done, we’ll configure it according to our needs. We’ll start with the example config file:

cp example-dnscrypt-proxy.toml dnscrypt-proxy.toml

The example script is actually pretty well configured for our needs. we really need to change very few things. First is the load balancing strategy, which will determine which server will be elected for every query. we will go with random:

lb_strategy = 'random'

We want to make sure no UDP plaintext protocol will be used:

force_tcp = true

Disable tls session tickets to make it harder for passive tls decryption on continuous connections:

tls_disable_session_tickets = true

Make sure the configured system dns never get used:

ignore_system_dns = true

We let DNScrypt know what kind of restrictions we want for the DNS resolvers it connects to, to make sure we only connect to resolver that meet out demands (no filtering, no logging, use only secure connection):

dnscrypt_servers = true

DNScrypt will use these lists of resolvers (one, two) and will filter them according to your selection. You can of course manually add or remove resolvers as you see fit.

Finally, if you plan on using the proxy on any other machine other the one its currently running on, change the listening address:

֫listen_addresses = ['XX.XX.XX.XX:53', '[::XX]:53']

now we’re ready to run DNScrypt:

root@kali:~/linux-x86_64# ./dnscrypt-proxy 
[2018-04-19 15:32:35] [INFO] Loading source information from URL [https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v2/public-resolvers.md]
[2018-04-19 15:32:35] [INFO] Loading source information from URL [https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v2/public-resolvers.md.minisig]
[2018-04-19 15:32:35] [NOTICE] Source [public-resolvers.md] loaded
[2018-04-19 15:32:35] [NOTICE] dnscrypt-proxy 2.0.9
[2018-04-19 15:32:35] [NOTICE] Now listening to 127.0.0.1:53 [UDP]
[2018-04-19 15:32:35] [NOTICE] Now listening to 127.0.0.1:53 [TCP]
[2018-04-19 15:32:35] [NOTICE] Now listening to [::1]:53 [UDP]
[2018-04-19 15:32:35] [NOTICE] Now listening to [::1]:53 [TCP]
[2018-04-19 15:32:36] [NOTICE] [arvind-io] OK (crypto v2) - rtt: 196ms
...
...
...
18-04-19 15:32:53] [NOTICE] [soltysiak] OK (crypto v1) - rtt: 77ms
[2018-04-19 15:32:53] [NOTICE] [trashvpn] OK (crypto v2) - rtt: 88ms
[2018-04-19 15:32:54] [NOTICE] [ventricle.us] OK (crypto v2) - rtt: 153ms
[2018-04-19 15:32:54] [NOTICE] Server with the lowest initial latency: cloudflare (rtt: 62ms)
[2018-04-19 15:32:54] [NOTICE] dnscrypt-proxy is ready - live servers: 30

DNScrypt will choose resolvers that answer your criteria and will try to establish a connection with them, measuring their speed and checking the connection to them. Once done, it will announce the fastest server (Cloudflare, no surprises here) and the number of servers it was able to contact and validate.
Now, set you local machine DNS to the ip address DNScrypt is listening on, and you’re done! Every DNS query your machine makes will go out thru one of the 30 (!) different resolvers. How’s that for extra layer of privacy?

Not happy with running DNScrypt-proxy as a service on your local machine? no worries. It can easily be enabled in DD-WRT or Tomato firmwares of various popular routers.

So Here we are. The most secure and private DNS setup that I know of. Hopefully this short guide was helpful for you privacy nutters out there. If you have any comments or remarks please comment below!