Cross-Platform Usage of Nslookup

Problem

I recently discovered a problem with the domain name of a website I manage. Attempting to resolve a DNS record which had been created a few days earlier was resulting in intermittent failures. This post details the process I used to diagnose the problem with nslookup and how I turned that manual process into a cross-platform (GNU/Linux and Windows) compatible script.

Diagnosis

To diagnose the problem I used the venerable command line tool nslookup. My plan was to query each of the domain’s authoritative name servers for the record that was intermittently failing.

I needed to obtain the domain’s authoritative name server(s). I don’t think this was strictly necessary but I felt that the best source from which to obtain this information was the domain’s primary name server. So I began by querying the domain for its SOA (Start of Authority) record, from which I was able to ascertain the primary name server. I then proceeded to query the primary name server for the domain’s authoritative name server(s), the result of which showed that this domain had four.

Next I queried each authoritative name server for the problematic record. In doing so I discovered that one of the domain’s four authoritative name servers was failing to return an answer when queried, which explained the intermittent nature of the problem.

As for actually fixing the underlying problem, a third party managed the domain’s DNS, so I sent them the evidence I’d collected and they resolved the problem with the errant authoritative name server.

The example below is fictitious, don’t try to run it yourself. It simply illustrates the problem I’ve described; one of the authoritative name servers (c.iana-servers.net) for the domain example.com fails to return an answer when queried for the A record dev.example.com (see lines 42 - 46):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
C:\> nslookup -querytype=soa example.com
Server: 192.168.10.1 
Address:  90.207.238.97

Non-authoritative answer:
example.com
        primary name server = sns.dns.icann.org
        responsible mail addr = noc.dns.icann.org
        serial  = 2019041034
        refresh = 7200 (2 hours)
        retry   = 3600 (1 hour)
        expire  = 1209600 (14 days)
        default TTL = 3600 (1 hour)

C:\> nslookup -querytype=ns example.com sns.dns.icann.org
Server:  gsi1.dns.icann.org
Address:  192.0.32.162

example.com     nameserver = a.iana-servers.net
example.com     nameserver = b.iana-servers.net
example.com     nameserver = c.iana-servers.net
example.com     nameserver = d.iana-servers.net
a.iana-servers.net       internet address = 199.43.135.53
b.iana-servers.net       internet address = 199.43.133.53
c.iana-servers.net       internet address = 199.43.134.53
d.iana-servers.net       internet address = 199.43.132.53

PS C:\> nslookup -querytype=a dev.example.com a.iana-servers.net
Server:  a.iana-servers.net
Address:  199.43.135.53

Name:    www.example.com
Address:  93.184.216.34

C:\> nslookup -querytype=a dev.example.com b.iana-servers.net
Server:  b.iana-servers.net
Address:  199.43.133.53

Name:    www.example.com
Address:  93.184.216.34

PS C:\> nslookup -querytype=a dev.example.com c.iana-servers.net
Server:  c.iana-servers.net
Address:  199.43.134.53

*** c.iana-servers.net can't find dev.example.com: Non-existent domain

PS C:\> nslookup -querytype=a dev.example.com d.iana-servers.net
Server:  c.iana-servers.net
Address:  199.43.132.53

Name:    www.example.com
Address:  93.184.216.34

Script

In case I ran into this problem again in future, I wanted to replace the manual process of typing nslookup commands with a script. I also wanted the script to be usable on both GNU/Linux and Windows.

I decided to use PowerShell Core as the scripting language since it’s available on both GNU/Linux and Windows. I considered replacing nslookup with an equivalent PowerShell cmdlet (or .Net class) but on investigation I found that (at the time of writing) PowerShell Core lacks a native cross-platform means of performing DNS client operations.

In the end I wrote a PowerShell function which calls nslookup. But before I began writing any code I had to do some research on nslookup in order to determine its suitability for cross-platform usage. If you’d like to know more about that process then read on to the next section of this post which covers that investigation in detail.

The script along with instructions can be found here: Get-RecordFromAuthoritativeNameServers

Nslookup - Further Research

Background

The nslookup utility is part of the BIND DNS software suite. The acronym BIND stands for Berkeley Internet Name Domain, a name which derives from the project’s origins at the University of California, Berkeley (UCB) where it was first developed in 1986. The current maintainer of BIND is the Internet Systems Consortium.

The Reports of My Death are Greatly Exaggerated

I found a number of articles and forum posts dating from 2003 to 2017 claiming that nslookup had been deprecated. The nslookup article on Wikipedia clarified the situation: “During the development of BIND9 it was marked as deprecated but this decision was later reversed”. The article cites a mailing list post for the release of BIND 9.3.0 in which there is a change log which includes the following:

1700.   [func]      nslookup is no longer to be treated as deprecated.
                    Remove "deprecated" warning message.  Add man page.

This can also be seen in the CHANGES file of the BIND9 repository on Gitlab.

Availability on GNU/Linux and Windows

There are several popular alternatives to nslookup such as dig and host, however since my objective was to write a cross-platform script I wanted to use something that was likely to be present on a default installation of a GNU/Linux distro and Windows, hence why I favoured nslookup.

It’s common to find nslookup on many GNU/Linux distros out-of-the-box, such as on Ubuntu Server 19.07 where it is included in the bind9-host package, see the installation media manifest. If nslookup is not present by default on a GNU/Linux distro then it should simply be a matter of installing it using the distro’s package manager.

As for Windows, BIND (the software suite which includes nslookup) can be downloaded from the Internet Systems Consortium’s website. Furthermore, since the release of Windows 2000, Microsoft has shipped nslookup.exe with its Windows desktop and server operating systems. Although I’ve found no official acknowledgement from Microsoft, it appears as though this is a fork of BIND nslookup, the evidence for which is as follows…

The interactive mode help of nslookup.exe is largely the same as that found in older releases of BIND nslookup. For example, compare the first five lines of interactive help text produced by nslookup.exe on Windows 10 (1809) against those produced by nslookup in BIND 4.8.1 (see named/tools/nslookup/nslookup.help) which was released in 1988 and you’ll find they are identical:

Commands: 	(identifiers are shown in uppercase, [] means optional)
NAME		- print info about the host/domain NAME using default server
NAME1 NAME2	- as above, but use NAME2 as server
help or ?	- print help information
set OPTION	- set an option

Another clue is that the nslookup.exe interactive help text on Windows 10 (1809) includes a reference to pg, a command which has never shipped with Windows:

view FILE           - sort an 'ls' output file and view it with pg

pg is a terminal pager program, it is described on Wikipedia as a “…historical utility on BSD UNIX systems.”. BSD was a Unix operating system, the initialism stands for Berkeley Software Distribution, which as you’ve probably guessed derives from its place of development, the University of California, Berkeley, the same place that first produced nslookup. So it looks as though Microsoft forked a copy of BIND nslookup which was originally intended for use on BSD Unix.

Finally, I had read on slashdot and ars technica that it’s possible to see the original Berkeley copyright notices in nslookup.exe, so naturally I wanted to try that out for myself. On Windows 10 (1809), I downloaded Strings, a Microsoft Sysinternals tool for extracting text strings embedded within binary files. I ran the following command strings.exe c:\Windows\System32\nslookup.exe and proceeded to examine the output for any references to Berkeley… there were none to be found. I ran the same command on Windows Server 2016, again there were no references to Berkeley. I decided to check some older versions of Windows, I didn’t have any Windows Server 2000 media to hand but I did have access to Windows XP, Windows Server 2003, Windows Server 2003 R2, Windows Server 2008, Windows Server 2008 R2, Windows Server 2012 and Windows Server 2012 R2. All of these older operating systems except for Windows Server 2012 R2 contained references to Berkeley in their respective versions of nslookup.exe:

Windows XP, Windows Server 2003 and Windows Server 2003 R2:

@(#) Copyright (c) 1985,1989 Regents of the University of California.
@(#)nslookup.c  5.39 (Berkeley) 6/24/90
@(#)commands.l  5.13 (Berkeley) 7/24/90
@(#)debug.c     5.22 (Berkeley) 6/29/90
@(#)list.c      5.20 (Berkeley) 6/1/90
@(#)subr.c      5.22 (Berkeley) 8/3/90
@(#)skip.c
@(#)getinfo.c   5.22 (Berkeley) 6/1/90
@(#)send.c      5.17 (Berkeley) 6/29/90

Windows Server 2008, Windows Server 2008 R2 and Windows Server 2012:

@(#)send.c      5.17 (Berkeley) 6/29/90
@(#)getinfo.c   5.22 (Berkeley) 6/1/90
@(#)skip.c      5.9 (Berkeley) 8/3/90
@(#)subr.c      5.22 (Berkeley) 8/3/90
@(#)list.c      5.20 (Berkeley) 6/1/90
@(#)debug.c     5.22 (Berkeley) 6/29/90
@(#)commands.l  5.13 (Berkeley) 7/24/90
@(#)nslookup.c  5.39 (Berkeley) 6/24/90
@(#) Copyright (c) 1985,1989 Regents of the University of California.

Comparison of BIND nslookup and Microsoft’s nslookup Fork

As previously mentioned, the evidence suggests that nslookup.exe on Windows is a fork of BIND nslookup. Since Windows is a proprietary operating system, we cannot examine the source code, so it’s difficult to tell how disparate this fork is from BIND’s current version of nslookup. It may well be that this fork has had little done to it since it’s inception in Windows 2000.

So if you intend to write a cross-platform script capable of targeting Microsoft’s fork of nslookup just bear in mind that it may not exhibit exactly the same behaviour as a recent official release of BIND nslookup.

For my purposes the only substantial difference I encountered was that when the SOA record of a domain is queried, Microsoft’s fork refers to the primary name server as primary name server whereas recent BIND releases refer to it as origin.

Comments

Leaving comments has been disabled for this post.

Copyright © 2018 - 2022 thecliguy.co.uk
For details, see Licences and Copyright