DNSCrypt to the rescue! DNS is one of the fundamental building blocks of the Internet. It’s used any time you visit a website, send an email, have an IM conversation or do anything else online; so it makes sense to secure DNS queries before they leave your home network, right? There are several reasons why an everyday user may want to encrypt DNS and if you’re reading this you likely have your own good ones (security, privacy, anti-snooping, keeping your ISP out of your browsing habit; you name it).
DNSCrypt is a protocol that authenticates communications between a DNS client and a DNS resolver. It prevents DNS spoofing. It uses cryptographic signatures to verify that responses originate from the chosen DNS resolver and haven’t been tampered with… more about dnscrypt.
In the same way the SSL turns HTTP web traffic into HTTPS encrypted Web traffic, DNSCrypt turns regular DNS traffic into encrypted DNS traffic that is secure from eavesdropping and man-in-the-middle attacks… so let’s encrypt our DNS queries before they leave our network, next.
You’ll need (for this tutorial) a Linux Mint box or a Ubuntu Server instance in your LAN. Instead of running dnscrypt-proxy client on each machine at home (which makes little sense), we will fire up a dnscrypt-proxy service in our home network for virtually all your client machines, mobile devices and anything else that queries DNS.
Personally, I run a server (Ubuntu Server 14.04 LTS) in my LAN for DNS, DHCP, privoxy, Squid and few more services, including DNSCrypt. Be creative and use either a dedicated box or a virtual machine; you must keep it running at all times!
From Terminal: (source webupd8.org)
sudo add-apt-repository ppa:anton+/dnscrypt sudo apt-get update sudo apt-get install dnscrypt-proxy
At this point dnscrypt-proxy should be up and running, listening (locally) on 127.0.0.2 – port 53 by default. Let’s test it:
dig @127.0.0.2 -p 53 unlockforus.com
Great; the request was accepted on 127.0.0.2 – port 53, passed to the resolver and answered. That means our query was encrypted and validated before it was finally passed to the client. We’re using DNSCrypt; it’s that easy!
Now we need to fine tune the configuration to allow local network clients to use our dnscrypt-proxy as well as using a closer resolver to our location.
# Stop dnscrypt-proxy service: sudo service dnscrypt-proxy stop # Edit /etc/default/dnscrypt-proxy: sudo vi /etc/default/dnscrypt-proxy
Update the local-address:127.0.0.2:53 IP with the LAN IP of your machine/server. This will be the LAN IP the daemon will listen to so that other clients in your network can use this proxy. In my case, my server LAN IP is 192.168.1.6 as shown below:
Scroll down and find the DNSCrypt-enabled resolvers section in the configuration file. You can use any of the public DNS resolvers supporting DNSCrypt. See /usr/share/dnscrypt-proxy/dnscrypt-resolvers.csv
In my server, I’ll use okturtles – a US based upstream resolver instead of the default DNSCrypt.eu The Hague, Holland.
Save the changes and start dnscrypt-proxy once again:
sudo service dnscrypt-proxy start
dnscrypt-proxy should now be listening on the LAN IP (192.168.1.6 in my case), therefore other clients on the network should be able to use it; so let’s test it!
In the server machine run a tcpdump so you can see whether the queries to the upstream server are taking place as expected: tcpdump -i dst host … (where [network-interface] is your active network interface like eth0, etc. – you can find it using “ifconfig” -, and [resolver-address] is the resolver used in your configuration – in my case okturtles upstream resolver 18.104.22.168
sudo tcpdump -i eth0 dst host 22.214.171.124
In a network computer, change its DNS to point to your dnscrypt-proxy box (192.168.1.6 in my case), open your web-browser and visit few sites. Look at the tcpdump and make sure requests are coming from the upstream resolver as expected:
The proxy will accept incoming requests on 192.168.1.6 – port 53, add an authentication tag, forward them to the resolver, and validate each answer before passing it to the client.
Given such a setup, in order to actually start using DNSCrypt in all your clients, you need to configure their DNS settings to use the IP of your dnscrypt-proxy machine as a name server. You can do so by configuring your home router, access points, etc. to use your dnscrypt-proxy box as the local DNS server.
dnscrypt-proxy does not cache your DNS requests, so every time a DNS query is made, it is passed to the upstream resolver. Read here on how to optimize DNS lookup performance and caching with dnscrypt-proxy + dnsmasq; a light weight DNS caching server… stay tuned!