Encrypted DNS with BIND and DNSCrypt
DNSCrypt is a protocol that authenticates communications between a DNS client and a DNS resolver. It works by encrypting all DNS traffic between the user and resolver, preventing any spying, spoofing or man-in-the-middle attacks. It uses cryptographic signatures to verify that responses originate from the chosen DNS resolver and haven’t been tampered with and is DNSSEC compatible. It is an open specification, with free and open source reference implementations, and it is not affiliated with any company nor organization. Free DNSCrypt-enabled resolvers are available all over the world.
DNSCrypt setup
The project provides the DNSCrypt proxy as source code and pre-built binaries for most operating systems and architectures.
root@dns:/opt# wget https://github.com/jedisct1/dnscrypt-proxy/releases/download/2.0.16/dnscrypt-proxy-linux_x86_64-2.0.16.tar.gz
root@dns:/opt# tar -xzvf dnscrypt-proxy-linux_x86_64-2.0.16.tar.gz
root@dns:/opt# mv linux-x86_64/ dnscrypt-proxy
root@dns:/opt# cd dnscrypt-proxy/
root@dns:/opt/dnscrypt-proxy# ls -la
total 7808
drwxr-xr-x 2 2000 2000 4096 Jun 22 12:29 .
drwxr-xr-x 6 root root 4096 Aug 16 2018 ..
-rwxr-xr-x 1 2000 2000 7884928 Jul 10 2018 dnscrypt-proxy
-rw-r--r-- 1 root root 14628 Aug 16 2018 dnscrypt-proxy.toml
-rw-r--r-- 1 2000 2000 841 Jul 10 2018 example-blacklist.txt
-rw-r--r-- 1 2000 2000 714 Jul 10 2018 example-cloaking-rules.txt
-rw-r--r-- 1 2000 2000 14593 Jul 10 2018 example-dnscrypt-proxy.toml
-rw-r--r-- 1 2000 2000 600 Jul 10 2018 example-forwarding-rules.txt
-rw-r--r-- 1 2000 2000 723 Jul 10 2018 example-whitelist.txt
-rw-r--r-- 1 2000 2000 818 Jul 10 2018 LICENSE
-rw-r--r-- 1 root root 39140 Jun 22 12:29 public-resolvers.md
-rw-r--r-- 1 root root 307 Jun 22 12:29 public-resolvers.md.minisig
Create the configuration file and setup the proxy to listen on 127.0.2.1:53
:
root@dns:/opt/dnscrypt-proxy# cp example-dnscrypt-proxy.toml dnscrypt-proxy.toml
root@dns:/opt/dnscrypt-proxy# vi dnscrypt-proxy.toml
[...]
#listen_addresses = ['127.0.0.1:53', '[::1]:53']
listen_addresses = ['127.0.2.1:53']
[...]
tls_cipher_suite = [52392, 49199]
[...]
Do a test run and check if it can start properly:
root@dns:/opt/dnscrypt-proxy# ./dnscrypt-proxy -list
[2019-06-23 12:02:22] [NOTICE] Source [public-resolvers.md] loaded
doh.appliedprivacy.net
arvind-io
bottlepost-dns-nl
charis
cloudflare
cpunks-ru
cs-ch
cs-swe
cs-nl
cs-nl2
cs-fi
cs-pl
cs-dk
cs-it
cs-fr
cs-fr2
cs-pt
cs-ro
cs-mo
cs-lv
cs-uk
cs-de
cs-de2
cs-ca
cs-ca2
cs-usny
cs-usil
cs-usnv
cs-uswa
cs-usdc
cs-ustx
cs-usga
cs-usnc
cs-usca
cs-usor
d0wn-is-ns2
d0wn-tz-ns1
de.dnsmaschine.net
dnscrypt.ca-1
dnscrypt.ca-2
dnscrypt.eu-dk
dnscrypt.eu-nl
dnscrypt.me
dnscrypt.nl-ns0
dnscrypt.nl-ns0-doh
dnscrypt.uk-ipv4
doh-crypto-sx
doh-ibksturm
encrypt-town
ev-va
ev-to
freetsa.org
gridns-jp
gridns-sg
ibksturm
ipredator
opennic-ethservices
opennic-ethservices2
opennic-luggs
opennic-luggs2
powerdns-doh
publicarray-au
publicarray-au-doh
publicarray-au2
publicarray-au2-doh
quad101
quad9-dnscrypt-ip4-nofilter-pri
quad9-dnscrypt-ip4-nofilter-alt
quad9-doh-ip4-nofilter-pri
quad9-doh-ip4-nofilter-alt
qualityology.com
scaleway-fr
securedns
securedns-doh
soltysiak
suami
trashvpn.de
ventricle.us
opennic-R4SAS
root@dns:/opt/dnscrypt-proxy# ./dnscrypt-proxy -check
[2019-06-23 12:02:32] [NOTICE] Source [public-resolvers.md] loaded
[2019-06-23 12:02:32] [NOTICE] Configuration successfully checked
root@dns:/opt/dnscrypt-proxy# ./dnscrypt-proxy -resolve cloudflare-dns.com
Resolving [cloudflare-dns.com]
Domain exists: yes, 3 name servers found
Canonical name: cloudflare-dns.com.
IP addresses: 104.16.249.249, 104.16.248.249, 2606:4700::6810:f8f9, 2606:4700::6810:f9f9
TXT records: v=spf1 include:no-ip.com -all
Resolver IP: 220.233.0.34 (kolanut2.exetel.com.au.)
To install as service we run:
root@dns:/opt/dnscrypt-proxy# ./dnscrypt-proxy -service install
[2019-06-23 12:02:58] [NOTICE] Source [public-resolvers.md] loaded
[2019-06-23 12:02:58] [NOTICE] dnscrypt-proxy 2.0.16
[2019-06-23 12:02:59] [NOTICE] Installed as a service. Use `-service start` to start
On Ubuntu 14.04:
root@dns:/opt/dnscrypt-proxy# cat /etc/init/dnscrypt-proxy.conf
# Encrypted/authenticated DNS proxy
description "DNSCrypt client proxy"
kill signal INT
chdir /opt/dnscrypt-proxy
start on filesystem or runlevel [2345]
stop on runlevel [!2345]
respawn
respawn limit 10 5
umask 022
console none
pre-start script
test -x /opt/dnscrypt-proxy/dnscrypt-proxy || { stop; exit 0; }
end script
# Start
exec /opt/dnscrypt-proxy/dnscrypt-proxy
On Ubuntu-16.04:
root@dns:/opt/dnscrypt-proxy# systemctl cat dnscrypt-proxy.service
# /etc/systemd/system/dnscrypt-proxy.service
[Unit]
Description=Encrypted/authenticated DNS proxy
ConditionFileIsExecutable=/opt/dnscrypt-proxy/dnscrypt-proxy
[Service]
StartLimitInterval=5
StartLimitBurst=10
ExecStart=/opt/dnscrypt-proxy/dnscrypt-proxy
WorkingDirectory=/opt/dnscrypt-proxy
Restart=always
RestartSec=120
EnvironmentFile=-/etc/sysconfig/dnscrypt-proxy
[Install]
WantedBy=multi-user.target
Testing the service startup:
root@dns:/opt/dnscrypt-proxy# ./dnscrypt-proxy -service start
[2019-06-23 12:04:04] [NOTICE] Source [public-resolvers.md] loaded
[2019-06-23 12:04:04] [NOTICE] dnscrypt-proxy 2.0.16
[2019-06-23 12:04:05] [NOTICE] Service started
root@dns:/opt/dnscrypt-proxy# systemctl status dnscrypt-proxy.service
dnscrypt-proxy.service - Encrypted/authenticated DNS proxy
Loaded: loaded (/etc/systemd/system/dnscrypt-proxy.service; enabled; vendor preset: enabled)
Active: active (running) since Sun 2019-06-23 12:04:04 AEST; 39s ago
Main PID: 25687 (dnscrypt-proxy)
CGroup: /system.slice/dnscrypt-proxy.service
└─25687 /opt/dnscrypt-proxy/dnscrypt-proxy
Jun 23 12:04:40 dns dnscrypt-proxy[25687]: [2019-06-23 12:04:40] [NOTICE] [scaleway-fr] OK (crypto v2) - rtt: 304ms
Jun 23 12:04:40 dns dnscrypt-proxy[25687]: [2019-06-23 12:04:40] [NOTICE] [securedns] OK (crypto v1) - rtt: 303ms
Jun 23 12:04:42 dns dnscrypt-proxy[25687]: [2019-06-23 12:04:42] [NOTICE] [securedns-doh] OK (DoH) - rtt: 305ms
Jun 23 12:04:42 dns dnscrypt-proxy[25687]: [2019-06-23 12:04:42] [NOTICE] [soltysiak] OK (crypto v1) - rtt: 330ms
Jun 23 12:04:43 dns dnscrypt-proxy[25687]: [2019-06-23 12:04:43] [NOTICE] [suami] OK (crypto v2) - rtt: 333ms
Jun 23 12:04:43 dns dnscrypt-proxy[25687]: [2019-06-23 12:04:43] [NOTICE] [trashvpn.de] OK (crypto v2) - rtt: 329ms
Jun 23 12:04:43 dns dnscrypt-proxy[25687]: [2019-06-23 12:04:43] [NOTICE] [ventricle.us] OK (crypto v2) - rtt: 227ms
Jun 23 12:04:43 dns dnscrypt-proxy[25687]: [2019-06-23 12:04:43] [NOTICE] [opennic-R4SAS] OK (crypto v2) - rtt: 301ms
Jun 23 12:04:43 dns dnscrypt-proxy[25687]: [2019-06-23 12:04:43] [NOTICE] Server with the lowest initial latency: quad9-dnscrypt-ip4-nofilter-pri (rtt: 9ms)
Jun 23 12:04:43 dns dnscrypt-proxy[25687]: [2019-06-23 12:04:43] [NOTICE] dnscrypt-proxy is ready - live servers: 72
We can go and enable it now:
root@dns:/opt/dnscrypt-proxy# systemctl enable dnscrypt-proxy.service
root@dns:/opt/dnscrypt-proxy# systemctl is-enabled dnscrypt-proxy.service
enabled
BIND setup
Now tell BIND to forward to DNSCrypt, edit the /etc/bind/named.conf.options
file and forward the traffic to 127.0.2.1
where our dnscrypt-proxy
is listening:
options {
directory "/var/cache/bind";
// If there is a firewall between you and nameservers you want
// to talk to, you may need to fix the firewall to allow multiple
// ports to talk. See http://www.kb.cert.org/vuls/id/800113
// If your ISP provided one or more IP addresses for stable
// nameservers, you probably want to use them as forwarders.
// Uncomment the following block, and insert the addresses replacing
// the all-0's placeholder.
// forwarders {
// 0.0.0.0;
// };
//========================================================================
// If BIND logs error messages about the root key being expired,
// you will need to update your keys. See https://www.isc.org/bind-keys
//========================================================================
version "get lost";
allow-transfer {"none";};
allow-query { any; };
minimal-responses yes;
// Forward the queries I can't resolve (domains not mine)
forwarders {
// DNSCrypt
127.0.2.1;
//forward only;
// CloudFlare and Google
//1.1.1.1;
//8.8.8.8;
};
dnssec-validation auto;
// look for dnssec keys here:
key-directory "/etc/bind/keys";
// only sign DNSKEY with KSK
dnssec-dnskey-kskonly yes;
// expiration time 21d, refresh period 16d
sig-validity-interval 21 16;
auth-nxdomain no; # conform to RFC1035
listen-on-v6 { any; };
edns-udp-size 4096;
};
and reload the service:
root@dns:/opt/dnscrypt-proxy# rndc reload
Testing if DNSCrypt proxy is in use
Testing is very simple, since my local BIND is my primary DNS on the home LAN I stop the dnscrypt-proxy
and confirm I can not reach any public website.
Leave a Comment