dnscrypt-proxy as a forwarder for BIND

I’m always looking for ways I can add layers of encryption and security to my network and I recently came across the DNSCrypt project created by OpenDNS. This toolset and infrastructure encrypts DNS queries from your machine or network so that your ISP can’t snoop on them. I decided to set up dnscrypt-proxy as a forwarder on my home router so that all DNS traffic leaving my network is encrypted.

I run BIND on my Ubuntu-based mini-PC router. A rough diagram of how DNS queries flow through my network is below, where green indicates a trusted zone or encrypted link, and red indicates untrusted/unencrypted.

My goal is to insert dnscrypt-proxy into the DNS query flow to encrypt all queries along as they transit the untrusted zone. What we will end up with is this:

dnscrypt-proxy Installation and First Run

Installation and startup is easy:

apt install dnscrypt-proxy
systemctl start dnscrypt-proxy

Check to make sure it is running and determine which IP/port it listens on:

$ lsof -i -n | grep dnscrypt
dnscrypt- 27114 _dnscrypt-proxy 3u IPv4 15407729 0t0 TCP 127.0.2.1:domain (LISTEN)
dnscrypt- 27114 _dnscrypt-proxy 4u IPv4 15407730 0t0 UDP 127.0.2.1:domain

By default dnscrypt is configure to use the OpenDNS/Cisco resolver and I suggest you keep using it during setup because they offer a nifty utility to validate you are dnscrypt enabled. You can change it after you know everything works, if you want. Check the IP address of the resolver in use using:

$ systemctl status dnscrypt-proxy
dnscrypt-proxy.service - DNSCrypt proxy
Loaded: loaded (/lib/systemd/system/dnscrypt-proxy.service; enabled; vendor preset: enabled)
Active: active (running) since Sun 2017-12-10 15:50:23 EST; 10s ago
Docs: man:dnscrypt-proxy(8)
Main PID: 27857 (dnscrypt-proxy)
Tasks: 1
Memory: 260.0K
CPU: 17ms
CGroup: /system.slice/dnscrypt-proxy.service
└─27857 /usr/sbin/dnscrypt-proxy --resolver-name=cisco

Dec 10 15:50:23 duchess dnscrypt-proxy[27857]: [WARNING] - [cisco] logs your activity - a different provider might be better a choice if privacy is a concern
Dec 10 15:50:23 duchess dnscrypt-proxy[27857]: [NOTICE] Starting dnscrypt-proxy 1.6.1
Dec 10 15:50:23 duchess dnscrypt-proxy[27857]: [INFO] Done
Dec 10 15:50:23 duchess dnscrypt-proxy[27857]: [INFO] Server certificate #1490391488 received
Dec 10 15:50:23 duchess dnscrypt-proxy[27857]: [INFO] This certificate is valid
Dec 10 15:50:23 duchess dnscrypt-proxy[27857]: [INFO] Chosen certificate #1490391488 is valid from [2017-03-25] to [2018-03-25]
Dec 10 15:50:23 duchess dnscrypt-proxy[27857]: [INFO] Server key fingerprint is E7F8:4477:BF89:1434:1ECE:23F0:D6A6:6EB9:4F45:3167:D71F:80BB:4E80:A04F:F180:F778
Dec 10 15:50:23 duchess dnscrypt-proxy[27857]: [NOTICE] Proxying from 127.0.2.1:53 to 208.67.220.220:443
Dec 10 15:50:23 duchess systemd[1]: Started DNSCrypt proxy.

If you want to see that your queries are not leaving in plain text, use tcpdump:

tcpdump -i enp2s0 -A host 208.67.220.220

Run this test query which will return the IP of the resolver you have chosen, in this case Opendns/Cisco:

hostip -r 127.0.0.1 resolver.dnscrypt.org

And this query which will give some more details about the setup plus confirm that you are using dnscrypt from the local machine:

$ dig debug.opendns.com txt

; <<>> DiG 9.10.3-P4-Ubuntu <<>> debug.opendns.com txt
 ;; global options: +cmd
 ;; Got answer:
 ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 33886
 ;; flags: qr rd ra; QUERY: 1, ANSWER: 6, AUTHORITY: 13, ADDITIONAL: 5

;; OPT PSEUDOSECTION:
 ; EDNS: version: 0, flags:; udp: 4096
 ;; QUESTION SECTION:
 ;debug.opendns.com. IN TXT

;; ANSWER SECTION:
 debug.opendns.com. 0 IN TXT "actype 0"
 debug.opendns.com. 0 IN TXT "source 108.52.34.196:50221"
 debug.opendns.com. 0 IN TXT "server m61.ash"
 debug.opendns.com. 0 IN TXT "flags 20 0 70 7950800000000000000"
 debug.opendns.com. 0 IN TXT "dnscrypt enabled (713156774457306E)"
 debug.opendns.com. 0 IN TXT "originid 0"

You should see some gibberish come across in your tcpdump window. Success!

Configure BIND to Forward to dnscrypt-proxy

Once BIND is configured as a forwarder, all clients on the network will have their queries transparently forwarded through dnscrypt without any changes required on the endpoints themselves. Edit /etc/bind/named.conf.options and add a forwarders block:

options {
    ...
    forwarders {
        127.0.2.1;
    };
    ...
};

Restart BIND (systemctl restart bind9) and do another test query from a different machine on the network. You should see some more gibberish come across your tcpdump window and the query should return successfully. Success! Before we forget, make sure dnscrypt-proxy starts on every boot:

systemctl enable dnscrypt-proxy

Change dnscrypt Resolver and Other Config

Last, you’ll want to choose a dnscrypt resolver that you trust. The current list of resolvers is here: https://dnscrypt.org/dnscrypt-resolvers.html Once you have chosen one, edit /etc/default/dnscrypt-proxy.conf and change DNSCRYPT_PROXY_RESOLVER_NAME.

You should also review the man page for dnscrypt-proxy and see if there are other options you want to configure. I added “-E” to DNSCRYPT_PROXY_OPTIONS so that a new key is generated for every query. I am not concerned about query performance because my little router does very little work.

Restart dnscrypt-proxy and check to see that the new resolver’s IP address is listed in `systemctl status dnscrypt-proxy`. If it is, you are done! Now all your DNS traffic is encrypted and protected from your ISP’s snooping.

Leave a Reply

Your email address will not be published. Required fields are marked *