8.8.8.8 is Google’s “free, global DNS resolution service”, so popular that it’s been lampooned by XKCD. It has a wonderfully straightforward front-end: the IP address 8.8.8.8. But that begs the question: what’s on the back-end? Do the authoritative nameservers receive queries from 8.8.8.8 or some other IP address?

Spoiler: the queries don’t originate from 8.8.8.8; instead, the queries originate from a range of IP addresses, some IPv4, some IPv6.

Testing 8.8.8.8

To see how 8.8.8.8 queries authoritative nameservers, I need an authoritative nameserver. Luckily, I happen to be in possession of such a nameserver (well, four such nameservers).

You see, I run nip.io & sslip.io, a “wildcard” DNS service. We’ll take advantage of the wildcarding to send a slew of carefully-marked DNS queries to 8.8.8.8, ones that will be forwarded to our nameservers.

for i in $(seq 0 255); do
  dig +short 8-8-8-8.test-$i.sslip.io @8.8.8.8
done

Now let’s get onto the nameserver and see what the logs look like:

ssh ns-ovh.sslip.io

The Logs

Let’s dump our DNS server’s logs. My DNS server is run as a systemd service, so I can use journalctl to retrieve the logs since yesterday and write them to a temporary file. It’s a lot of logs: the command takes eight minutes to run and produces a 1.5 GiB log file:

sudo journalctl -u sslip.io-dns -S yesterday > /tmp/sslip.io.log

Let’s extract our specially-crafted lookups from the log file:

grep -i 8-8-8-8.test /tmp/sslip.io.log

The astute among you might ask, “why are you instructing grep to ignore case with the -i flag?” To which I answer, “be patient, gentle reader, we’ll get to that.”

Let’s look at what our grep discovered:

172.253.244.145.46402 TypeA 8-8-8-8.TesT-158.SsLIp.io. ? 8.8.8.8
172.253.244.144.45355 TypeA 8-8-8-8.test-158.sslip.io. ? 8.8.8.8
172.253.0.21.41598 TypeA 8-8-8-8.teSt-161.SSlIP.iO. ? 8.8.8.8
172.253.2.29.34349 TypeA 8-8-8-8.tEst-163.ssliP.iO. ? 8.8.8.8
172.253.244.145.48298 TypeA 8-8-8-8.test-163.sslip.io. ? 8.8.8.8
2607:f8b0:4004:1001::12b.39475 TypeA 8-8-8-8.TesT-164.Sslip.Io. ? 8.8.8.8
74.125.181.155.54746 TypeA 8-8-8-8.TEST-173.ssLip.iO. ? 8.8.8.8
172.253.2.23.49071 TypeA 8-8-8-8.TeSt-177.sSlIP.iO. ? 8.8.8.8

Let’s break down the log file, using the first line as an illustrative example:

  • 172.253.244.145 the address from which the DNS query came; in this case, an IPv4 address.
  • 46402 the port number from which the DNS query came
  • TypeA the type of record; an A record is an address record
  • 8-8-8-8.test-2.sSlip.iO. the query. Notice the random capitalization (this didn’t come from us; Google’s nameservers introduced it).
  • ? this was a DNS query (it’s always a DNS query)
  • 8.8.8.8 this was the address (DNS A record) that we returned

We can easily see the following:

  • Of our 256 DNS queries, Only 8 (3%) were forwarded to our Warsaw server
  • Our Warsaw server typically handles 66% of the lookups. In this case, not even close. Perhaps because the queries originate from 5,850 miles away, San Francisco?
  • The originating IP address was not 8.8.8.8.
  • The originating address was different each time.
  • The originating address was IPv4 seven times, IPv6 once (we’ll come back to this later)
  • Each lookup had what appears to be random capitalization, and this is one of Google’s strategies to mitigate DNS cache poisoning. Surprisingly there’s a more sure-fire way to mitigate cache poisoning, and that’s to use TCP (Transmission Control Protocol) instead of UDP (User Datagram Protocol), and my DNS servers accept both TCP and UDP connections. I suspect that the Google engineers weighed the random source address, the random source port, and random capitalization and determined that DNS cache poisoning was no longer possible, so switching to using TCP as the transport protocol wasn’t worth the overhead. Google is not the only recursive nameserver that ruled out TCP: of the 1,460,199,364 queries to my server, only 3,560 used the TCP protocol (0.0002%), and many of those TCP queries originated from my continuous integration (CI) server.

Let’s make sure those source IP addresses belong to Google by querying ARIN (American Registry For Internet Numbers); we’ll start by querying who owns the IP block, and how big a block it is (CIDR) (Classless Inter-Domain Routing). We’ll use jq to tease out that information:

curl \
  -H "Accept: application/json" \
  "https://whois.arin.net/rest/ip/172.253.244.145" | \
jq '.net.orgRef."@name", .net.netBlocks.netBlock.cidrLength."$"'

We see the following output:

"Google LLC"
"16"

Yup, Google definitely owns that IPv4 address. In fact, with a /16 CIDR, Google owns every IPv4 address that starts with “172.253”, which accounts for 6 of 8 the source IP addresses in our log file. Let’s look up the sole IPv6 address:

curl \
  -H "Accept: application/json" \
  "https://whois.arin.net/rest/ip/2607:f8b0:4004:1001::12b" | \
jq '.net.orgRef."@name", .net.netBlocks.netBlock.cidrLength."$"'

And we see,

"Google LLC"
"32"

Which means that Google owns every IPv6 address that starts with “2607:f8b0”.

I leave the lookup of the remaining IPv4 address, 74.125.181.155, to the reader. But trust me when I say that every IPv4 address that starts with “74.125” is owned by Google.

Conclusion

When 8.8.8.8 queries upstream nameservers, the queries don’t originate from 8.8.8.8; instead, they originate from a variety of Google-owned IP addresses, some IPv4, some IPv6. In addition, Google randomly capitalizes letters in the lookup in order to foil DNS cache poisoning.