By Charles Leavitt
The Domain Name Service (DNS) is one of the core protocols that the Internet is built on. Every time we go to a website, or use any Internet connected service, DNS is working away in the background resolving domain names, those human readable addresses like google.com, into the actual IP address of the resource. For example, when you type the domain name “google.com” into a browser a DNS query is sent to recursive DNS server which then resolves that URL to the IP “22.214.171.124” or the IP of any Google search web server. The DNS server then sends a DNS response back to your device with the IP. This service is crucial to security since the DNS response is trusted by applications as being correct and authentic. The main problems with DNS security and privacy lie in the fact that DNS queries and responses are transmitted in plain text and devices inherently trust and use the first response they receive. This makes a variety of attacks such as DNS spoofing, DNS hijacking and the use of a Rouge DNS server particularly easy. The plain text data allows the attacker to read queries and manipulate responses to redirect the user, without their knowledge, to any domain the attacker wishes. In addition to a malicious attackers, many ISPs also monitor and track their users internet usage using DNS and in many cases even hijack the DNS traffic to push advertisements. For more in depth details on the vulnerabilities of DNS see RFC3883.
So what are options do we have to improve the security of DNS? The predominate answer is to use the DNS Security Extensions (DNSSEC). All DNS record answers received from a DNSSEC protected zone are digitally signed and DNS resolver is able to check if the information in the answer is identical to the information published by the zone owner and served on an authoritative DNS server. This provides authentication of DNS responses but DNSSEC does not improve the privacy or confidentiality of the data since the responses are authenticated but they are not encrypted, so any third party capable of sniffing traffic can still see all queries and responses in plain text. Another major issue is that the deployment of DNSSEC remains very low since it takes the cooperation of both the DNS servers and domains themselves to implement it. According to OpenDNS “DNSSEC today represents a near-zero percentage of overall domain names and an increasingly smaller percentage of DNS records each day as the Internet grows”.
It is fairly easy to test if a DNS server is properly enforcing DNSSEC. To do so run the command:
“dig +dnssec @[DNS Server IP] www.dnssec-failed.org”
This tells dig to attempt to have the specified DNS server resolve www.dnssec-failed.org which is a testing domain that intentionally has a bad mismatched signature. A properly configured DNS server with DNSSEC should return a response with a SERVFAIL in the header and no answers. Here is an example using Google’s 126.96.36.199 DNS server which uses DNSSEC.
cil@ubuntu:~/Desktop$ dig +dnssec +multi @188.8.131.52 www.dnssec-failed.org ; <<>> DiG 9.10.3-P4-Ubuntu <<>> +dnssec +multi @184.108.40.206 www.dnssec-failed.org ; (1 server found) ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 64826 ;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags: do; udp: 512 ;; QUESTION SECTION: ;www.dnssec-failed.org. IN A ;; Query time: 87 msec ;; SERVER: 220.127.116.11#53(18.104.22.168) ;; WHEN: Sun May 07 15:10:34 PDT 2017 ;; MSG SIZE rcvd: 50
As you can see the DNS response was a SERVFAIL, thus Google’s DNSSEC is working properly. However if I attempt the same query against a Time Warner Cable DNS server (IP 22.214.171.124) it returns answers showing that the TWC DNS server is not implementing DNSSEC.
cil@ubuntu:~/Desktop$ dig +multi @126.96.36.199 www.dnssec-failed.org ; <<>> DiG 9.10.3-P4-Ubuntu <<>> +multi @188.8.131.52 www.dnssec-failed.org ; (1 server found) ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 6816 ;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 8192 ;; QUESTION SECTION: ;www.dnssec-failed.org. IN A ;; ANSWER SECTION: www.dnssec-failed.org. 7200 IN A 184.108.40.206 www.dnssec-failed.org. 7200 IN A 220.127.116.11 ;; Query time: 120 msec ;; SERVER: 18.104.22.168#53(22.214.171.124) ;; WHEN: Sun May 07 15:20:34 PDT 2017 ;; MSG SIZE rcvd: 82
As shown above, the query received an answer and the flag “ad”, which indicates that DNSSEC is being used, is missing from the response header. This Time Warner Cable DNS server is certainly not DNSSEC enabled.
Now that we can test if our DNS server is using DNSSEC, we can also test to see if any particular domain is also participating in DNSSEC. The dig command is once again used:
“dig +dnssec +multi @[DNSSEC Server IP] [Tested Domain Name]”
Here is an example of a failed test were the tested domain, rit.edu, is not implementing DNSSEC. Note that the query still returned an answer, per the RFC specification, however the “ad” flag is missing from the header so there is no guarantee that this answer has not been tampered with.
cil@ubuntu:~$ dig +dnssec +multi @126.96.36.199 rit.edu ; <<>> DiG 9.10.3-P4-Ubuntu <<>> +dnssec +multi @188.8.131.52 rit.edu ; (1 server found) ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 3738 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags: do; udp: 512 ;; QUESTION SECTION: ;rit.edu. IN A ;; ANSWER SECTION: rit.edu. 328 IN A 184.108.40.206 ;; Query time: 41 msec ;; SERVER: 220.127.116.11#53(18.104.22.168) ;; WHEN: Sun May 07 15:39:55 PDT 2017 ;; MSG SIZE rcvd: 52
Now here is an example using a domain, pir.org, that is DNSSEC enabled. Note how the “ad” is present in the header flags and the RRSIG with its signature is present in the answer section.
cil@ubuntu:~$ dig +dnssec +multi @22.214.171.124 pir.org ; <<>> DiG 9.10.3-P4-Ubuntu <<>> +dnssec +multi @126.96.36.199 pir.org ; (1 server found) ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 64935 ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags: do; udp: 512 ;; QUESTION SECTION: ;pir.org. IN A ;; ANSWER SECTION: pir.org. 142 IN A 188.8.131.52 pir.org. 142 IN RRSIG A 5 2 300 ( 20170521084000 20170507084000 8309 pir.org. dXm3Pg9tB079eyg9mHmT1CRE97H8ohuJGPCXfVHAos+U LfEedWB/9ouNsnT48PUKhYlCNXXQVBrRsGIQs7z6L6bo d2Ohbo3qxU4EMqaUKfAIdkuhQWrkly8BdizX3wrK7FRT kBIE99PPzxFJ2FU82DmRB2LTKqRgP1scy9ezuls= ) ;; Query time: 45 msec ;; SERVER: 184.108.40.206#53(220.127.116.11) ;; WHEN: Sun May 07 15:34:21 PDT 2017 ;; MSG SIZE rcvd: 219
It is also important to show that both the DNSSEC query and response are being transmitted in plain text as showing in this wireshark screen-shot:
Given the problems of DNSSEC, primarily that it is not widely used and that it does not provide any privacy what can we do to secure our DNS traffic? The most viable solution I have found is the DNSCrypt protocol at https://dnscrypt.org/. The DNSCrypt protocol provides an open source solution that both authenticates and encrypts DNS traffic between the DNSCrypt client and DNSCrypt server. The DNSCrypt client acts as a local proxy for DNS that wraps around the DNS protocol, much like SSL/TLS is used as a wrapper for HTTP. The DNSCrypt client encrypts the DNS query and sends the encrypted query to a DNSCrypt Resolver which is a public recursive DNS server that participates in this open source project. The DNSCrypt server then recursively resolves the DNS query, encrypts it and sends the DNS response back to the DNSCrypt client. There are many available DNSCrypt servers available around the globe with many of them also supporting DNSSEC for added authentication. The communications between the client and server are sent over UDP port 443 and are encrypted with public key cryptology using Curve25519 encryption. DNSCrypt can optionally use TCP port 443 to further protect the traffic for use with a VPN or TOR. A full RFC style explanation of the entire DNSCrypt protocol can be found at this LINK.
The DNSCrypt client can be installed on Windows, Mac, Linux, Android (rooted), iOS (jail broken) and some routers. It supports usage as either a command line tool or with a user-friendly GUI that simplifies configuration. Here is a screen-shot of the Windows GUI client’s main configuration page:
This allows you to select what interfaces you want to use DNSCrypt on and gives you a drop down option to select what DNS Resolver you want to use. As you can see from the screen-shot both my primary and secondary DNS resolvers support DNSSEC validation. A full list of all DNSCrypt Resolvers and their options can be found Here.
Here is a screen-shot of the traffic generated by performing a nslookup for “rit.edu” through the DNSCrypt client, My IP is the 192.168.0.14 and the DNSCrypt Resolver IP is 18.104.22.168:
The DNS traffic in the contents of these packets is entirely encrypted and obfuscated. If I hadn’t known to expect the encrypted DNS traffic on UDP port 443 going to the IP of my selected DNSCrypt Resolver there is no way that I could discern that this was in fact encrypted DNS traffic.
In addition to its main features of encrypting and authentication DNS traffic, DNSCrypt clients can also provide advanced features such as blacklisting of domains or IP addresses, real-time logging of DNS queries, and local DNS caching.
In conclusion, it appears that using DNSCrypt is currently the best way to enhance the security and privacy of DNS. After using DNSCrypt for several days I have not observed any noticeable change in the time it takes to resolve queries and load web pages. The only issue I can see with using DNSCrypt is that you are placing your trust in the DNSCrypt Resolver to not be malicious; however, I believe this can be mitigated by choosing the reputable Cisco OpenDNS Resolver or selecting one that also supports DNSSEC. As shown this solution provides protection from both potential attackers who are attempting to spoof/manipulate DNS traffic and from and ISPs who wants to track DNS traffic.
Once again, this is an Open Source protocol and if you are interested in implementing DNSCrypt the full documentation and downloads can be found at the official DNSCrypt website: https://dnscrypt.org/ and the official GitHub is https://github.com/jedisct1/dnscrypt-proxy.