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.