Hack and Defend
I’m excited to announce that my new book Linux Server Security: Hack and Defend is now available from Amazon in the US and all good book shops.
Practical Linux Topics
Build, maintain and secure your servers using my latest book Practical Linux Topics
Dig Deeper Into Your DNS
There’s little debate that one of the absolutely fundamental services critical to the functionality of the Internet is the Domain Name System (DNS). Akin to SMTP (the Simple Mail Transfer Protocol), which is the grounding for all things e-mail, and NTP, the Network Time Protocol which keeps the Internet ticking, DNS has unquestionably played a key part in both the Internet’s inception and somewhat surprisingly its continued growth today; a testament to its architects.
During the course of administrating online systems effectively Sysadmins need to run both Name Servers, which include the likes of “BIND” and “djbdns” (also called “tinydns”) to answer the questions asked about the Domain Names for which they’re responsible and they also use tools to query other Domain Name settings hosted remotely.
And, it’s important to note that there are several DNS lookup tools available in Linux, some bundled with Operating Systems, in one form or another, and others installed optionally as packages on top. If you’re like me you tend to get used to one package in particular which you then either explore thoroughly or use to a smaller degree alongside other packages. My long-term, favourite DNS lookup tool has been the “host” command however there have been occasions when it just didn’t quite cut the mustard and give me the level of detail required to complete a task.
Instead, in these situations, my tool of choice has been the “dig” command which is a successor to the “nslookup” and “host” commands and a tool bundled with the BIND Name Server. It is probably worth pointing out that there is a good chance that the “host” command did in fact have some have of the features which I needed but there weren’t enough examples readily available on the Internet when I looked or possibly the examples weren’t as intuitively constructed which meant they were easily forgotten.
In this article I will briefly explore the powerful “dig” utility. For anyone that hasn’t used in the command in the past hopefully this insight into dig will give a useful overview of what its features can be used for. And, for those that have utilised dig in the past hopefully this article will be a reminder of its versatility and extensive functionality.
Apparently dig stands for “Domain Information Groper”. Who am I to suggest that its naming might have involved a backronym?!
To all intents and purposes the functionality of DNS is simply the act of converting an IP Address to a Domain Name and the reverse, converting a Domain Name to an IP Address. I use the two words “Domain Name” advisedly and more accurately I really mean a hostname (such as “mail.chrisbinnie.tld” or “www.chrisbinnie.tld”).
Wherefore Art Thou?
Incidentally if you can’t get a response from typing "dig" on your command line then you might not be lucky enough to have it installed. On Debian and Ubuntu you can install the “dnsutils” package by typing:
# apt-get install dnsutils
On Redhat and CentOS systems you can install it with the following command:
# yum install bind-tools
For future reference, if you are unsure which package an already installed file belongs to on Redhat-based systems then you might want to try this command:
# rpm – qf /usr/bin/dig
On Debian-based systems the same can hopefully be accomplished using the faithful "dpkg" package manager as follows:
# dpkg –search /usr/bin/dig
However without the packages being installed already these commands may do the trick should you need to look for a file. Be warned that, depending on software versions, your mileage may indeed vary:
# yum whatprovides ‘*bin/dig’
# apt-cache search dig dns
Let’s take a moment now to explore the basics of dig using a few of the more straightforward command line options available.
It’s probably worth saying at this stage, that on most Unix-like the lookup order of which Name Servers to query are found inside the file “/etc/resolv.conf“ which might have contents similar to this:
The other options instead of just using “nameserver” within that file are using short names relative to the local domain for that server. Therefore another option for “/etc/resolv.conf” might simply be:
Using that “domain” option should we simply look up “mail”, without the full Domain Name appended to it, then our query would automatically resolve to “mail.chrisbinnie.tld”. Or, in other words this is the system’s local Domain Name.
And, equally another option is the “search” parameter which you can also use for resolving shortened hostnames. If for example you use two Domain Names frequently then adding the following entries will check each in the same way as the “domain” option allows. An example might be:
search chrisbinnie.tld binnie-linux.tld
Now that we can see how the Operating System performs its DNS lookups let’s get on to to looking at some of dig’s features as promised.
The host command typically responds to time-honoured syntax as follows to look up MX records for a Domain Name:
# host -t mx chrisbinnie.tld
The DNS tool “nslookup” however can drop you down into what might be described as its own command line interface having executed its name from your own command line, although it does let you enter commands directly into the command line too.
You might use “nslookup” command directly as the following example will show. This functionality can also be achieved with the same syntax using the “host” command. We can directly query a specific Name Server for its response (instead of relying on other DNS lookups to get you to that server in the first place) to get a definitive answer with a command such as:
# nslookup mail.chrisbinnie.tld 18.104.22.168
And, conversely you might perform a Reverse DNS lookup using the following in order to convert an IP Address to a Domain Name:
# nslookup 192.168.0.1 22.214.171.124
In both cases “126.96.36.199” is the IP Address of a popular DNS Resolver which will ask other Name Servers for the answer should it not be armed with it.
I mention the syntax of other DNS tools because the mighty dig utility, in its wisdom, does things slightly differently. A typical query might look something like this:
# dig @188.8.131.52 chrisbinnie.tld mx
Appended to the “@” sign is the name of the server which we wish to directly query. Then the “chrisbinnie.tld” element is the resource that we are asking that Name Server about. And, finally the last entry on the command line is the type of query which might be “any”, “mx” or “a” records for example, amongst others.
Vehicle Is Reversing
If we use the easy-to-remember “-x” switch then it’s possible to always force a Reverse DNS lookup where you convert an IP Address to a hostname. This command shows an intentionally abbreviated output for clarity:
# dig -x 184.108.40.206
220.127.116.11.in-addr.arpa. 21600 IN PTR www.ripe.net.
Many of the name servers on the Internet today use UDP however on occasion, especially for larger packet sizes (for IPv6 or DNSSec for example), TCP responses are also made available on some Name Servers however.
If my memory serves then one of the first times I ever used the dig utility was to query a TCP Name Server. The format might look something like this if you needed to use such a command, again querying a popular DNS Resolver “18.104.22.168”:
# dig +tcp @22.214.171.124 chrisbinnie-linux.tld
Get The Syntax Right
One of the things I like about the dig utility, even if the syntax is a little different to other DNS lookup packages, is there’s a very simple “+” or “no” structure to the options which it offers.
For example, if you wanted to perform UDP lookups only, then you would simply add “no” to the beginning of the TCP parameter, as follows:
# dig +notcp @126.96.36.199 chrisbinnie.tld
It’s very simple I’m sure that you’ll agree.
There are significant number of features available with the dig utility. Let’s have a look at the displaying of Time To Live (TTL) settings on a DNS record. Or in other words the countdown until a record should be refreshed to prevent it going stale. This command can be entered as "+[no]ttlid" options. An example of this option in use might be:
# dig +ttlid chrisbinnie.tld
The standard output from the dig utility is very verbose and certainly in comparison to “host” I find it a little unwieldy. We will start off by looking at the "short" output version of the dig utility. The output is shown below as an example IP Address "188.8.131.52".
# dig chrisbinnie.tld +nocomment +nostats +short
Without the "+short" addition we see the following:
# dig chrisbinnie.tld +nocomment +nostats
; <<>> DiG 9.8.1-P1 <<>> chrisbinnie.tld +nocomment +nostats
;; global options: +cmd
;chrisbinnie.tld. IN A
chrisbinnie.tld. 37765 IN A 184.108.40.206
We can now do exactly the same but include the default comments and statistics parameters. You can see the default output offers significantly more detail:
# dig chrisbinnie.tld
; <<>> DiG 9.8.1-P1 <<>> chrisbinnie.tld
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 58982
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;chrisbinnie.tld. IN A
;; ANSWER SECTION:
chrisbinnie.tld. 35636 IN A 220.127.116.11
;; Query time: 15 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Sat Nov 8 20:22:27 2014
;; MSG SIZE rcvd: 44
Hopefully the majority of the answer’s output is self explanatory. The question and answer sections are really very close to a DNS query-and-response’s model. Other sections which are important to note are the server which was used (under “SERVER” we see “localhost” because we didn’t query a Name Server directly with the “@server” parameter). There is mention of the standard DNS port following that output under “#53”. Also the “Query time” section can offer insight into server load issues and connectivity bottlenecks.
Fill Your Boots
One time-saving feature which would undoubtedly help if used within scripts is that of being able to ingest a potentially lengthy list of hostnames to query from a text file. We use the “-f” switch to activate the reading of a file.
# dig -f file_full_of_hostnames
You can simply list a new hostname to query on each line of a file in a list and then run a command over it as above.
Respect My Authority
If, for example, you wanted to check all of the Name Servers responsible, authoritatively, for a Domain Name then you could swiftly achieve this with a command as follows:
# dig ultradns.com NS +noall +answer
ultradns.com. 236 IN NS pdns196.ultradns.org.
ultradns.com. 236 IN NS pdns196.ultradns.com.
ultradns.com. 236 IN NS pdns196.ultradns.info.
ultradns.com. 236 IN NS pdns196.ultradns.net.
ultradns.com. 236 IN NS pdns196.ultradns.biz.
ultradns.com. 236 IN NS pdns196.ultradns.co.uk.
For simplicity I have pruned the output a little but you can see that the Domain Name which we queried has a healthy geographical coverage when it comes to its authoritative Name Servers; it’s by design, to provide optimal levels of resilience.
The Future is a No. 6
We couldn’t possibly expect IPv6 to be ignored by the superb dig utility. Even though the excellent DNS tool heralds from a time well before IPv6 was popularly used. Being part of one of the most widely used DNS servers on the planet, BIND, however we can safely say that IPv6 functionality will be present in the dig utility, due to its provenance.
This example of querying IPv6 is relatively intuitive. Let’s check an “AAAA” record:
# dig google.com AAAA +short
Without A Trace
My favourite dig utility feature is definitely the “trace” option. For those unfamiliar with the process, let’s slowly run through it.
When a DNS query is made the “chain” of events (for want of a better description) starts with the Name Server initiating the lookup speaking to one of the world’s “Root” Name Servers. The Root Server knows, via a Name Server which acts as an authority for a top-level country code, which remote Name Server is responsible for responding to queries about that particular Domain Name (if that Domain Name exists).
Figure One: A DNS lookup for “sample.org”
Figure One shows us the delegation from the Root Servers down into the key servers responsible for the delegation of the Top Level Domain (TLD) “.org”. Underneath those authoratative “afilias-nst” servers we see (at the foot of the output) the two Name Servers responsible for answering queries for the Domain Name “sample.org”. In this case “ns1.mailbank.com” and “ns2.mailbank.com”. The last salient link in the chain is:
sample.org. 300 IN A 18.104.22.168
This is the “A Record” result for the non “www” record for “sample.org” (in other words if you just typed “sample.org” into a Web Browser without a “www” this is the IP Address you would visit). This is ultimately the answer which we’ve been waiting for and you might be surprised how many servers we needed to ask in order to to receive it.
Now that we’ve got to grips with DNS delegation and traversed the lengthy chain required for a ".org" namespace lookup let’s compare that output with a ".co.uk" DNS lookup. Figure Two shouldn’t cause too many headaches to decipher.
Figure Two: Shows the “sample.co.uk” delegation during a DNS lookup
The ten “.nic.uk” Name Servers (geographically disparate for resilience which you could confirm categorically with a “WHOIS” lookup on each of their IP Addresses) shows the .UK namespace is well protected from issues. For reference “Network Information Centre” or NIC is common parlance throughout the Name Server world and if you’re ever unsure which authoritative body is responsible for a country’s Domain Name space then trying something like http://www.nic.uk, in the case of the United Kingdom, might save the day.
Compare that with a much more concise output using the "+short" option as follows. In Figure Three we can see that the NIC’s inclusion is not displayed but instead just the other salient parts of the chain. The command that we used was:
# dig +short +trace @22.214.171.124 sample.co.uk
Figure Three: Shows Root Server delegation in "short".
The timing of DNS lookups are clearly of paramount importance. Your boss may have invested in the latest dynamic infrastructure for your killer application but if you are delaying each connection to your application by two seconds because of poorly configured DNS then your users will be far from best-pleased.
If you see very slow response times anywhere in the chain (you can see the lookup completion results at the foot of each section in Figure One and Figure Two) then my advice would be to turn to one of the many online tools which assists in measuring performance. They can help isolate and then identify the bottlenecks and additionally suggest improvements.
Hold on for a second. What if you needed to use the dig utility in a script and you foresaw connectivity issues or queries that wouldn’t have valid answers? You can set a timeout function as follows deviating from the default five seconds using the "+time=" command switch:
# dig +time=2 chrisbinnie.tld mx
You can now be assured of running through multiple lookups, with or without lookup failures, in two second increments.
Start Of Authority
Those familiar with zone files will understand this next section. Imagine, and this almost certainly harks from the Internet of old, that you need to figure out who to contact about a Domain Name issue or discover certain parameters which help to control how a Domain Name runs its synchronisation of data between its Name Servers. You can discover much of this (not always entirely accurately because there can be other factors at play) by querying the Start Of Authority (SOA) of a Domain Name.
Here is a “short” example which I’ll explain in a second with its output following:
# dig +short @126.96.36.199 chrisbinnie.tld soa
toma550561.mars.orderbox-dns.com. transfer.active-domain.com. 2014102717 7200 7200 172800 38400
Let’s compare that slightly unusual numerical output to a default display of a SOA query using the dig utility in Figure Four.
To achieve a reasonable amount of detail but in a sensible way the command line I used was:
# dig +multiline @188.8.131.52 chrisbinnie.tld SOA
The “+multiline” option tries its best to offer a formatted layout coupled with helpful comments. In the case of the SOA I’m sure that you’ll agree it makes sense of an otherwise difficult to read output under the “AUTHORITY SECTION”.
Figure Four: Shows the use of the “multiline” parameter in the dig utility.
I, for one, think that’s much less cryptic. The “serial” number in an SOA is a simple measure of when a change to the Domain Name was last made. Request For Comments (RFCs) which are technical specifications for the Internet most likely recommend the serial takes the form of a date format shown backwards which we can see in our example.
Apparently (but this may not be the case) that RFC 1035 holds fort for SOA recommendations which can be found here https://www.ietf.org/rfc/rfc1035.txt if you would like some enlightening, bedtime reading.
Other Name Servers simple increment a long number such as 1000003 each time there’s a change which admittedly doesn’t help with when an update was made but at least lets you know which version of a zone file you are looking at. This is important because when sharing updates between many Name Servers it’s imperative that they answer with the most up-to-date version of the DNS and don’t respond with stale, potentially damaging information.
In case you’re wondering the reason why we’re seeing the “root-servers.net” and “verisign-grs.com” Domain Names being mentioned is because the Domain Name “chrisbinnie.tld” doesn’t exist (we’re just using it as an example) so Figure Four is showing the SOA for “a.root-servers.net” instead which is the first link in the chain for our non-existent DNS lookup.
The “refresh” field looks at how soon secondary Name Servers are to come back for new information (secondaries and tertiaries are Name Servers serving the same information for resilience in addition to the primary). Usually this value sits at 24 hours but it’s shorter for a Root Server. The “retry” is how quickly to try a “refresh” that failed again. On a Name Server which isn’t a Root Server you would expect this to be 7200 seconds (two hours).
The “expire” field lets secondary Name Servers know when the answers which it has been serving should be considered stale (or, in other words, how long the retrieved information remains valid).
Finally the “minimum” field shows secondaries (also called “slaves”) how long the information received should be cached before checking again. This has been called the setting with the greatest importance thanks to the fact that, with frequent changes to your DNS you need to keep secondaries up-to-date with frequent data updates.
The tricky balance however is that if you don’t make frequent DNS updates keeping this entry set at a matter of days is best to keep your DNS server load down. The rule of thumb is that to speed up a visitor’s connection time you really don’t want to enforce a DNS lookup unless you’re making frequent changes. On today’s internet this is less critical because Name Server traffic is relatively cheap thanks to its tiny packet size and the efficiency of modern Name Servers. It’s still a design variable to consider however.
When You’re Ready
And, at the risk of sounding melodramatic, when it comes to DNS, every millisecond really does count.
Another quick note about Figure Four would be that “a.root-servers.net” is the authorative name of the Name Server for that Domain Name’s zone. And, separately, the “nstld.verisign-grs.com” entry is the contact method of the Domain Name Administrator which I mentioned earlier. Although it’s a strange format if you haven’t seen it before, in order to avoid the use of the “@” symbol I assume, this field is actually translated as “ firstname.lastname@example.org ” into a functioning e-mail address.
Finally the “1799” at the start of that line is the Time To Live – how many seconds (thirty minutes in this case, minus a second) client software which connects should hold onto the retrieved data before asking for it again, in the event that it’s changed in the meantime.
We’re All Secure, Sir
Many of you will have come across DNSSec in the past. It’s not an area that I have explored in any great detail yet I have to admit but as you would expect the excellent dig utility takes the securing of DNS in its stride with the following option, where I request an “A” record and any associated DNSSec records with it:
# dig @184.108.40.206 chrisbinnie.tld A +dnssec +multiline
We can see the inclusion of DNSSec records in Figure Five. For clarity, we are purposely interrogating a non-existent Domain Name so you are seeing the response from the a Root Server (a.root-servers.net) again.
Figure Five: Shows setting dig to request that DNSSec records are also sent with the query’s answer.
To facilitate those with a compulsive, painstaking need to always make certain configuration changes with the dig utility there’s a config file option which reads from within a user’s home directory, named as so:
# cat ~/.digrc
+nocomments +recurse +multiline +nostats +time=1 +retry=5
As you can see my “.digrc” file is simple and to the point but keeps the output straightforward. It’s worth mentioning that the standard “A Record” is the default lookup unless another type of record is specified such as “MX” etc. That might affect how much information you usually want from your output, and thus how you set up your “.digrc” file, should you be looking up less popular record types more frequently.
It would be remiss not to mention at this stage that I have intentionally, to keep things simple for newcomers to the dreaded DNS realm, so far not mentioned the fact that each and every (okay, barring one or two exceptions where it simply wouldn’t make sense) of the powerful dig utility’s command line options can be negated with a prepended “no”.
A simple example which I will leave you to apply to your heart’s content might be as follows:
# dig chrisbinnie.tld +notrace
I’m sure you get the gist and that any further explanation would likely be futile. Try any of the other options mentioned if you’re unsure with a “no” in front.
Eggs, Bean, Spam
With the viral outbreak of spam during the latter years of the Internet clearly it’s critical that the largely successful attempt by the community to suppress it within DNS can be integrated into the dig utility.
Step forward TXT record checking. We can either point at a "@server" to query directly or you can use something like this in the same format as before:
# dig chrisbinnie.tld txt
If you look closely at the ANSWER section the IP Addresses which SPF (Sender Policy Framework) pays attention to should be fairly obvious. In brief this shows which IP Addresses are authorised to send e-mail on behalf of a Domain Name amongst other settings. Another important parameter is how strictly to enforce such settings before bouncing or blackholing an e-mail as Spam.
Suit You, Sir!
Following on from the truly accommodating perspective with which the dig utility was written there is also a couple of useful options which are not in fact related but have caught my eye in the past.
Firstly the try-hard dig utility offers us the ability to look past any malformed or corrupted responses received from Name Servers with the following option:
# dig @220.127.116.11 chrisbinnie.tld A +besteffort
In other words display some corruption if it exists, even if the output is a little nonsensical, in the hope that some useful information might be gleaned. You might see why this could be very useful if I mention that the dig utility even pays attention to non-ASCII based Domain Names.
Referred to as “IDN Support” which the manual reports is “Internationalized Domain Name Support” the mighty DNS tool, dig, can covertly change its character set before receiving an answer or sending a question to an international Name Server. On today’s Internet this is of significant value and will likely only become more useful in the future as international languages meld further, thanks to the pervasive uptake of the Web globally.
Actually, It’s A Feature
One concluding note which I enjoyed reading from the June 30th, 2000 version of dig’s man pages was at the foot of the information under the “BUGS” section where there is a curious entry. It might be read differently on a number of levels but expresses simple sentiments if read literally.
The BUGS section of the manual is usually a way of briefing declaring known issues. In dig’s case however the line “There are probably too many query options.” is all that exists.
I’m afraid that on the surface I would have to agree but I suspect that, at one stage or another, each one of those DNS options have been very useful to someone, somewhere. I mention this because it’s not always immediately obvious how far to delve into DNS, even when faced with relatively complex scenarios such as using Name Servers for failing-over between Web Servers. You can be assured however that whatever you need from a DNS query, the ever-faithful dig utility is almost definitely going to provide it and in varying levels of detail, to suit your preference of output.
We have barely scratched the surface of the dig utility’s feature list or what and how DNS actually works. If you are new to working as a Sysadmin there are likely to be many opportunities for you to learn DNS and evolve your knowledge by using it over time.
My hope in writing this article was to give you the confidence required to always turn to the dig utility if you ever need to query DNS in detail. And, having written this I have come to realise that “dig www.domainname.tld ” is actually even shorter than using the “host” command alternative. You never know, maybe my daily DNS habits have been changed forever as a result and I will turn to the dutiful dig over the “host” command from now on.