TL;DR – Any recursive DNS resolver that responds to all requests, instead of returning NXDOMAIN, NODATA or SERVFAIL when an authoritative server gives these responses, is most likely going to cause issues for any dual-stacked host.
At OpenDNS we think a fast and reliable internet experience starts with a high-quality recursive DNS provider, so any time we find issues in common industry practices, we want everyone to know about it. In this post I’ll be showing a few issue that arise for dual-stacked hosts (meaning the host has both IPv4 and IPv6 addresses) when they’re using a DNS provider that redirects NXDOMAIN, NODATA and SERVFAIL responses. If you need a quick refresh on NXDOMAIN vs NODATA, see my previous post.
DNS redirection is the act of a recursive resolver intercepting NXDOMAIN, NODATA and SERVFAIL responses from an authoritative server and serving up an alternative IP address. This effectively tricks the requesting application into thinking there is an actual host at that name. This technique is commonly used by ISPs or DNS providers as a means of serving assisted search pages for mistyped domains, redirecting clients to advertising pages/resources, or for collecting statistics (see DNS Hijacking for more details). For the most part, on a typical IPv4 enabled host, DNS redirection isn’t a problem (although it may complicate some special DNS applications), but a real issue begins to arise when dual-stack (both IPv4 and IPv6 enabled) clients encounter DNS redirection.
I’ve previously written about how different operating systems resolve hostnames when they are dual-stacked here, so for now I’m only going to focus on OSX 10.9 (but know that this problem will affect most OSes). When you have a dual-stacked OSX host, and an application that is using the system resolving libraries (the system call getaddrinfo() specifically), OSX will send out both A (IPv4) and AAAA (IPv6) requests. Here’s an example of my dual-stacked host trying to lookup the local donut shop’s domain:
# tcpdump -n -s 1500 -i en0 udp port 53 & ./getaddrinfo www.timhortons.com 10.10.10.165.63835 > 126.96.36.199: 18223+ A? www.timhortons.com. 10.10.10.165.55987 > 188.8.131.52: 9571+ AAAA? www.timhortons.com. 184.108.40.206 > 10.10.10.165.63835: 18223 1/0/0 A 220.127.116.11 18.104.22.168 > 10.10.10.165.55987: 9571 0/1/0
From the tcpdump we can see that A and AAAA requests were sent out in parallel. Our A record request received “22.214.171.124” and our AAAA record request recieved a NODATA response. Now let’s imagine we were using a DNS provider that was doing DNS redirection. The AAAA NODATA response from our donut shop’s authoritative DNS server would have been redirected and we would have been served a valid IPv6 address (hopefully with some donut-related advertising). At this point both the A and AAAA records would be given to the calling application and it would be up the applications logic to choose which record to use (but the application has no way of knowing that the AAAA record has been falsified). This can (and will) lead to a very confusing browsing experience, the falsified record may take you to a webpage claiming the domain you’re looking for doesn’t exist!
“Can’t the DNS provider’s recursive resolver just look to see if both records types (the IPv4 and IPv6) are NXDOMAIN, NODATA or SERVFAIL before deciding to redirect an answer?”
At first glance it might look as though recursive DNS providers can work around this problem by checking both record types before responding, but another issues arises for DNS redirection when you include a search domain in your systems resolv.conf. Let’s assume for the purpose of this example you’ve added “dunkindonuts.com” and “opendns.com” to your list of DNS search domains so that you only have to type “system” when looking up “system.opendns.com” (knowing that there is no “system.dunkindonuts.com” host). Now let’s look at what the system’s resolving libraries will do:
# tcpdump -n -s 1500 -i en0 udp port 53 & ./getaddrinfo system 10.10.10.165.50227 > 126.96.36.199.53: 5591+ A? system.dunkindonuts.com. 188.8.131.52.53 > 10.10.10.165.50227: 5591 NXDomain 0/1/0 10.10.10.165.54555 > 184.108.40.206.53: 48108+ A? system.opendns.com. 220.127.116.11.53 > 10.10.10.165.54555: 48108 1/0/0 A 18.104.22.168
The system resolving libraries have done a lookup for “system.dunkindonuts.com”, waited for the responses (which was an NXDOMAIN), and then tried a lookup of “system.opendns.com”. The result is that we get the correct response for “system.opendns.com”. Now if this query had been done against a server which was doing DNS redirection our initial NXDOMAIN response (meaning there were neither IPv4 or IPv6 records) from the “system.dunkindonuts.com” query would have been redirected and replaced with a falsified record and the OS would have stopped trying to resolve the correct host.
“Doesn’t OpenDNS use DNS redirection to display ads? Isn’t that your entire business model?”
It is true that previously OpenDNS did use DNS redirection for the purpose of giving what we called “a guide page”, but we don’t do that anymore. OpenDNS has transitioned away from advertising-based revenue to focus on our world class enterprise security platform. You can read more about our transition away from ads in our CEO’s blog post “No more ads”.
So now that you know more about the pitfalls of DNS redirection, don’t put up with a recursive DNS server that redirects your traffic, especially not in the coming dual-stacked world.