DNS 101
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:
74.125.224.72
An IPv6 identifier is 128 bits long, written in hexadecimal and separated by colons:
3ffe:1900:4545:3:200:f8ff:fe21:67cf
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 74.125.224.72
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: google.com
.
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).
Lookup Process
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:
- Resolver
- Root Name Server(s)
- TLD Name Server(s)
- SLD Name Server(s)
Resolver
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 /etc/resolv.conf
(server-side).
The resolver will have a ‘root hints’ file with a hardcoded list of root name servers (there are thirteen root 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).
Resolvers also include additional logic for invalidating the favoured root name server, but that’s outside the scope of this article.
† there are only thirteen root server clusters, because that’s all that can fit inside a single UDP packet. Historically, DNS has operated through UDP packets, meaning the response to a request can never be more than 512 bytes.
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)
Tree Hierarchy
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 www.example.com
):
. (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.com
to 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.com
query to the .com gTLD - The gTLD responds to say “go talk to the
example.com
authoritative name server” - The resolver then sends the same
www.example.com
query 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
DNS Structure
Each period in a ‘domain’ is actually a ‘level’. Hence extensions such as .com
or .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:
<protocol><hostname>.<sld>.<tld>.
This would materialise into something like:
http://www.example.com
Where…
http://
is the protocolwww
is the hostnamesld
is ‘example’tld
is ‘com’
Note: things get a little more complicated with ccTLDs
As country codes can have a third level (e.g.example.co.uk
)
uk
(TLD),co
(SLD),example
(3LD)
Typically the combination of <sld><tld>
is referred to as the ‘domain name’.
Authority Zones
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).
Zonefile
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 example.com
:
$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. ns1
, www
, bill
and 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 ...
Note: where
...
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.$TTL
defines 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$ORIGIN
- The
$ORIGIN
directive is not mandatory. If not provided, then BIND (the DNS server software) will acquire a value from the configuration filenamed.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
IN
as 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
.
then the$ORIGIN
is 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
rr
is 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)
† the fields date back to an era where there were multiple computer networks in competition with each other. IN (internet) was just one of many. Others at the time might have been
CH
(CHAOSNET) orHS
(Hesiod, and in part is still used by MIT students to this day). You’ll find all available references in the official DNS Parameters RFC.
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 .org
, .com
, .net
, .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 example.co.uk
).
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.
Practical example
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
. So 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, whereas 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.
Name Servers
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
Commands
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.
whois
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:
whois integralist.co.uk
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: 162.251.82.121
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: 216.239.32.21
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
whois
command doesn’t work with .uk TLD’s
You’ll see an error about a strict no=
character allowed
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
command):
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: abusecomplaints@markmonitor.com
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 contact-admin@google.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: dns-admin@google.com
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: dns-admin@google.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: dns-admin@google.com
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>
dig
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
So 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 integralist.co.uk
:
dig integralist.co.uk
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 192.30.252.153
;; 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 212.67.202.2
ns2.123-reg.co.uk. 7 IN A 92.51.159.40
;; 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 domainANSWER
: displays ttl (time to live) followed by record/ip for the specified domainAUTHORITY
: 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 212.67.202.2
ns2.hosteurope.com. 48488 IN A 92.51.159.40
;; 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
Flags
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).
option: nostats
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)
option: nocomments
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 185.31.18.133
;; 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:
option: trace
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 128.63.2.53#53(128.63.2.53) 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 103.49.80.1#53(103.49.80.1) in 75 ms
www.integralist.co.uk. 14400 IN CNAME integralist.github.com.
;; Received 75 bytes from 212.67.202.2#53(212.67.202.2) in 21 ms
Other options
For a full list of options that you can play around with, I suggest reviewing:
man dig
host
Taking the description direct from the manual:
host
is 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:
host www.integralist.co.uk
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 23.235.43.133
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:
host integralist.co.uk
You’d find you get a different response:
integralist.co.uk has address 192.30.252.153
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:
host 192.30.252.153
I would subsequently get back the following response, which indicates that my website is actually hosted with GitHub Pages:
153.252.30.192.in-addr.arpa domain name pointer pages.github.com.
Note:
dig
can do the same withdig -x <ip>
nslookup
Taking the description direct from the manual:
nslookup
is a program to query Internet domain name servers
nslookup
From here you’ll be prompted to specify a domain, so for example we could now type:
> integralist.co.uk
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: 192.30.252.153
If I was to now use host
to find the name this ip resolves to:
host 192.30.252.153
It would display:
153.252.30.192.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: 23.235.43.133
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 = 212.67.202.2
ns2.123-reg.co.uk internet address = 92.51.159.40
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 = 212.67.202.2
ns2.hosteurope.com internet address = 92.51.159.40
Now we see that www.integralist.co.uk
is a CNAME (Canonical Name) to integralist.github.com
.
Note: to exit
nslookup
press<Ctrl-c>
Record Types
There are many different RR (Resource Record) types availble within DNS, the following are the most popular:
NS
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
+short
flag provided bydig
This enables us to reduce the visual noise
Another trick is to use+short +noshort
together
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
command:
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.
A
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.
CNAME
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 dig
ing this website (specifically the www
host name):
dig www.integralist.co.uk
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 185.31.19.133
[!IMPORTANT] A CNAME in DNS serves to map one name to another source of truth for ALL DNS resource record types.
So if you have:
service.example.com. IN CNAME other.service.example.net.
An A Record lookup for service.example.com.
will return the A record of other.service.example.net.
An MX Record lookup for service.example.com.
will return the MX record of other.service.example.net.
A TXT Record lookup for service.example.com.
will return the TXT record of other.service.example.net.
MX
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.
SOA
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 serverhostmaster.integralist.co.uk.
: party responsible for your domain2012022703
: timestamp that is updated when the domain is updated86400
: 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 www
for 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. 201 3600 600 604800 3600
SRV
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:
_<name>._<protocol>.<domain>.
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:
_website._tcp.integralist.co.uk.
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 80
.
The full details of which are broken down into sections, like so:
Hostname
:_website._tcp
Type
:SRV
Priority
:11
(a lower number is a higher priority)TTL
:60
(in seconds)Destination
:1 80 www.integralist.co.uk.
(<weight> <port> <fully-qualified origin>
)
Note: the
priority
is useful for when you have multiple hosts configured for the same service, while theweight
is typically used for services that have the samepriority
value
PTR
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 in-addr
.
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 185.31.19.133
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):
$ORIGIN 19.31.185.IN-ADDR.ARPA.
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 185.31.19.133
then 133
would be the name of the PTR record, while its value would be a fully qualified domain such as www.example.com.
:
133 IN PTR www.example.com.
Note: because we’ve defined an
$ORIGIN
in 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 185.31.19.133
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 185.31.19.133
thus providing reasonable authentication that the queries are related and not being spoofed.
TXT
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
and host
commands:
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 dig
’s +short
flag):
"integralist.co.uk is a tech blog"
Note: if no TXT record is found then
dig
will return nothing, whereashost
will returnintegralist.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 @8.8.8.8 +short
Note:
8.8.8.8
is 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.
Local Caching
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
:
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.
References
Conclusion
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.