What is a DNS ZONE file: A Complete Tutorial on zone file and its contents
DNS (Domain name system) is the most critical infrastructure on the internet. Each and every user connected to the internet, knowingly or unknowingly make hundreds of DNS queries each and every day. So in a way, internet is almost of no use without the system called as DNS. The only way you can make use of internet without DNS, is to memorize all the numerical IP addresses associated with each and every domain(not only you will have to memorize, but will have remember which IP address is for which domain. So its an impossible task, and lets not discuss it).
If you are interested in understanding the basic working of a DNS query and how a server responds to that query, or in other words, if you want to understand how a computer uses a DNS server to resolve domain names to IP addresses, then i will recommend reading the below post.
Read: How does a DNS query Work
DNS architecture works on an inverted tree structure. At the top of the inverted tree is the 13 DNS root servers, and then comes the TLD(Top Level Domain) servers, and beneath the TLD servers comes the authoritative DNS server for a particular domain(sometimes called as secondary domains.)
The above shown diagram depicts the classification of DNS inverted tree structure. You can clearly see that the root servers are at the top of the inverted tree, gTLD(Generic Top Level Domains) & CCTLD(Country Code Top Level Domains) comes below the root servers, and then comes the DNS servers for an example domain.
Consider the above shown tree structure as the flow chart of a DNS name resolution. So for example, if you want to find the IP address of mail.example.com two types of DNS queries can be made. One is called Iterative & the other is called recursive(which is the normal configuration of all local DNS servers).
If you are interested in understanding the difference between iterative and recursive query, then read the below post, before going ahead with this post.
Read: What is the difference between iterative and recursive DNS query
Let's say you have a Linux machine as your personnel computer, and it has the below configuration inside the resolv.conf file(which mentions the DNS server for that computer)
[root@localhost ~]# cat /etc/resolv.conf nameserver 172.16.140.34 nameserver 172.16.140.33 [root@localhost ~]#
In the above shown resolv.conf file, there are two DNS servers that can be used to query for DNS requests. Now whenever you send a query for any domain, for example, you want the ip address for example.com. Then in that case the query first goes to the local DNS server (172.16.140.34 in our case).
If you want to understand the complete recursive query structure, i always recommend to do a dig + trace to understand the entire flow of the query. Let's do a dig + trace for example.com.
[root@localhost ~]# dig +trace example.com ; <<>> DiG 9.3.6-P1-RedHat-9.3.6-16.P1.el5 <<>> +trace example.com ;; global options: printcmd . 76094 IN NS b.root-servers.net. . 76094 IN NS e.root-servers.net. . 76094 IN NS j.root-servers.net. . 76094 IN NS g.root-servers.net. . 76094 IN NS i.root-servers.net. . 76094 IN NS h.root-servers.net. . 76094 IN NS c.root-servers.net. . 76094 IN NS m.root-servers.net. . 76094 IN NS l.root-servers.net. . 76094 IN NS f.root-servers.net. . 76094 IN NS d.root-servers.net. . 76094 IN NS k.root-servers.net. . 76094 IN NS a.root-servers.net. ;; Received 497 bytes from 172.16.140.34#53(172.16.140.34) in 0 ms com. 172800 IN NS a.gtld-servers.net. com. 172800 IN NS g.gtld-servers.net. com. 172800 IN NS d.gtld-servers.net. com. 172800 IN NS m.gtld-servers.net. com. 172800 IN NS f.gtld-servers.net. com. 172800 IN NS l.gtld-servers.net. com. 172800 IN NS h.gtld-servers.net. com. 172800 IN NS b.gtld-servers.net. com. 172800 IN NS c.gtld-servers.net. com. 172800 IN NS e.gtld-servers.net. com. 172800 IN NS j.gtld-servers.net. com. 172800 IN NS i.gtld-servers.net. com. 172800 IN NS k.gtld-servers.net. ;; Received 489 bytes from 192.228.79.201#53(b.root-servers.net) in 284 ms example.com. 172800 IN NS a.iana-servers.net. example.com. 172800 IN NS b.iana-servers.net. ;; Received 165 bytes from 192.5.6.30#53(a.gtld-servers.net) in 226 ms example.com. 172800 IN A 192.0.43.10 example.com. 172800 IN NS b.iana-servers.net. example.com. 172800 IN NS a.iana-servers.net. ;; Received 93 bytes from 199.43.132.53#53(a.iana-servers.net) in 100 ms
One major thing to understand here in the above shown trace query is the fact that, when you do a dig +trace, your local dns server (the server mentioned in resolv.conf), will only provide you with address of the 13 dns root servers. Rest of the job of fetching the A record for example.com is done by the dig tool itself. Which is evident from the output.
If you simply follow the output of the trace, you will come to know the flow of the query. The first result shows that your local DNS server provided the address of the 13 root servers to select from, which is clear by the below line.
;; Received 497 bytes from 172.16.140.34#53(172.16.140.34) in 0 ms
Now dig will select one root server from the 13, to fetch the address of the .COM TLD servers. So the root server selected will reply with the .COM TLD server addresses, which is clear by the below part in the trace result.
com. 172800 IN NS a.gtld-servers.net.
com. 172800 IN NS g.gtld-servers.net.
com. 172800 IN NS d.gtld-servers.net.
com. 172800 IN NS m.gtld-servers.net.
com. 172800 IN NS f.gtld-servers.net.
com. 172800 IN NS l.gtld-servers.net.
com. 172800 IN NS h.gtld-servers.net.
com. 172800 IN NS b.gtld-servers.net.
com. 172800 IN NS c.gtld-servers.net.
com. 172800 IN NS e.gtld-servers.net.
com. 172800 IN NS j.gtld-servers.net.
com. 172800 IN NS i.gtld-servers.net.
com. 172800 IN NS k.gtld-servers.net.
;; Received 489 bytes from 192.228.79.201#53(b.root-servers.net) in 284 ms
The above line clearly mentions that the COM server addresses are provided by b.root-servers.net or 192.228.79.20 (which is one of the 13 root server).
Now from the COM server addresses given, one of them is selected to return the name servers for the domain example.com, which is shown below.
example.com. 172800 IN NS a.iana-servers.net.
example.com. 172800 IN NS b.iana-servers.net.
;; Received 165 bytes from 192.5.6.30#53(a.gtld-servers.net) in 226 ms
The last line indicates that the COM GTLD server named a.gtld-servers.net with the ip address of 192.5.6.30 replied us with the name servers responsible for the domain example.com. Which means the two name servers mentioned in the answer a.iana-servers.net & b.iana-servers.net, are the authoritative name server for the domain name example.com.
Which means these two name server will the one, that contains answers for all records related to example.com domain. Again from those two, one of them will be selected, and will reply us with the A record for example.com, which is clear from the final part of the trace output.
example.com. 172800 IN A 192.0.43.10
example.com. 172800 IN NS b.iana-servers.net.
example.com. 172800 IN NS a.iana-servers.net.
;; Received 93 bytes from 199.43.132.53#53(a.iana-servers.net) in 100 ms
Which means example.com has got an A record of 192.0.43.10, which was given to us by the server 199.43.132.53 or a.iana-servers.net (which is responsible for the complete dns records for the domain example.com).
If you notice the trace output, dig command was only provided with the domain names, and not the ip addresses. For example, our local name server only provided the FQDN (Fully Qualified Domain name) of the 13 root servers in the initaial phase of the trace, according to the output. However in reality our local name server provides both the FQDN as well as the IP addresses related to those FQDN along with it. Using trace option with dig by default suppresses the additional part. In order to see the entire reply, you need to use the +additional option with dig as shown below.
[root@localhost ~]$ dig +trace +additional example.com ; <<>> DiG 9.3.6-P1-RedHat-9.3.6-16.P1.el5 <<>> +trace +additional example.com ;; global options: printcmd . 69362 IN NS g.root-servers.net. . 69362 IN NS i.root-servers.net. . 69362 IN NS h.root-servers.net. . 69362 IN NS c.root-servers.net. . 69362 IN NS m.root-servers.net. . 69362 IN NS l.root-servers.net. . 69362 IN NS f.root-servers.net. . 69362 IN NS d.root-servers.net. . 69362 IN NS k.root-servers.net. . 69362 IN NS a.root-servers.net. . 69362 IN NS b.root-servers.net. . 69362 IN NS e.root-servers.net. . 69362 IN NS j.root-servers.net. g.root-servers.net. 60367 IN A 192.112.36.4 i.root-servers.net. 60367 IN A 192.36.148.17i.root-servers.net. 60367 IN AAAA 2001:7fe::53 h.root-servers.net. 60367 IN A 128.63.2.53 h.root-servers.net. 60367 IN AAAA 2001:500:1::803f:235 c.root-servers.net. 60367 IN A 192.33.4.12 m.root-servers.net. 60367 IN A 202.12.27.33 m.root-servers.net. 60367 IN AAAA 2001:dc3::35 l.root-servers.net. 60367 IN A 199.7.83.42 l.root-servers.net. 60367 IN AAAA 2001:500:3::42 f.root-servers.net. 60367 IN A 192.5.5.241 f.root-servers.net. 60367 IN AAAA 2001:500:2f::f d.root-servers.net. 60367 IN A 199.7.91.13 ;; Received 509 bytes from 172.16.140.34#53(172.16.140.34) in 0 ms com. 172800 IN NS m.gtld-servers.net. com. 172800 IN NS l.gtld-servers.net. com. 172800 IN NS g.gtld-servers.net. com. 172800 IN NS k.gtld-servers.net. com. 172800 IN NS d.gtld-servers.net. com. 172800 IN NS b.gtld-servers.net. com. 172800 IN NS a.gtld-servers.net. com. 172800 IN NS i.gtld-servers.net. com. 172800 IN NS j.gtld-servers.net. com. 172800 IN NS h.gtld-servers.net. com. 172800 IN NS c.gtld-servers.net. com. 172800 IN NS e.gtld-servers.net. com. 172800 IN NS f.gtld-servers.net. a.gtld-servers.net. 172800 IN A 192.5.6.30 a.gtld-servers.net. 172800 IN AAAA 2001:503:a83e::2:30 b.gtld-servers.net. 172800 IN A 192.33.14.30 b.gtld-servers.net. 172800 IN AAAA 2001:503:231d::2:30 c.gtld-servers.net. 172800 IN A 192.26.92.30 d.gtld-servers.net. 172800 IN A 192.31.80.30 e.gtld-servers.net. 172800 IN A 192.12.94.30 f.gtld-servers.net. 172800 IN A 192.35.51.30 g.gtld-servers.net. 172800 IN A 192.42.93.30 h.gtld-servers.net. 172800 IN A 192.54.112.30 i.gtld-servers.net. 172800 IN A 192.43.172.30 j.gtld-servers.net. 172800 IN A 192.48.79.30 k.gtld-servers.net. 172800 IN A 192.52.178.30 l.gtld-servers.net. 172800 IN A 192.41.162.30 ;; Received 501 bytes from 192.36.148.17#53(i.root-servers.net) in 55 ms example.com. 172800 IN NS a.iana-servers.net. example.com. 172800 IN NS b.iana-servers.net. a.iana-servers.net. 172800 IN A 199.43.132.53 a.iana-servers.net. 172800 IN AAAA 2001:500:8c::53 b.iana-servers.net. 172800 IN A 199.43.133.53 b.iana-servers.net. 172800 IN AAAA 2001:500:8d::53 ;; Received 165 bytes from 192.41.162.30#53(l.gtld-servers.net) in 205 ms example.com. 172800 IN A 192.0.43.10 example.com. 172800 IN NS b.iana-servers.net. example.com. 172800 IN NS a.iana-servers.net. ;; Received 93 bytes from 199.43.132.53#53(a.iana-servers.net) in 97 ms
Let's now get back to our topic of zone file. Let's once again take the above example of example.com. As shown in the trace output, example.com has got two authoritative name servers, which will be having the zone file for example.com domain. Now that zone file will contain the entire details for that domain. We will see the contents of a zone file and understand the meaning of the content in some time.
Zone files are nothing but simple text files, that can be easily modified by using text editors such as VIM, EMACS etc. This file contains the complete details of all resource records for that domain. In other words it will contains the entire ip to domain mapping of the domain.During this tutorial i will be using a zone file made for BIND(Berkeley Internet Name Domain) DNS server, which is a very widely used DNS server package. Zone files are made in such a way that it can be made portable for any DNS server.
The main purpose of this tutorial is to understand the contents of a zone file, and how they play a major role in the DNS system(we will also be studying some of the widely used resource records in DNS). We will be discussing bind related configurations in a separate post, as it requires special attention.
In the above image, i have tried to depict an example configuration of DNS zone file for the domain example.com. Let's understand each and every part of that zone file separately.
Default TTL (Time To Live)
In the above shown example configuration file, there a TTL value assigned by the below method.
@TTL 1d
TTL stands for Time To Live, which mentions the time in seconds for which caching name servers can cache the data. Here the TTL value mentioned in the beginning of the file, is the bind's method of specifying the default TTL value for the domain, if not explicitly mentioned.
Let's take an example to understand TTL. I will do a simple dig against google.com, to see what's the TTL.
[root@localhost ~]$ dig google.com ;; QUESTION SECTION: ;google.com. IN A ;; ANSWER SECTION: google.com. 104 IN A 173.194.36.41 google.com. 104 IN A 173.194.36.37 google.com. 104 IN A 173.194.36.36
In the above example, the TTL value of 104 mentioned in the second column of the output is the number of seconds remaining for the TTL to expire. Please note the fact that, the above reply is given by your local name server which you have in your resolv.conf file. 104 seconds means, that after 104 seconds, your local DNS server will follow the entire procedure of fetching A record for google.com(from root to TLD and TLD to authoritative name server of Google.)
But until that TTL expires, your local DNS server will sit and serve the cached records to all the clients. So if you repeatedly do a dig for google.com, you will always get a different value in TTL field(because its in seconds and goes on reducing).
If you really want to know the TTL of any record of any domain, you either need to do a dig to the authoritative name server for that domain, or do a dig + trace for that domain. So let's find out the exact TTL value for Google.com by doing a dig against its authoritative name server(which you will get by doing a dig NS google.com or a dig + trace)
[sarath.p@localhost ~]$ dig @ns1.google.com google.com ;; QUESTION SECTION: ;google.com. IN A ;; ANSWER SECTION: google.com. 300 IN A 173.194.36.41 google.com. 300 IN A 173.194.36.39 google.com. 300 IN A 173.194.36.46 google.com. 300 IN A 173.194.36.33
So you will always get the TTL value of 300, when you do a dig by using ns1.google.com. Doing @<server> while using dig will ask dig to send the DNS query to that server, instead of your local DNS server mentioned in resolv.conf
There are two things that you need to consider about TTL value.
- A low TTL value means, that your authoritative name server will get a higher number of queries, because the TTL gets expired fast, due to which resolvers, and DNS servers will query the server more often. But yeah if you change the records too often, then its advisable to keep a low TTL value, so that the latest entry gets updated fast. So for example you have a website www.example.com with an A record (we will be discussing A records in some time)of 172.16.140.43, and you want to change the IP address to something else, then in that case if you have a higher TTL value, the resolvers and DNS server's who already have the old entry will not refetch the current data until the TTL expires. So if you change records more often its advisable to keep a low value of TTL
- Keeping a higher value TTL will result in less number of queries hitting your authoritative name server. This is because once a record is cached in a local name server, it will not refetch the value until the TTL expires, and a high value TTL means less number of query, which intern means less load on your authoritative name server.
If you remember the dig + trace we did, the reply from TLD name servers always had a higher TTL value. Which means the servers which gives you the address of authoritative name server for a domain, has a higher value TTL. The default value of that TTL most of the times is 48 hours(2 days). The below shown snippet from the dig + trace shows the TTL value given by gTLD servers.
example.com. 172800 IN NS a.iana-servers.net. example.com. 172800 IN NS b.iana-servers.net. ;; Received 165 bytes from 192.5.6.30#53(a.gtld-servers.net) in 226 ms
172800 seconds in the above shown result means 48 hours. That large value is correct, because its very less often that people change the authoritative name server IP addresses(note the fact that the above output is the data given by a.gtld-servers.net showing the name servers for the domain example.com).
SOA or Start of Authority in a Zone file
SOA is the mandatory record that must be there in all zone files. It specifies the main properties and characteristics of a domain. We will walk through each of them one by one. The default format of specifying a SOA record is shown below.
NAME TTL CLASS RR NAMESERVER EMAIL SERIALNUMBER REFRESH RETRY EXPIRY MIN
NAME: This specifies the name of the domain. As mentioned before, i am using a zone file made for bind DNS server. If you see our SOA begins with the following line
@ IN SOA ns1.example.com. admin.example.com.
@ shown in the above line is the NAME value for this SOA record. Using @ at this place will replace it with example.com as we have mentioned it in $ORIGIN. One important thing to understand here is the $ORIGIN entry, which is used to make all other entires in the zone file a FQDN. FQDN stands for Fully Qualified Domain Name, and it always ends with a dot (.).
So www.example.com is not a FQDN but www.example.com. is. The final DOT specifies the root name servers.
$ORIGIN is used in the zone file to properly make all the records a FQDN record. If you see the $ORIGIN entry, it has the final DOT at the end.
Hence in the NAME field of the SOA, we have used @ which means example.com. (its the normal behaviour of BIND dns server to replace it with $ORIGIN )
TTL: You can give different TTL values to different records, however we have already defined a default TTL value of 1 day in the beginning of the zone file. This default TTL value gets applied for all records that does not have an explicit TTL defined. So in case of our SOA record, the default TTL value of 1 day gets applied, as there is no TTL specific to SOA is defined.
CLASS: The default path used for all resource records are IN, which stands for internet(there are few other class as well which are mentioned in the RFC 2929).
RR: This specifies the resource record name. so its SOA here.
NAMESERVER: This is the primary name server for this domain/zone. Please note the fact that there must be a A record for this name server later in the same zone file that will specify the IP address of that name server. We will be discussing A records in some time.
EMAIL: This specifies the administrative contact email address for this domain. But if you see our example zone file, you will see that its admin.example.com instead of any email address. That's simiply because @ sign in zone file has some different meaning other than email address.
SERIALNUMBER: Its one of the important entries inside the SOA record in a zone file. Serial number tells the modification date of the zone file. Every time you modify the zone file, you also need to modify the serial number. Serial numbers in zone file follows a date format of yyyymmddss. Which means if you have edited your zone file on 12th September 2013, your serial number will be 2013091200. This entry of serial number is mostly used for zone transfer to confirm the last modification of the zone. We will be discussing the zone transfer stuff in a dedicated post.
REFRESH: Indicates the time after which the secondary or slave DNS server for this domain re-fetches the SOA record for this zone.
RETRY: Specifies the retry interval if the slave will take, in case of a failure.
EXPIRY: This specifies the duration after which the slave name server will stop responding to DNS queries if the connection to master server cannot be established by following retry interval.
MIN: You might have seen something like NXDOMAIN, while digging for any domain name. for example lets dig for a non existent domain name.
[sarath.p@m1-sv-xbox2 ~]$ dig xyz.google.com ; <<>> DiG 9.3.6-P1-RedHat-9.3.6-16.P1.el5 <<>> xyz.google.com ;; global options: printcmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 32299 ;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 0 ;; QUESTION SECTION: ;xyz.google.com. IN A
If you see the above dig command, i have used a domain name that does not exist. So the name server for google.com replied with the status of NXDOMAIN, which is evident from the line ;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 32299, in the above output.
NXDOMAIN means non-existent domain name. So this MIN, filed in the SOA indicates the duration for which caching name servers (like your local name server) will cache the NXDOMAIN value.
Hence our final zone file SOA record will look something like below, which was also previously shown in the image.
@ in SOA ns1.example.com. admin.example.com. ( 2013091200; serial number 12h ; refresh 15m ; retry 3w ; expiry 2h ; ttl for nxdomain )
NS record in a DNS Zone file
This record specifies the DNS server responsible for this domain. In our example zone file shown previously, we have two name servers(dns servers) responsible for the example.com domain. One is ns1.example.com and the other is ns2.example.com.
The IP address for both of them needs to be defined in the zone file as A records.
The format of defining NS record is very simple and straightforward. In reality you can also write this NS record as shown below.
example.com. IN NS ns1.example.com.
<name> <TTL> <class> <RR name> <name for example ns1.example.com.>
But if you see our example zone file we have defined NS record as shown below.
IN NS ns1.example.com
That's because other values are default.
MX records or Mail server entry in DNS
MX records define the mail servers for a domain. The format of defining mail servers or MX records are very much same as NS records.
<name> <TTL> <class> <RR name> <preference> <name for example ns1.example.com.>
Read: MX Record in DNS Tutorial
If you notice there is an additional parameter in MX record, called preference. This is a numerical number ranging from 0 to 65535. A mail server MX record with lower numerical number has the higher preference. normally people assign preferences starting from 10, then 20, then 30 and so on.
The reason behind starting from 10 is only because, you can add another mail server with much more higher priority without modifying any other record. And this method of starting from 10 is conventionally followed. You can assign any number based on your priority, without following the convention.
Hence our MX record entry of example.com zone looks something like the below.
IN MX 10 mail.example.com.
Similar to other records, not mentioning a field like ttl, name, etc will add the default value for them.
A Record or address record in DNS zone file
A record or address record is used to add IP address for a hostname in a zone. It is the highly used resource record in a zone file. Also when you dig for a domain, the default answer you get is a A record which is denoted by a capital A.
The important fact to keep in mind is the fact that, A record is used to add an IP address of IP version 4. For adding IP version 6 address a similar record type called AAAA is used.
As mentioned before, the default answer provided, while doing a dig for any domain is the A record.
[root@myvm1 ~]# dig example.com ; <<>> DiG 9.3.4-P1 <<>> example.com ;; global options: printcmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 38701 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 4 ;; QUESTION SECTION: ;example.com. IN A ;; ANSWER SECTION: example.com. 5 IN A 192.0.43.10
As discussed earlier, the default format used for adding an A record, is almost the same as other records.
NAME TTL CLASS RR IP(V4)
ns1 IN A 172.16.140.41
mail IN A 172.16.140.42
www IN A 172.16.140.44
The three example's shown above shows the method to add A record to a zone file. The $ORIGIN value gets appended with the hostname specified in the beginning of the record.
So for example, the A record added for mail host means that mail.example.com. has an IP address of 172.16.140.42.
Like other records, as we have not specified the TTL, the default TTL value gets applied to them. But it will be better if you override the default TTL value for A record, by making it 300 seconds, as this is the most commonly modified resource record in DNS.
Making 300 seconds means you can change the IP address of a particular host, and within 5 minutes, the new IP address will get reflected across the internet(as the caching name servers can only cache the data till 300 seconds).
Also note the fact that, although we have specified the authoritative name server for this domain during the beginning of the zone file, the A record for the name server must be added.
CNAME Record in DNS Zone file
We have a dedicated post that explains the working of DNS cname record in detail. I will recommend to read that post for understanding CNAME records.
Read: What is DNS CNAME record?
Note: We will be discussing the remaining records as well as some advanced DNS functionalities once we complete BIND configuration related post.
Also note the fact that example.com is a reserved domain name by IANA for illustration purposes. That's the reason example.com returns a valid IP adress and trace works flawlessly.
Comments
DNS query
Hi Sarath,
Lets say that I have delegated nameservers and added them (private nameservers) in the customers zone file and listed them with my registrar as well.
My Question is:
With most client queries are recursive and when the list of Authoritative nameservers are listed, will the queried Domain Name Server pick the closest/best NS to the client or will it still go to the primary nameserver(which could be far away from the client) for an IP address.
I am assuming that it automatically picks the closet one, but I could be wrong.
Thanks,
Kiran - slashroot fanboy :)
Great
I would say this is really informative with practical examples.
Keep posting guys, for sure I will be one of regular visitor on your site.
Cheers !
Very informative
Very much informative and well explained.
Very much informative
Thanks a lot..details explanation of DNS..
Add new comment