8 bits only: DNS namespaces and domain resolution in action

Note: I want to start writing more often, and I think that part of doing that will simply be word vomiting whatever i’m doing onto this blog from time to time, instead of trying to write more comprehensive (and as a result, longer) posts. Whenever I can, I’ll be trying to post quicker posts under this 8 bits only collection (with the goal making these posts a lot more digestible than the others a la 8 bits only)

I was curious to see to what granularity I could track the construction of HTTP requests from my machine to the internet. In particular, I’ve been wanting to see whether I can get a concrete answer on which DNS server my machine is using to resolve domains. I’ll talk a bit about what can be done to dissect this process, but let’s discuss what I’m even going on about first.

What is DNS?

I don’t want these 8 bit posts to drag on too long, but I would be remiss not to give any context whatsoever about what i’m talking about. Put shortly, DNS (domain name system), is the naming service which is used to map application layer domain names to IP addresses. What this means exactly is that when we want to go to, say, google.com, what we are really doing behind the scenes is called DNS resolution: we are requesting from DNS the corresponding IP address of the server for the specified domain (google.com in this case), and then issuing our request to this IP address. Domain names like {google/twitter/youtube}.com are simply a way for humans to interact with resources on the internet more easily, using understandable names with meaning, as opposed to strings of digits that underlay these domain names. The machinery that allows this to work as it does so well is DNS.

DNS hierarchical namespace

For end users, we can, for all intents and purposes, look at DNS as an all-powerful dictionary located on a machine somewhere on the internet, taking in domain names as input, and returning back to clients the corresponding IP address. The reality is not so simple, as the ubiquity of the internet obviously necessitates a distributed approach to this critical service.

DNS is distributed based on a hierarchy, which itself is derived from different domain names.

credit: computerhope

The above diagram breaks down the layering we see in DNS. In particular, the top 3 level in the hierarchy are:

  1. Root DNS server: These servers are the “roots” of the DNS service. They are the servers initially contacted when attempting DNS resolution, and respond back to clients with the IP address of the relevant Top-Level Domain Server for the client’s request. (For reference, there are only 13 root name servers, with multiple instances of each, resulting in 1381 instances of these servers worldwide as of writing, with tracking of this information at https://root-servers.org/).
  2. Top-Level Domain Server: TLD servers are the partitioning level for specific domain types e.g. .com, .edu etc. They are the second point of contact for DNS resolution, and return back to the client the IP address of an authoritative server for the given domain.
  3. Authoritative Server: These are the servers which give us our “final answer”. They will return back the corresponding IP address for the client’s requested domain name. In cases where a domain itself may have sub-domains (e.g. maps.google.com is a sub-domain of google.com), an authoritative server may deflect again, returning an IP address to another authoritative server tasked with handling DNS resolution for this sub-domain. Note that these authoritative servers may be managed directly by the domain owner, or through a DNS service provider.

Local Name Server

Though we’ve talked about the levels of DNS hierarchy above, there is an additional player involved in servicing DNS resolution requests, known as the local name server. This server stands between clients and the DNS hierarchy, and executes the set of requests described above on behalf of clients, starting with the root name servers, all the way down to the authoritative servers, ultimately returning back to the client the IP address they will need to send network requests to the desired domain.

Local name servers can additionally cache DNS mappings that have been requested in the past, returning these cached results to the client, to reduce the load on the root servers, and to reduce the number of repetitive DNS resolutions requested by the client. (There is also additional OS-level DNS caching on client machines, but I’m not going to get into this)

Putting it together

There’s obviously much more we can get into when it comes to the DNS service, but putting together what we’ve discussed above, we can now get a semblance of where DNS fits into the lifecycle of network requests:

We ultimately go through the following steps

  1. Client forwards DNS resolution request to local DNS server
  2. If local DNS server has client requested domain cached, return corresponding IP address to client, skip to last step
  3. Local DNS server forwards client request to root name server, which responds back with address of relevant TLD server
  4. Local DNS server forwards requests to TLD server specified by root server, which responds back with corresponding authoritative server for the domain
  5. Local DNS server forwards request to authoritative server specified by TLD server, which responds back with IP address the domain maps to (or, if there are further sub-domains, potentially an IP address for a subsequent authoritative server, in which case, redo this step with the new authoritative server)
  6. local DNS server returns IP address for the given domain to the client, which can now execute network requests directly to the server

DNS in action

The first thing worth doing is trying to initiate DNS resolution directly. This can be done via the nslookup utility, see below:

DNS Resolution

What the above response is telling us is the following:

  • The DNS server which serviced our request (returned us the IP) is 192.168.50.1, and the port used is port 53 (this is a well-defined port reserved for DNS)
  • The Non-authoritative answer to our request is that the domain google.com maps to the IP address 142.250.69.206

Now you may be asking, what does it mean when the response specifies the answer is non-authoritative? As we discussed earlier, we expect DNS resolution to be handled eventually by an authoritative server, so from this description we can make the conclusion that that was not the case, and in fact, the server which returned us the IP address was in fact not an authoritative server.

What this means is that this DNS resolution was handled by our local DNS server. This server is not an authoritative server, but since it caches DNS mappings, it has the capacity to provide an answer to DNS resolutions for domains which it has already serviced a request for in the past. (my guess is, nslookup for google.com will yield a non-authoritative answer for any of you following along as well)

What’s my Local DNS server?

Though we’ve come to a conclusion about the local DNS server already, we can concretely verify this information.

On Linux, we may try the below command, to check the resolver.conf file on our machine (this file stores information about the local DNS server configuration):

Since I am running on OS X, this is in fact not the reference I want to check (as the message so helpfully describes), but instead, we can check the local DNS server as done below:

Unpacking this a little further, we know the following information about our local DNS server:

  • The IP address of the server is 192.168.50.1 (confirming our hypothesis from earlier)
  • The network interface its corresponding resolver is associated with is en0 (this is a well-defined network interface for wi-fi)
  • We interact with this server by requesting A records (another way of saying what we get back is IP addresses)

Analyzing packets from/to local DNS server

We can take a further look at what packets are flowing from and to the local DNS server with tcpdump, like the below result after initiating tcpdump, and executing DNS resolution for example.com

We can deduce from the output of nslookup, and the packet sent to the local DNS server, that exactly the interaction we expected has occurred

  1. The client (us, 192.168.50.164.57882) initiates a request to the local DNS server, requesting the A record (the corresponding IP address) for the domain, example.com
  2. The local DNS server responds back with the A record, again from its own cache, which indicates the IP address for the requested domain is 93.184.216.34

I hope, if you made it to this point, you got to learn something new, or get a refresher, about how network traffic to human-named domains is served through the power of the DNS service, and how to analyze the machinery of DNS behind the scenes.

Working on storage management and infrastructure at Azure SQL