- DNS (Domain Name System)
- Lookup Process
- Tree Hierarchy
- DNS Structure
- Authority Zones
- Name Servers
- Record Types
- TTL (Time to Live)
DNS (Domain Name System)
You likely have many applications running on your laptop right now, and chances are some of them require an external resource or piece of data that will be retrieved from across a network.
In order for your applications to access these resources they need to know their location. The location is typically identified by an ip address and are written in either decimal or hexadecimal.
When dealing with ips, they can be very hard to memorise; especially as there are two different forms of ip:
An IPv4 identifier is 32 bits long, written in decimal and separated by periods:
An IPv6 identifier is 128 bits long, written in hexadecimal and separated by colons:
It’s even more awkward if you have a program with a hard coded ip address for a specific resource. If the resource has to change its location, then the program now has to be updated as well to point to that new location.
What’s easier would be the use of a name that maps to an underlying value. So for example, the ip address
184.108.40.206 points to Google’s search page. Rather than type that ip into your web browser (or hard code it inside an application) you would likely instead find it much easier to reference the resource by its name:
Your application (e.g. web browser, whatever) when encountering this ‘resource’ will lookup the name provided, resolve the underlying ip address and ultimately retrieve the relevant resource.
This is the basis of what is known as DNS (Domain Name System).
In order for you to access a resource using a name, you need to now know the location of the system that contains the information (also known as ‘records’) for the resource you’re interested in.
The idea being is that if you knew which DNS held a record containing information about the resource you wanted, you could ‘query’ the DNS and say…
“hey, what’s the ip for resource X?”
…the DNS would then respond with the information you needed.
This is what’s known as the ‘lookup process’.
The lookup process is where your machine communicates across different networks until it finds one that knows the ip address of the resource you’re looking for. Now there are a few different parts to this lookup process:
- Root Name Server(s)
- TLD Name Server(s)
- SLD Name Server(s)
The ‘resolver’ knows the location of the ‘root name server(s)’. When you make a request for a DNS resource, then the resolver is what you communicate with first. The resolver is typically either assigned via DHCP (client-side) or via
The resolver will have a ‘root hints’ file with a hardcoded list of root name servers. The resolver takes the DNS resource request and queries all the root name servers at once. Whichever root name server responds first, the resolver will keep a note of it as being the quickest (so for future requests it’ll favour that server over the other root name servers).
Note: resolvers also include additional logic for invalidating the favoured root name server, but that’s outside the scope of this article
Now depending on what your query is, the resolver’s job isn’t necessarily finished. For some queries (such as
www.example.com) the resolver doesn’t just send a request to one level of name servers.
The resolve first makes a request to the root name servers, waits for a response and then sends another query; this time the query is sent to a ‘sub level’ name server known as a TLD name server.
The TLD name server also returns a referral, this time to a SLD name server which the resolver will query. The SLD should now be able to identify the requested DNS resource.
Root Name Server(s)
There are multiple root name servers and each one knows the location of a sub level name server capable of handling the requested DNS resource (or at least knowing the next level of name servers to delegate the request onto).
Effectively the root name servers parse the requested resource and identify which ‘TLD’ name server the resolver should query. Once the root name server has identified the sub level name server, it returns that information to the resolver.
TLD Name Server(s)
There are multiple TLD name servers and each one knows the location of sub level name servers capable of handling the requested DNS resource and identifying its underlying ip address. The TLD name servers parse the requested resource and identify which ‘SLD’ name server the resolver should query.
Once the TLD name server has identified the SLD name server, it returns that information to the resolver.
Note: TLD name servers are split into two: gTLD (.com, .org, .net etc) and ccTLD (.us, .uk etc)
SLD Name Server(s)
SLD name servers are known by a few different names:
- User DNS name server
- Authoritative name server
The latter (authoritative) being the most well known, because these name servers are the final step to hopefully discovering the identity of the requested DNS resource and this DNS server will be responsible for the DNS settings applied to the resource.
Note: you may find some people use the term ‘authoritative’ quite liberally, because in essence even a TLD name server can be considered authoritative in respect to the TLDs it manages (depends on your perspective)
It can be useful to try and visualise the hierarchy of this lookup process.
The following code snippet shows a potential lookup flowing from an initial request to a ‘root’ name server, into a ‘TLD’ name server (I show both sub categories: gTLD and ccTLD just to be clearer); another request is then made to a specific gTLD (
.com in this case) and from there the next step is for the resolver to query the SLD (in this example we’re looking for the resource
. (root) / \ / \ (gTLD). .(ccTLD) \ \ .(com) \ \ .(example.com)
The requests that would have been made to fulfil the above flow diagram would have looked something like:
- Resolver makes multiple requests for
www.example.comto its list of root name servers
- One of the root name servers would have responded first to say “go talk to the .com gTLD”
- The resolver then sends the same
www.example.comquery to the .com gTLD
- The gTLD responds to say “go talk to the
example.comauthoritative name server”
- The resolver then sends the same
www.example.comquery to the relevant authoritative name server
- The authoritative name server has the record the resolver is looking for and sends back its details
- The resolver can now provide those details back to the application who originated the request
Note: so far we’ve spoken about name servers that run DNS software. There are many DNS software programs available (some paid, some free), but the most popular is BIND. We’ll see references to it throughout this article
Each period in a ‘domain’ is actually a ‘level’. Hence extensions such as
.us are considered a TLD (top-level domain). This also explains why an SLD is named so: because it sits at a ‘secondary’ level (it sits ‘below’ the TLD).
The syntax structure of a domain resembles the following:
This would materialise into something like:
http://is the protocol
wwwis the hostname
Note: things get a little more complicated with ccTLDs
As country codes can have a third level (e.g.
Typically the combination of
<sld><tld> is referred to as the ‘domain name’.
Now that we understand that a domain is made up of ‘levels’, the concept of ‘zones’ should be easier to comprehend. A level is equivalent to a zone, but when using the term ‘zone’ we’re being explicit in what context we’re talking about. Effectively each zone is responsible (i.e. an authority) for its own resource records (RR).
A resource record (RR) is simply a line in a text file. This text file defines what records have been created for the level/zone. Each authoritative name server (zone) has its own zonefile because it needs to be able to respond to requests (queries) for records it may have.
Below is an example of what a zonefile might look like for the domain
$TTL 86400 ; 24 hours could have been written as 24h or 1d $ORIGIN example.com. @ 1D IN SOA ns1.example.com. hostmaster.example.com. ( 2002022401 ; serial 3H ; refresh 15 ; retry 1w ; expire 3h ; minimum ) IN NS ns1.example.com. ; in the domain IN NS ns2.smokeyjoe.com. ; external to domain IN MX 10 mail.another.com. ; external mail provider ; server host definitions ns1 IN A 192.168.0.1 ;name server definition www IN A 192.168.0.2 ;web server definition ftp IN CNAME www.example.com. ;ftp server definition ; non server domain hosts bill IN A 192.168.0.3 fred IN A 192.168.0.4
The zonefile is effectively the mapping between a domain name and its associated ip address (as you’ll see later on, the use of tools such as
dig return us similar output).
In the above example zonefile we can see that we have a few records defined, such as an ‘A’ record (e.g.
fred) and a ‘CNAME’ record (
ftp), as well as a couple of ‘NS’ records and a ‘MX’ record. We’ll take a look at what these records really represent later on in this article.
The format for these records is as follows:
name ttl class rr ...
...represents specific arguments for the type of RR being created
The reason I mention this syntax structure is because there are some nuances regarding this zonefile that tie into the syntax structure but might not be immediately clear:
- Anything starting with a
$is referred to as a ‘directive’ and affects processing of the zonefile (e.g.
$TTLdefines the default ttl for the entire zone; this can be overridden by a ttl set within a RR).
- The SOA record needs to be the first record defined
- The SOA record replaces
@with the value assigned to
$ORIGINdirective is not mandatory. If not provided, then BIND (the DNS server software) will acquire a value from the configuration file
named.conf(but generally it’s more portable to provide one in your zonefile)
- The SOA could be made into a one liner, but uses parentheses to indicate ‘multi-line’
- Not all arguments are mandatory and so can be left blank, by way of a space or a tab (known as a ‘field separator’)
- Most RR’s utilise
INas the ‘class’ value (which stands for ‘Internet’). There are other values but they’re very rarely used
- The ‘name’ used for most of the RR’s in the above example aren’t considered “fully qualified domain names”. I discuss what this means below, but for now you should know that the rule is: if the name doesn’t end with a dot
$ORIGINis appended to the name (see next section for more details)
- With RRs you can have the same ip assigned to multiple names (as the one host could potentially be serving up different services, such as a DNS as well as a web server)
- You can simplify the creation of multiple records of the same RR type by omitting their value (see above example zonefile). For example, if no value for
rris found then it’ll use the value from the previous record
- You can provide very basic DNS ‘load balancing’ by creating multiple A records and pointing them to different ips. BIND will handle requests by carrying out either a round-robin process or a random selection (depending on the rrset-order setting inside the configuration
named.conf; round-robin being the default)
To put this into context, consider the ICANN organisation, who are responsible for providing an accreditation system for domain ‘registrars’. A domain registrar is an organisation who has been authorised to sell SLDs for a chosen TLD.
Registrars are a special entity who have been given ‘authority’ over a set of TLDs. They’re able to create records for their zone (which is the top level domain itself).
For example, 123-Reg is a domain registrar authorised to sell SLDs for all types of TLDs (such as
.co.uk etc). 123-Reg is a registrar who has (in my case) sold me the SLD (and technically a third-level domain)
integralist.co for the ccTLD
.uk - which means I’m the authority for
integralist.co.uk and can create records/hosts/sub domains for it.
This registrar could also sell the SLD
example (which gives you ownership and responsibility for
example.com and everything to the left of it; e.g. you could create
www.example.com). Or maybe this registrar sells you a SLD/3LD combination for something like
example.co (which gives you ownership and responsibility for
Once you purchase a SLD (e.g. you could purchase the SLD
example under the TLD
.com), you are the authority for that zone (the SLD). This means you are able to create resource records for that zone.
So if you had
example.com, then you could create an A record
www which points to a specific ip address, or maybe you create a
blog CNAME record which acts as an alias to another service such as GitHub pages (we’ll see this demonstrated later on when looking at the different types of records in more detail).
Ultimately you have control over your zone (
example), and everything to the left of it, until you reach a new zone that has been delegated to another entity.
Fully Qualified Domains
We should be clear that a ‘record’ isn’t just the hostname part (e.g.
www). The record looks more like
www.example.com. (notice the dot on the end which indicates the ‘root’).
Most registrars provide a bit of visual sugar in their applications which mean you can create a record for
www.example.com. but only require you to enter
www, as they will add the ‘origin’ (e.g.
example.com.) onto the end of the
www automatically for you.
Don’t be confused and think the ‘record’ is just
www; it’s not. This is why they are typically referred to as a “fully qualified domain” (FQD).
The dot on the end of the FQD indicates the root, the starting point of the DNS lookup hierarchy.
It’s nice to be able to see a practical example of how authority zones work (and in this case it’ll help with understanding some later examples I’ll be showing to you).
I have the domain
integralist.co.uk. It has a zone defined there, but it also has a separate zone defined by the host/sub domain
www.integralist.co.uk is controlled by another entity (in my case a GitHub related entity).
This is why when looking at the SOA record (we’ll explain what this is later, but in summary it stands for “Start of Authority”) for
integralist.co.uk we’ll see that (as of 2015) 123-Reg is the authoritative name server, where as if you look at
www.integralist.co.uk you’ll see that (again, as of 2015) Fastly is the authoritative name server as the
www host is set-up as a CNAME that is an alias pointing to GitHub, which in turn is a domain handled by Fastly.
We’ve mentioned ‘name servers’ a few times so far in this article and that’s because they’re a key component within the lookup process for a DNS resource. A ‘name server’ is a server that runs DNS software and is capable of mapping an ip to an easier to read/remember identifier.
This is why the resolver pings a set of root name servers, as it knows it’ll either get back the ip for the requested domain name, or it’ll be referred to some other name server that can provide that information.
When handling the DNS for a specific zone within your domain, you’ll likely set a NS (NameServer) record to point to a DNS service which allows you to administer DNS services for the zone you are the owner of. These name servers are typically referred to as a “primary” and “secondary” name server.
The primary/secondary name servers are effectively where the authoritative name server (the servers handling DNS responsibilities) is split into sub sections. You’ll have one ‘primary’ name server that contains the ‘zonedata’ file(s) - also known as a zonefile - and then the secondary name server(s) will reference that zonefile via a mechanism known as BIND (which is one of the largest DNS software implementations available).
Note: the way zonefiles are replicated is a much bigger discussion topic and falls outside the focus of this article, but in short there have been a few alternative mechanisms implemented since BIND; such as: rsync, git and even database replication
I want to take a slight detour now and quickly discuss a set of shell commands that are useful in debugging and querying the DNS. After this section I’ll be explaining the various types of records available, and I’ll be using the following commands to help me demonstrate the different record types.
So for the time being, don’t worry too much if you don’t feel you have a good handle on these commands after reading this section as this is just a light(ish) introduction, whereby I’ll start to elaborate on their usage more in the subsequent sections.
Taking the description direct from the manual:
The whois utility looks up records in the databases maintained by several Network Information Centers (NICs).
So if you want a very top level and general view of a domain and who owns/manages it, then the
whois command is for you. Typically you’ll use it to see who has registered a domain and to see the state of the domain (when was it last updated? when is it expiring? which organisation handles the DNS services? etc).
Let’s see what sort of data we get back when querying the domain for my website:
This would provide the following response:
Domain name: integralist.co.uk Registrant: Mark McDonnell Registrant type: UK Individual Registrant's address: The registrant is a non-trading individual who has opted to have their address omitted from the WHOIS service. Data validation: Nominet was able to match the registrant's name and address against a 3rd party data source on 10-Dec-2012 Registrar: 123-Reg Limited t/a 123-reg [Tag = 123-REG] URL: http://www.123-reg.co.uk Relevant dates: Registered on: 19-Jul-2009 Expiry date: 19-Jul-2017 Last updated: 12-Jul-2015 Registration status: Registered until expiry date. Name servers: ns.123-reg.co.uk ns2.123-reg.co.uk
Note: the output will differ depending on the TLD (Top Level Domain)
as they are managed by different NICs (Network Information Centers)
Now there can be problems when doing a simple
whois <domain> query. For example, the below output is the result of executing the command
whois google.com. You’ll notice that we get back multiple name servers responsible for a
google.com domain (and not always the official Google you’re expecting):
Whois Server Version 2.0 Domain names in the .com and .net domains can now be registered with many different competing registrars. Go to http://www.internic.net for detailed information. Aborting search 50 records found ..... GOOGLE.COM.AFRICANBATS.ORG GOOGLE.COM.ANGRYPIRATES.COM GOOGLE.COM.AR GOOGLE.COM.AU GOOGLE.COM.BAISAD.COM GOOGLE.COM.BEYONDWHOIS.COM GOOGLE.COM.BR GOOGLE.COM.CN GOOGLE.COM.CO GOOGLE.COM.DO GOOGLE.COM.FORSALE GOOGLE.COM.HACKED.BY.JAPTRON.ES GOOGLE.COM.HANNAHJESSICA.COM GOOGLE.COM.HAS.LESS.FREE.PORN.IN.ITS.SEARCH.ENGINE.THAN.SECZY.COM GOOGLE.COM.HK GOOGLE.COM.HOUDA.DO.YOU.WANT.TO.MARRY.ME.JEN.RE GOOGLE.COM.IS.APPROVED.BY.NUMEA.COM GOOGLE.COM.IS.NOT.HOSTED.BY.ACTIVEDOMAINDNS.NET GOOGLE.COM.LASERPIPE.COM.DOMAINPENDINGDELETE.COM GOOGLE.COM.LOLOLOLOLOL.SHTHEAD.COM GOOGLE.COM.MX GOOGLE.COM.MY GOOGLE.COM.NS1.CHALESHGAR.COM GOOGLE.COM.NS2.CHALESHGAR.COM GOOGLE.COM.PE GOOGLE.COM.PK GOOGLE.COM.SA GOOGLE.COM.SHQIPERIA.COM GOOGLE.COM.SOUTHBEACHNEEDLEARTISTRY.COM GOOGLE.COM.SPAMMING.IS.UNETHICAL.PLEASE.STOP.THEM.HUAXUEERBAN.COM GOOGLE.COM.SPROSIUYANDEKSA.RU GOOGLE.COM.SUCKS.FIND.CRACKZ.WITH.SEARCH.GULLI.COM GOOGLE.COM.TESTZZZZ.3000-RI.COM GOOGLE.COM.TR GOOGLE.COM.TW GOOGLE.COM.UA GOOGLE.COM.UK GOOGLE.COM.UY GOOGLE.COM.VABDAYOFF.COM GOOGLE.COM.VN GOOGLE.COM.WORDT.DOOR.VEEL.WHTERS.GEBRUIKT.SERVERTJE.NET GOOGLE.COM.YUCEHOCA.COM GOOGLE.COM.YUCEKIRBAC.COM GOOGLE.COM.ZNAET.PRODOMEN.COM GOOGLE.COM.ZZZZZ.GET.LAID.AT.WWW.SWINGINGCOMMUNITY.COM GOOGLE.COM.ZZZZZZZZZZZZZ.GET.ONE.MILLION.DOLLARS.AT.WWW.UNIMUNDI.COM GOOGLE.COM.ZZZZZZZZZZZZZZZZZZZZ.LOLLERSKATES.RENDRAG.NET GOOGLE.COM.ZZZZZZZZZZZZZZZZZZZZZZZZZZ.HAVENDATA.COM GOOGLE.COMICTOWEL.COM GOOGLE.COM
Only the last item in that list is the genuine Google domain we wanted to query (
GOOGLE.COM). So how do we query that specific domain and not get back all these other variants? To do that we need to find out the ‘whois server’ for that domain.
To find out the ‘whois server’ (that is, the server which holds the ‘whois record’) we need to use the
= sign within our command, like so:
whois '=google.com' and from there you can discover the whois server and then we can use that information to help us query the server more directly.
The following output is from executing
whois '=google.com' and again is shortened for brevity (as there are quite a few results that come through), but this time we’re getting the
Whois Server information passed through. Notice out of the three records returned that only the last one is a genuine Google domain:
Server Name: GOOGLE.COM.ZZZZZZZZZZZZZZZZZZZZZZZZZZ.HAVENDATA.COM IP Address: 220.127.116.11 Registrar: PDR LTD. D/B/A PUBLICDOMAINREGISTRY.COM Whois Server: whois.PublicDomainRegistry.com Referral URL: http://www.PublicDomainRegistry.com Server Name: GOOGLE.COMICTOWEL.COM IP Address: 18.104.22.168 Registrar: GODADDY.COM, LLC Whois Server: whois.godaddy.com Referral URL: http://registrar.godaddy.com Domain Name: GOOGLE.COM Registrar: MARKMONITOR INC. Sponsoring Registrar IANA ID: 292 Whois Server: whois.markmonitor.com Referral URL: http://www.markmonitor.com Name Server: NS1.GOOGLE.COM Name Server: NS2.GOOGLE.COM Name Server: NS3.GOOGLE.COM Name Server: NS4.GOOGLE.COM Status: clientDeleteProhibited http://www.icann.org/epp#clientDeleteProhibited Status: clientTransferProhibited http://www.icann.org/epp#clientTransferProhibited Status: clientUpdateProhibited http://www.icann.org/epp#clientUpdateProhibited Status: serverDeleteProhibited http://www.icann.org/epp#serverDeleteProhibited Status: serverTransferProhibited http://www.icann.org/epp#serverTransferProhibited Status: serverUpdateProhibited http://www.icann.org/epp#serverUpdateProhibited Updated Date: 20-jul-2011 Creation Date: 15-sep-1997 Expiration Date: 14-sep-2020
Note: the use of = in the
whoiscommand doesn’t work with .uk TLD’s
You’ll see an error about a strict no
Once you find the domain you’re after (in this case we want the real
google.com), you can filter out the
Whois Server line and use that to query the domain directly via the whois server responsible for the actual
google.com domain (this is done by adding the
-h flag to the
whois -h whois.markmonitor.com google.com
Doing this we can now see the actual output we want:
Domain Name: google.com Registry Domain ID: 2138514_DOMAIN_COM-VRSN Registrar WHOIS Server: whois.markmonitor.com Registrar URL: http://www.markmonitor.com Updated Date: 2015-06-12T10:38:52-0700 Creation Date: 1997-09-15T00:00:00-0700 Registrar Registration Expiration Date: 2020-09-13T21:00:00-0700 Registrar: MarkMonitor, Inc. Registrar IANA ID: 292 Registrar Abuse Contact Email: firstname.lastname@example.org Registrar Abuse Contact Phone: +1.2083895740 Domain Status: clientUpdateProhibited (https://www.icann.org/epp#clientUpdateProhibited) Domain Status: clientTransferProhibited (https://www.icann.org/epp#clientTransferProhibited) Domain Status: clientDeleteProhibited (https://www.icann.org/epp#clientDeleteProhibited) Registry Registrant ID: Registrant Name: Dns Admin Registrant Organization: Google Inc. Registrant Street: Please contact email@example.com, 1600 Amphitheatre Parkway Registrant City: Mountain View Registrant State/Province: CA Registrant Postal Code: 94043 Registrant Country: US Registrant Phone: +1.6502530000 Registrant Phone Ext: Registrant Fax: +1.6506188571 Registrant Fax Ext: Registrant Email: firstname.lastname@example.org Registry Admin ID: Admin Name: DNS Admin Admin Organization: Google Inc. Admin Street: 1600 Amphitheatre Parkway Admin City: Mountain View Admin State/Province: CA Admin Postal Code: 94043 Admin Country: US Admin Phone: +1.6506234000 Admin Phone Ext: Admin Fax: +1.6506188571 Admin Fax Ext: Admin Email: email@example.com Registry Tech ID: Tech Name: DNS Admin Tech Organization: Google Inc. Tech Street: 2400 E. Bayshore Pkwy Tech City: Mountain View Tech State/Province: CA Tech Postal Code: 94043 Tech Country: US Tech Phone: +1.6503300100 Tech Phone Ext: Tech Fax: +1.6506181499 Tech Fax Ext: Tech Email: firstname.lastname@example.org Name Server: ns4.google.com Name Server: ns2.google.com Name Server: ns3.google.com Name Server: ns1.google.com DNSSEC: unsigned
The structure of this variation of the
whois command is:
whois -h <whois_server> <domain>
Taking the description direct from the manual:
dig (domain information groper) is a flexible tool for interrogating DNS name servers. It performs DNS lookups and displays the answers that are returned from the name server(s) that were queried
dig it turns out is, in a practical sense, a great DNS debugging tool. Let’s take a look at a quick example where we want to find out some DNS related information for the domain
Executing this command will give us back the following response:
; <<>> DiG 9.8.3-P1 <<>> integralist.co.uk ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 5590 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 2 ;; QUESTION SECTION: ;integralist.co.uk. IN A ;; ANSWER SECTION: integralist.co.uk. 14400 IN A 22.214.171.124 ;; AUTHORITY SECTION: integralist.co.uk. 151529 IN NS ns2.123-reg.co.uk. integralist.co.uk. 151529 IN NS ns.123-reg.co.uk. ;; ADDITIONAL SECTION: ns.123-reg.co.uk. 7 IN A 126.96.36.199 ns2.123-reg.co.uk. 7 IN A 188.8.131.52 ;; Query time: 94 msec ;; SERVER: 192.168.1.1#53(192.168.1.1) ;; WHEN: Sun Sep 27 15:32:02 2015 ;; MSG SIZE rcvd: 126
This was a standard
dig command and so you’ll notice that the response has been split up into sections:
HEADER: displays which options and flags have been enabled when executing the command (we’ll look at both options and flags in more detail later)
QUESTION: displays which record you requested for the specified domain
ANSWER: displays ttl (time to live) followed by record/ip for the specified domain
AUTHORITY: displays the authoritative name servers (i.e. the service handling DNS responsibilities)
ADDITIONAL: displays all the authoritative name servers available for querying (inc. their remaining ttl)
STATS: displays basic stats such as query time, server ip, date of query, message size
You can also specify a specific record type you want to query, like so:
dig ns integralist.co.uk
Which gives us back the following response:
; <<>> DiG 9.8.3-P1 <<>> ns integralist.co.uk ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 57285 ;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 2 ;; QUESTION SECTION: ;integralist.co.uk. IN NS ;; ANSWER SECTION: integralist.co.uk. 2671 IN NS ns.hosteurope.com. integralist.co.uk. 2671 IN NS ns2.hosteurope.com. ;; ADDITIONAL SECTION: ns.hosteurope.com. 284 IN A 184.108.40.206 ns2.hosteurope.com. 48488 IN A 220.127.116.11 ;; Query time: 36 msec ;; SERVER: 192.168.1.1#53(192.168.1.1) ;; WHEN: Sun Sep 27 22:15:11 2015 ;; MSG SIZE rcvd: 116
In the response for a
dig command, under the header area, you’ll notice specific flags being set. These flags determine how the dig command should handle certain situations. The following flags are what you’ll likely see the most:
- QR (Query Response)
- RD (Recursion Desired)
- RA (Recursion Available)
- TC (TrunCated)
- AA (Authoritative Answer)
When you execute a
dig command you’ll pretty much always see QR in the response (e.g.
flags: qr) because it indicates what you’re looking at is in fact the response.
The RD (“Recursion Desired”) flag (e.g.
flags: qr rd ra) means the query will keep referring queries until it finds an answer from an authoritative name server. The RD flag is set by default but can be disabled with the
+norecurse option. The reason for disabling this flag would be to help you identify if a RR (resource record) exists in a cache.
Note: the RA flag (“Recursion Available”) in the response means the server is willing to allow recursion
So if you wanted to see if one of the authoritative name servers for
integralist.co.uk had its
www CNAME record cached, then you would execute the following command:
dig @ns.123-reg.co.uk www.integralist.co.uk +norecurse
If the response doesn’t have an
ANSWER section, then you know it has been cached.
The TC flag (“TrunCated”) is used for when a UDP response is larger than 512 bytes. The response will set TC to 1 and so the client/resolver will need to try again, this time using TCP instead of UDP so it can retrieve the full response.
Note: enabling TC can be used as a DDoS mitigation technique - where the layers in front of your name servers will purposely set TC on - so if an attacker tries using UDP when attacking your DNS, then their request will immediately fail and they’ll be required to try again using TCP (as TCP connections is easier to filter); but it’s unlikely that an automated DDoS attack will retry a failed attempt
You’ll normally see the AA flag in the response (e.g.
flags: qr aa) when you query an authoritative name server directly (like we did above when checking to see if the
www CNAME for
integralist.co.uk was stored in a cache).
Enabling ‘no stats’:
dig www.integralist.co.uk +nostats
The response will be missing the following section:
;; Query time: 7 msec ;; SERVER: 192.168.253.250#53(192.168.253.250) ;; WHEN: Wed Sep 23 08:52:18 2015 ;; MSG SIZE rcvd: 273
Note: personally I think this is safe to enable for the majority of use cases (stats are just visual noise I can do without)
Enabling ‘no comments’:
dig www.integralist.co.uk +nocomments
The response will look something like the following:
; <<>> DiG 9.8.3-P1 <<>> www.integralist.co.uk +nocomments ;; global options: +cmd ;www.integralist.co.uk. IN A www.integralist.co.uk. 13920 IN CNAME integralist.github.com. integralist.github.com. 17 IN CNAME github.map.fastly.net. github.map.fastly.net. 2 IN A 18.104.22.168 ;; Query time: 0 msec ;; SERVER: 192.168.253.250#53(192.168.253.250) ;; WHEN: Wed Sep 23 08:54:50 2015 ;; MSG SIZE rcvd: 126
You’ll notice that all the major ‘sections’ have been removed, such as
;; Got answer:,
;; QUESTION SECTION: and
;; ANSWER SECTION:
Trace is disabled by default so this is the first option we’ve looked at that actually needs ‘enabling’:
dig www.integralist.co.uk +trace
What this will do is display the full delegation path and show all referrals:
; <<>> DiG 9.8.3-P1 <<>> www.integralist.co.uk +trace ;; global options: +cmd . 489215 IN NS e.root-servers.net. . 489215 IN NS k.root-servers.net. . 489215 IN NS m.root-servers.net. . 489215 IN NS h.root-servers.net. . 489215 IN NS d.root-servers.net. . 489215 IN NS j.root-servers.net. . 489215 IN NS f.root-servers.net. . 489215 IN NS c.root-servers.net. . 489215 IN NS g.root-servers.net. . 489215 IN NS l.root-servers.net. . 489215 IN NS b.root-servers.net. . 489215 IN NS i.root-servers.net. . 489215 IN NS a.root-servers.net. ;; Received 496 bytes from 192.168.1.1#53(192.168.1.1) in 85 ms uk. 172800 IN NS nsa.nic.uk. uk. 172800 IN NS nsb.nic.uk. uk. 172800 IN NS nsc.nic.uk. uk. 172800 IN NS nsd.nic.uk. uk. 172800 IN NS dns1.nic.uk. uk. 172800 IN NS dns2.nic.uk. uk. 172800 IN NS dns3.nic.uk. uk. 172800 IN NS dns4.nic.uk. ;; Received 459 bytes from 22.214.171.124#53(126.96.36.199) in 96 ms integralist.co.uk. 172800 IN NS ns.123-reg.co.uk. integralist.co.uk. 172800 IN NS ns2.123-reg.co.uk. ;; Received 82 bytes from 188.8.131.52#53(184.108.40.206) in 75 ms www.integralist.co.uk. 14400 IN CNAME integralist.github.com. ;; Received 75 bytes from 220.127.116.11#53(18.104.22.168) in 21 ms
For a full list of options that you can play around with, I suggest reviewing:
Taking the description direct from the manual:
hostis a simple utility for performing DNS lookups
It is normally used to convert names to IP addresses and vice versa
So a much more basic version of
dig but in certain circumstances I could imagine it offering more semantic clarity.
A simple example would be as follows:
Running the above command would return to us the ip address for the specified domain. In this case it would return:
www.integralist.co.uk is an alias for integralist.github.com. integralist.github.com is an alias for github.map.fastly.net. github.map.fastly.net has address 22.214.171.124
Notice it displayed the full resolution path:
- CNAME alias to Github pages
- CNAME alias to Fastly
- ip address for Fastly
Now if you tried using the non-www version:
You’d find you get a different response:
integralist.co.uk has address 126.96.36.199
This is because my domain uses a redirect to
www.integralist.co.uk, which is then a CNAME alias to GitHub. So if I carried out the reverse lookup using the ip address above:
I would subsequently get back the following response, which indicates that my website is actually hosted with GitHub Pages:
188.8.131.52.in-addr.arpa domain name pointer pages.github.com.
digcan do the same with
dig -x <ip>
Taking the description direct from the manual:
nslookupis a program to query Internet domain name servers
From here you’ll be prompted to specify a domain, so for example we could now type:
Which would return the following response:
Server: 192.168.1.1 Address: 192.168.1.1#53 Non-authoritative answer: Name: integralist.co.uk Address: 184.108.40.206
If I was to now use
host to find the name this ip resolves to:
It would display:
220.127.116.11.in-addr.arpa domain name pointer pages.github.com.
Cool, so again we end up at GitHub pages where my website is hosted.
If I was to use
nslookup on the
www variation of my website then I’d see a slightly different response:
> www.integralist.co.uk Server: 192.168.1.1 Address: 192.168.1.1#53 Non-authoritative answer: www.integralist.co.uk canonical name = integralist.github.com. integralist.github.com canonical name = github.map.fastly.net. Name: github.map.fastly.net Address: 18.104.22.168
We can also use
nslookup to return specific record information. Imagine we want to see the SOA record for
integralist.co.uk. We can do this by typing
set querytype=soa followed by the domain, like so:
nslookup > set querytype=soa > integralist.co.uk Server: 192.168.1.1 Address: 192.168.1.1#53 Non-authoritative answer: integralist.co.uk origin = ns.hosteurope.com mail addr = hostmaster.integralist.co.uk serial = 2012022703 refresh = 86400 retry = 3600 expire = 1209600 minimum = 14400 Authoritative answers can be found from: integralist.co.uk nameserver = ns.123-reg.co.uk. integralist.co.uk nameserver = ns2.123-reg.co.uk. ns.123-reg.co.uk internet address = 22.214.171.124 ns2.123-reg.co.uk internet address = 126.96.36.199
We can also see this provides us with an authoritative answer. But as we already know, querying the
www host/sub domain will return us slightly different information:
Server: 192.168.1.1 Address: 192.168.1.1#53 Non-authoritative answer: www.integralist.co.uk canonical name = integralist.github.com. integralist.github.com canonical name = github.map.fastly.net. Authoritative answers can be found from: fastly.net origin = ns1.p04.dynect.net mail addr = hostmaster.fastly.com serial = 2015092706 refresh = 3600 retry = 600 expire = 604800 minimum = 3600
So if we decided to try this again but specify the record type as being a CNAME record:
nslookup > set querytype=cname > integralist.co.uk Server: 192.168.1.1 Address: 192.168.1.1#53 Non-authoritative answer: *** Can't find integralist.co.uk: No answer Authoritative answers can be found from: integralist.co.uk origin = ns.hosteurope.com mail addr = hostmaster.integralist.co.uk serial = 2012022703 refresh = 86400 retry = 3600 expire = 1209600 minimum = 14400
We see we get back an error that says there is no answer for this type of query. But if I was to try again and now use the host/sub domain
www (which I know to be a CNAME) then we get the following response:
Server: 192.168.1.1 Address: 192.168.1.1#53 Non-authoritative answer: www.integralist.co.uk canonical name = integralist.github.com. Authoritative answers can be found from: integralist.co.uk nameserver = ns.hosteurope.com. integralist.co.uk nameserver = ns2.hosteurope.com. ns.hosteurope.com internet address = 188.8.131.52 ns2.hosteurope.com internet address = 184.108.40.206
Now we see that
www.integralist.co.uk is a CNAME (Canonical Name) to
Note: to exit
There are many different RR (Resource Record) types availble within DNS, the following are the most popular:
The NS record should be pointed to the entity responsible for handling DNS duties for your domain.
You must have at least two name server records for the sake of resiliency.
The sequence/ordering of listed name servers has nothing to do with priority (unlike with MX records, see below for more details). For example, the following process DOESN’T happen: “query the A name server first and if no response then query the B name server”.
Multiple NS records simply means that there are multiple name servers available to query for the records required by the client application.
The NS record indicates the authoritative name servers for the current origin. But remember that different parts of an overall domain can be controlled by different entities (i.e. different Zone/SOA).
If you’re interested in seeing which root servers are responsible for knowing about a particular TLD, then again we can use
dig to find this information. For example, to see the ccTLD name servers for
.co.uk execute the following command:
dig +short -t ns co.uk
Note: we use the
+shortflag provided by
This enables us to reduce the visual noise
Another trick is to use
Which gives you reduced noise + additional info
This will return the following response:
dnsd.nic.uk. dns4.nic.uk. nsb.nic.uk. dns1.nic.uk. dns2.nic.uk. nsc.nic.uk. nsa.nic.uk. dns3.nic.uk.
If you’re interested in seeing the very root servers which your resolver will query for information about a particular domain then you can use the following variation of the
dig +short -t ns .
Note: you’ll notice the dot on the end
As we’ve mentioned previously,
the dot represents the ‘root’ of the DNS hierarchy
Executing this command will return the following output:
a.root-servers.net. b.root-servers.net. c.root-servers.net. d.root-servers.net. e.root-servers.net. f.root-servers.net. g.root-servers.net. h.root-servers.net. i.root-servers.net. j.root-servers.net. k.root-servers.net. l.root-servers.net. m.root-servers.net.
An A record should point to an ip address (i.e. it’s an “address record”).
In order to provide redundancy, you can have multiple A records associated with a domain. For example, imagine your service is sitting behind a load balancer such as AWS ELB. What you would likely do is create a CNAME (see below section for more details) that points to your load balancer’s own CNAME (it’s unlikely you’ll point your domain to a direct ip address when using a load balancer because if the load balancer changes then you’d need to update your DNS, which would result in potentially significant downtime) and then the load balancer would handle the responsibility of creating multiple A records that point to the actual ip addresses of your running servers.
A CNAME record is one that points not to an ip address (like an A record does), but instead points to either a CNAME or A record.
Let’s see a real world example by
diging this website (specifically the
www host name):
The information returned (see below), indicates that we have a CNAME (
www.integralist.co.uk.) that points to GitHub (
integralist.github.com.); and that in turn points to an A record (
github.map.fastly.net.), which itself points to the ip address of the server hosting the content:
;; ANSWER SECTION: www.integralist.co.uk. 14266 IN CNAME integralist.github.com. integralist.github.com. 2 IN CNAME github.map.fastly.net. github.map.fastly.net. 17 IN A 220.127.116.11
I wont spend much time on MX records, but in short it stands for “Mail eXchange” and you can have multiple records for the purposes of redundancy. Each MX record has a ‘priority value’ which indicates a relative value compared to the other MX records listed. What this means is that a lower value is considered a higher priority and so it’s used first when directing email.
I don’t have email set-up for my
integralist.co.uk domain so
dig mx integralist.co.uk wont help me demonstrate anything. Instead let’s look at the BBC:
dig mx bbc.co.uk +short
This will return the following response:
20 cluster1a.eu.messagelabs.com. 10 cluster1.eu.messagelabs.com.
As you can see, the BBC appear to be using
http://messagelabs.com/ as the entry point for managing their email systems.
Near the beginning of this article we discussed the concept of ‘zones’ to indicate which entity had authority over the DNS for a specific section of a domain. An SOA record (which stands for “Start of Authority”) details specific information related to TTLs regarding the current zone.
So for example, if I look at the SOA for
integralist.co.uk using the following command:
dig soa integralist.co.uk +short
I would get back the following response:
ns.hosteurope.com. hostmaster.integralist.co.uk. 2012022703 86400 3600 1209600 14400
Let’s break down this response into sections:
ns.hosteurope.com.: primary authoritative name server
hostmaster.integralist.co.uk.: party responsible for your domain
2012022703: timestamp that is updated when the domain is updated
86400: zone refresh TTL (in seconds)
3600: failed zone refresh retry (in seconds)
1209600: zone authoritative ownership expiration (in seconds)
14400: negative result TTL (how long resolver should consider a ‘negative result’ for a subdomain to be a valid result before retrying a query to the host/subdomain
Each ‘zone’ (i.e. each name server/entity who has authority at a specific point of the domain) will provide their own SOA record. So if I were to look at the CNAME
integralist.co.uk, then I would find that this points to a GitHub CNAME which points to a Fastly CNAME, and whose authoritative name servers are (as of 2015)
ns1.p04.dynect.net. This means a new ‘zone’ is defined by Fastly and so they have authority to add host names to the left of the
www section of the overall domain:
dig soa www.integralist.co.uk
I would get back the following response:
;; QUESTION SECTION: ;www.integralist.co.uk. IN SOA ;; ANSWER SECTION: www.integralist.co.uk. 14389 IN CNAME integralist.github.com. integralist.github.com. 19 IN CNAME github.map.fastly.net. ;; AUTHORITY SECTION: fastly.net. 289 IN SOA ns1.p04.dynect.net. hostmaster.fastly.com. 2015092706 3600 600 604800 3600
The purpose of an SRV record is simply to provide information about services available via your domain. You’ll find services such as SkyDNS and Etc use DNS and specifically SRV records as a way of handling distributed ‘service discovery’.
There is a very specific format to the records, which looks something like the following:
Note: the ‘name’ should be a easy to identify name
but otherwise there isn’t any other structure or restrictions I know of
So if I wanted to indicate to some other service or application that I had a website available somewhere underneath the top level domain
integralist.co.uk then I would create the following SRV record:
You could then verify the SRV record was set-up by using
dig like so:
dig _website._tcp.integralist.co.uk SRV +short +noshort
This would respond with the following output:
_website._tcp.integralist.co.uk. 14400 IN SRV 11 1 80 www.integralist.co.uk.
I set this up using my DNS provider’s own GUI (so your own provider may have a different interface), but effectively the response indicates to a requester that I have a single service available at
www.integralist.co.uk which you can access via TCP on port
The full details of which are broken down into sections, like so:
11(a lower number is a higher priority)
1 80 www.integralist.co.uk.(
<weight> <port> <fully-qualified origin>)
priorityis useful for when you have multiple hosts configured for the same service, while the
weightis typically used for services that have the same
The PTR record is surprisingly complex in its implementation and yet fairly simple with regards to its purpose and set-up. In short you use the PTR to do a reverse-mapping, which is the process of forwarding an ip to a hostname (the typical RR process is known as forward-mapping, where by you forward a hostname onto an ip).
The purpose of a PTR record is traditionally for authentication/security reasons. Think of mail servers that try to prevent spam messages being sent from what looks like valid hosts. In this scenario the mail server will attempt to verify that the host/ip match both ways: forward and reverse. If they don’t match then the mail is rejected.
Note: in the past when I’ve had clients complain their emails are being rejected by their intended recipient, you’ll find they’re missing a PTR record in their DNS. The recipient’s email provider will nearly always request we add a PTR record to our client’s DNS
I won’t go into the implementation details here, as I mentioned earlier it’s quite complex, but in essence there is another top level domain called
arpa with a sub level domain
This new domain works in a similar way to gTLD and ccTLDs in the sense that it has third level domains, but the difference is that the order is reversed from this point. So if your web server’s ip was
18.104.22.168 then the third level domain would use
185 as the name. These third level domains will also have their own zonefiles that describe the DNS at that level.
In the zonefile you would see something like the following (notice the ip address we mentioned above has been reversed due to the standard DNS hierarchy structure):
Note: convention states that although domains are case-insensitive, the
in-addr.arpa.should be capitalised
As far as the PTR record is concerned, you now take the last part of your ip and use that as the name of your PTR record. For example, if you had the ip
133 would be the name of the PTR record, while its value would be a fully qualified domain such as
133 IN PTR www.example.com.
Note: because we’ve defined an
$ORIGINin our zonefile that is an arpa address we’d typically use fully qualified domain names for all other RRs (such as we have in the above PTR example)
This now means that the DNS can carry out a reverse-lookup, and for the ip
22.214.171.124 it’ll locate the
133 PTR record and see that is resolves to
www.example.com. which when doing a forward-mapping DNS request results in the ip
126.96.36.199 thus providing reasonable authentication that the queries are related and not being spoofed.
The TXT record simply provides a description for the domain being queried. You must also wrap the description in double quotes (if you’re adding this record via a DNS provider then they might do this for you as you’ll likely be typing the value of this record into a HTML input field).
Let’s see a real-world example of this record using both
dig txt my-service-description.integralist.co.uk +short host -t txt my-service-description.integralist.co.uk
This query should return a response similar to the following (it’ll be slightly different for the
host command as it has no comparible flag to
"integralist.co.uk is a tech blog"
Note: if no TXT record is found then
digwill return nothing, where as
integralist.co.uk has no TXT record
When I initially set-up the TXT record, it wasn’t available via my local DNS resolver and so in the following example I query one of the authoritative name servers as well as a Google server to see the new TXT record before it has propagated around the internet:
dig txt my-service-description.integralist.co.uk @ns.123-reg.co.uk. +short dig txt my-service-description.integralist.co.uk @188.8.131.52 +short
184.108.40.206is one of Google’s own DNS name servers and although not an authoritative name server for my domain, it was very fast at getting the new record
TTL (Time to Live)
Every resource record (e.g. A, MX, CNAME etc) has a TTL set for it. When you make a request for a record, it will be cached for the length of time that the TTL is set. This is both good and a bad thing (as is usually the case with caching scenarios) as you need to find a good balance between a TTL that’s too high (meaning you lose the ‘freshness’ for DNS updates) and a TTL that’s too low (and subsequently ends up affecting the performance of your server).
Consider the following example, which is a query for an MX record from the BBC:
dig mx bbc.co.uk +short +noshort
The response to this query is as follows:
bbc.co.uk. 300 IN MX 10 cluster1.eu.messagelabs.com. bbc.co.uk. 300 IN MX 20 cluster1a.eu.messagelabs.com.
We can see the TTL for this record is 300 seconds (that’s 5 minutes). If you were to execute the same
dig command again, you would now notice the value for the TTL has dropped. Run it yet again and you’ll see the value drops even more. This is the TTL expiring second by second.
So if you make a change to your DNS and are wondering why it hasn’t taken effect, this might be because it’s cached and waiting to expire before the new changes are visible.
If you want to bypass your local ISP caching of DNS requests, then you’ll need to query an authoritative name server directly to see if the change has indeed been made and is just waiting to take effect.
The following snippet demonstrates the command syntax structure using
dig <domain> @<authoritative_nameserver>
If after executing the query the response is the one you expect, then it means the record has been updated in your DNS provider’s system but the changes still need to propagate.
Although a fairly long article, this has really only barely scratched the surface of what’s possible with DNS. I’ll be improving the contents of this page over the next few weeks, as I learn more, so stayed tuned for updates. If there are any glaring issues or inaccurate details then do please let me know. Feedback is always welcome.