Last Updated: 2018-05-29 14:33:47 UTC
by Johannes Ullrich (Version: 1)
I consider DNS one of the great success stories as far as internet protocols go. I remember (for a short time) updating host files and the emergence of DNS. DNS was created for a very different type of Internet then what we have today. It assumed a more "friendly" and cooperative Internet. Without amplified DDoS attacks, MITM attacks, and spoofing. Overall, DNS has survived pretty much in its original form with a couple of relatively small additions like EDNS 0 and DNSSEC (which nobody uses).
But recently, in particular, pushed by the need for more privacy and the more bold and unregulated data trading ISPs participate in, the need has come up for more privacy. Also, the failure of DNSSEC to gain substantial traction has led other, simpler, ideas to provide most of the benefit of DNSSEC.
In this article, I want to highlight two changes that I see showing up in DNS traffic:
1 - DNS Cookies
DNS Cookies have been introduced in RFC 7873 . They try to address many of the problems that DNSSEC tried to solve (like cache poisoning), and they are addressing issues like spoofed DNS amplification attacks that DNSSEC didn't prevent. In some cases, DNSSEC may have made these attacks worse. To make it a total "win": DNS cookies are much easier to implement than DNSSEC. The security afforded by DNS cookies is supposed to be similar to the security gained by using TCP instead of UDP. To successfully spoof TCP, an attacker needs to guess a 32-bit sequence number. DNSSEC is much harder to break. So DNS cookies are not as good as DNSSEC. But they may be "good enough."
So how does it work?
A client sending a DNS request will attach a cookie as an option. The cookie is a hash of client IP, server IP, and a secret. So the server will see consistent cookies from a particular client. The secret should be at least 64 Bits long. The details do not matter as long as the cookie is consistent with a specific server/client combination.
The server cookie uses the server IP address, the client cookie and again a secret that is only known to the server. The client IP is not used since it may change due to NAT. Using the client cookie instead will again lead to consistent cookies for a particular server-client combination.
A client that supports cookies will send them with all requests. This *should* not cause any problems. Unsupported options will be ignored. But some testing has shown in the past that there are non-compliant DNS servers that may reject the request as malformed. This test from a few years ago showed that 10% of name servers had problems. Not sure what this looks like right now, but the number is likely smaller.
The client will include a server cookie if it communicated with this server in the past.
Once a server receives a request with client cookie, one of several options may occur:
- If the server doesn't support cookies, then it will respond as usual ignoring the cookie.
- If the server does support cookies, and the client sent a request with only a client cookie, then the server will respond, but it may not include anything but the server cookie. Now the client may re-send the query and include the server cookie. However, servers may also send a complete response and apply different rate limits for server-cookie-less requests. Servers may also be more lenient responding to TCP requests that do not include the cookie.
- If the client included a server cookie, and the cookie is genuine, then the server will send a response.
For a badly formatted cookie, an error is returned (FORMERR). Requests that include an invalid server cookie are treated like requests that do not include a server cookie at all. This feature allows a client to recover if IP addresses changed, or if the server restarted and selected a new secret.
Cookies have been implemented in BIND 9.11. If you installed Ubuntu 18.04 LTS, you may have seen BIND use them. In BIND, cookies are enabled by default, but they are not enforced by default. Also, the "dig" tool now supports cookies with the +cookie option.
Here is a quick sample packet showing the cookie option in a DNS request. I haven't found any of the large DNS providers supporting the option yet, but I haven't tested them all.
To filter for these queries, you can use the Wireshark display filter "dns.opt.code == 10". There is no great BPF expresion for it, but "tcpdump -r dns -n 'udp[18:2]>0 && udp&0x80=0'" will show all queries with DNS options (some may just be the EDNS option 0).
Packet capture: DNS packets with cookies as Ubuntu 18.04 boots.
2 - DNS over TLS
The second DNS innovation I see more and more is DNS over TLS. Unlike DNS cookies, DNS over TLS attempts to solve the privacy issue in DNS. It has found more followers after Cloudflare's "184.108.40.206" DNS service started to support it. I set it up in my PFSense firewall and am including some sample packets below.
The protocol is pretty "straightforward": Setup a TCP TLS connection, then send the DNS query across this TLS tunnel. The problem is that the TLS connection takes quite a bit of overhead to establish. But it can be reused for multiple queries to limit the overhead. In real life, I find the TLS connections to last only a very short time, so the overhead is substantial as far as the number of packets exchanged goes. Also, note that the TLS endpoint will be able to inspect all your queries. Cloudflare states that they will not use the data.
The tricky part with DNS over TLS is that it renders many enterprise systems blind that take advantage of DNS traffic. Your best bet is to block DNS over TLS (it uses port 853/TCP) and to require users use an internal recursive DNS server. You can then do all the logging you need on that DNS server, and you may even use DNS over TLS from the recursive DNS server to an entity like Cloudflare if you trust them more then you do trust your ISP. Based on my observation, DNS over TLS also doesn't use the ALPN or the SNI options in TLS, which are used by more "regular" TLS connections like HTTPS.
Packet capture: DNS over TLS sample from PFSense to Cloudflare (anonymized IPs) https://isc.sans.edu/diaryimages/dnstlsanon.pcap