Ending DNS Hijacking with DNSCrypt

Nykolas Z
4 min readMar 19, 2018

--

I was at a Marriot hotel last week with my family and I noticed that they were doing DNS hijacking and redirecting all my DNS requests to their own servers.

It would not be a big deal, if wasn't for the fact that I had OpenDNS Family Filter setup on the laptop that the kids were using — and it wasn't working due to the DNS hijacking.

DNSCrypt to the rescue

At first, it was frustrating to see that the filters I had manually configured were not working, but I decided to take this opportunity and take my DNS privacy seriously by leveraging DNSCrypt in there.

If you are not familiar with DNSCrypt, it is a new protocol by Frank Denis and Yecheng Fu, that encrypts and authenticates all DNS traffic — Exactly what I needed to prevent any hotel or ISP from hijacking my connections.

Configuring DNSCrypt

The kids laptop are running the latest version of Ubuntu — 17.10, so in this document I will show the steps I took to get DNSCrypt configured and running there. I will be using the awesome DNSCrypt-proxy v2 by Frank Denis.

First, open your terminal and download and untar latest DNSCrypt-proxy version:

$ cd /opt

$ wget https://github.com/jedisct1/dnscrypt-proxy/releases/download/2.0.7/dnscrypt-proxy-linux_x86_64-2.0.7.tar.gz

$ tar -zxvf dnscrypt-proxy-linux_x86_64–2.0.7.tar.gz

$ mv linux-x86_64 dnscrypt

$ cd dnscrypt

That will download the set the basic files for DNSCrypt-proxy inside /opt/dnscrypt. Once that part is done, you need to run some commands as root (using sudo) to install DNSCrypt:

$ mv example-dnscrypt-proxy.toml dnscrypt-proxy.toml

$ sudo ./dnscrypt-proxy -service install
[2018–03–18 19:00:10] [NOTICE] Source [https://download.dnscrypt.info/resolvers-list/v2/public-resolvers.md] loaded
[2018–03–18 19:00:10] [NOTICE] dnscrypt-proxy 2.0.7

$ sudo ./dnscrypt-proxy -service start
[2018–03–18 19:00:20] [NOTICE] Source [https://download.dnscrypt.info/resolvers-list/v2/public-resolvers.md] loaded
[2018–03–18 19:00:20] [NOTICE] dnscrypt-proxy 2.0.7
[2018–03–18 19:00:20] [NOTICE] Service started

Having done that part, you should have DNSCrypt-proxy running at 127.0.0.1 port 53. You can verify it is working by doing:

$ dig -t A google.com @127.0.0.1
; <<>> DiG 9.10.3-P4-Ubuntu <<>> -t A google.com @127.0.0.1
;google.com. IN A
google.com. 527 IN A 172.217.194.101

$ sudo netstat -uanep |grep dnscryp
udp 0 0 127.0.0.1:53 0.0.0.0:* 0 22777 2014/dnscrypt-proxy

All good, but now we need to configure our system to use DNSCrypt-proxy instead of the default resolver at 127.0.0.53 (from systemd). You can do it manually for testing by modifying the /etc/resolv.conf file:

$ echo “nameserver 127.0.0.1” > /etc/resolv.conf

And test that your DNS still works. However, that won't last after a reboot. Ubuntu have messed up with DNS since they added the systemd-resolved, making it more complicated than what it should be. I tried multiple options to stick to only 127.0.0.1 (where dnscrypt-proxy is running), but none of them would stick — or it would be rotated with the DNS server received via DHCP.

At the end, I actually disabled systemd-resolve to avoid any more issues and set 127.0.0.1 as the default nameserver:

$ systemctl stop systemd-resolved

$ systemctl disable systemd-resolved

$ echo “dns-nameservers 127.0.0.1” >> /etc/network/interfaces

That did the tricky and stuck between restarts. If anyone has a better way to fully override the Name server on Ubuntu 17.10, let me know.

Parental Control with DNSCrypt

The final part was to configure OpenDNS with DNSCrypt-proxy. It took me a while to realize that it is called "cisco-familyshield" in the DNSCrypt configuration (not opendns), so that alone will save you some time there.

Unfortunately, OpenDNS and DNSCrypt did not work as expected. I kept getting a timeout error, and after some troubleshooting it seems that their DNSCrypt port was down from the hotel network.

Because of that, I decided to try some other providers. Both AdGuard, Comodo and CleanBrowsing support DNSCrypt, so I tried all of them:

Mar 16 20:01:22 dnscrypt-proxy[1167]: [2018–03–18 20:01:22] [NOTICE] [adguard-dns-family] OK (crypto v1) — rtt: 204ms
Mar 16 20:01:22 dnscrypt-proxy[1167]: [2018–03–18 20:01:22] [NOTICE] [cleanbrowsing-family] OK (crypto v1) — rtt: 12ms
Mar 16 20:01:22 dnscrypt-proxy[1167]: [2018–03–18 20:01:22] [NOTICE] [comodo-02] OK (crypto v1) — rtt: 58ms
Mar 16 20:01:22 dnscrypt-proxy[1167]: [2018–03–18 20:01:22] [NOTICE] Server with the lowest initial latency: cleanbrowsing-family (rtt: 12ms)

For some reason, having all 3 together also did not work as well. I still have to research what happened, but it seems that on a NXDOMAIN, it was trying a secondary server. Plus, the comodo-02 wasn't restricting adult content via DNSCrypt — still have to understand why.

To avoid wasting more time, I decided to stick with just 1. I chose CleanBrowsing as it had the better performance of the 3 and it fared very well on my comparison between providers.

The DNSCrypt-proxy configuration is very simpple and you can set a specific provider by adding a "server_names" in the /opt/dnscrypt/dnscrypt-proxy.toml configuration file:

server_names = [‘cleanbrowsing-family’]

Once that is done, you need to restart DNSCrypt and verify it is working by trying to do a DNS lookup of an adult site:

$ /opt/dnscrypt/dnscrypt-proxy -service restart

$ dig por[n[hub dot com
por[n]hub.com. 22 IN SOA cleanbrowsing.rpz.noc.org. accesspolicy.rpz.noc.org. 1 7200 900 1209600 86400
;; Query time: 18 msec

And that's pretty much it. It feels harder than what it should have been, specially due to the issues with the Ubuntu DNS resolver. I envy the time back in the day when only editing /etc/resolv.conf would have been enough.

Thanks Marriot for your DNS hijacking. You made me paranoid enough to learn and setup DNSCrypt-proxy.

--

--