In short? 99.8% of the time, they are these:
ns1.coza.net.za. IN A 66.135.62.20 ns.coza.net.za. IN A 206.223.136.200 ns4.iafrica.com. IN A 196.7.142.131 ns0.is.co.za. IN A 196.4.160.17 ns0.neotel.co.za. IN A 41.160.0.4 coza1.dnsnode.net. IN A 194.146.106.74
And the remaining 0.2% of the time? Let’s ask the root servers – what are the NS records for co.za:
# dig @a.root-servers.net ns co.za ;; AUTHORITY SECTION: za. 172800 IN NS za1.dnsnode.net. za. 172800 IN NS nsza.is.co.za. za. 172800 IN NS za-ns.anycast.pch.net. za. 172800 IN NS sns-pb.isc.org. za. 172800 IN NS disa.tenet.ac.za. ;; ADDITIONAL SECTION: za1.dnsnode.net. 172800 IN A 194.146.106.78 nsza.is.co.za. 172800 IN A 196.4.160.27 za-ns.anycast.pch.net. 172800 IN A 204.61.216.55 sns-pb.isc.org. 172800 IN A 192.5.4.1 disa.tenet.ac.za. 172800 IN A 196.21.79.50
Okay, that gets us za. Let’s ask one of them:
# dig @194.146.106.78 ns co.za ;; ANSWER SECTION: co.za. 3600 IN NS ns0.is.co.za. co.za. 3600 IN NS ns1.coza.net.za. co.za. 3600 IN NS ns4.iafrica.com. co.za. 3600 IN NS ns0.neotel.co.za. co.za. 3600 IN NS ns.coza.net.za. co.za. 3600 IN NS coza1.dnsnode.net.
Cool – we have names, but we don’t have IP addresses yet. So let’s go and find out what the IP address of ns.coza.net.za is. We already know the NS servers for .za but let’s pretend we don’t:
dig @a.root-servers.net ns.coza.net.za a za. 172800 IN NS za1.dnsnode.net. za. 172800 IN NS disa.tenet.ac.za. za. 172800 IN NS nsza.is.co.za. za. 172800 IN NS za-ns.anycast.pch.net. za. 172800 IN NS sns-pb.isc.org. ;; ADDITIONAL SECTION: za1.dnsnode.net. 172800 IN A 194.146.106.78 disa.tenet.ac.za. 172800 IN A 196.21.79.50 nsza.is.co.za. 172800 IN A 196.4.160.27 za-ns.anycast.pch.net. 172800 IN A 204.61.216.55 sns-pb.isc.org. 172800 IN A 192.5.4.1
They say to ask the .net.za servers, and provide glue. Cool:
# dig @196.4.160.27 a ns.coza.net.za ;; AUTHORITY SECTION: net.za. 86400 IN NS disa.tenet.ac.za. net.za. 86400 IN NS ns0.is.co.za. net.za. 86400 IN NS za-ns.anycast.pch.net. ;; ADDITIONAL SECTION: ns0.is.co.za. 86400 IN A 196.4.160.17 disa.tenet.ac.za. 86400 IN A 196.21.79.50
Let’s choose one of those that we happen to have glue for (we don’t want to be here all day):
# dig @196.4.160.17 ns.coza.net.za ;; AUTHORITY SECTION: coza.net.za. 86400 IN NS beth.coza.net.za. coza.net.za. 86400 IN NS secdns1.posix.co.za. coza.net.za. 86400 IN NS ns1.coza.net.za. ;; ADDITIONAL SECTION: ns1.coza.net.za. 86400 IN A 66.135.62.20 beth.coza.net.za. 86400 IN A 206.223.136.193 beth.coza.net.za. 86400 IN AAAA 2001:43f8:30::193
Let’s ask “secdns1.posix.co.za” – oh wait, we don’t have the NS for co.za yet and this is what we are trying to find out, so we’re sunk. This is a DNS loop.
What is the probability of this error? Well, for a single query, the probability is 0.2 % – 1 in 500 or so. A simple way to understand this is that 500 international users connect to your .co.za web site, then 499 will find it, and 1 will not.
# dnstraverse -t NS co.za Using a.root-servers.net (198.41.0.4) as initial root Running query co.za type NS 1 a.root-servers.net (198.41.0.4) 1.1 za1.dnsnode.net (194.146.106.78) 1.2 nsza.is.co.za (196.4.160.27) 1.2.1 ns0.is.co.za (196.4.160.17) 1.2.2 ns1.coza.net.za -- resolving 1.2.2 ns1.coza.net.za (66.135.62.20,Loop encountered resolving ns.coza.net.za) 1.2.3 ns4.iafrica.com -- resolving 1.2.3 ns4.iafrica.com (196.7.142.131) 1.2.4 ns0.neotel.co.za (41.160.0.4) 1.2.5 coza1.dnsnode.net -- resolving 1.2.5 coza1.dnsnode.net (194.146.106.74) 1.2.6 ns.coza.net.za -- resolving 1.2.6 ns.coza.net.za (206.223.136.200,Loop encountered resolving secdns1.posix.co.za) 1.3 za-ns.anycast.pch.net (204.61.216.55) 1.3.1 ns4.iafrica.com -- resolving 1.3.1 ns4.iafrica.com (196.7.142.131) -- completed earlier (1.2.3) 1.3.2 ns0.is.co.za (196.4.160.17) -- completed earlier (1.2.1) 1.3.3 ns0.neotel.co.za (41.160.0.4) -- completed earlier (1.2.4) 1.3.4 coza1.dnsnode.net -- resolving 1.3.4 coza1.dnsnode.net (194.146.106.74) -- completed earlier (1.2.5) 1.3.5 ns1.coza.net.za -- resolving 1.3.5 ns1.coza.net.za (66.135.62.20,Loop encountered resolving ns.coza.net.za) -- completed earlier (1.2.2) 1.3.6 ns.coza.net.za -- resolving 1.3.6 ns.coza.net.za (206.223.136.200,Loop encountered resolving secdns1.posix.co.za) -- completed earlier (1.2.6) 1.4 sns-pb.isc.org (192.5.4.1) 1.4.1 ns.coza.net.za -- resolving 1.4.1 ns.coza.net.za (206.223.136.200,Loop encountered resolving secdns1.posix.co.za) -- completed earlier (1.2.6) 1.4.2 ns1.coza.net.za -- resolving 1.4.2 ns1.coza.net.za (66.135.62.20,Loop encountered resolving ns.coza.net.za) -- completed earlier (1.2.2) 1.4.3 ns0.is.co.za (196.4.160.17) -- completed earlier (1.2.1) 1.4.4 ns4.iafrica.com -- resolving 1.4.4 ns4.iafrica.com (196.7.142.131) -- completed earlier (1.2.3) 1.4.5 ns0.neotel.co.za (41.160.0.4) -- completed earlier (1.2.4) 1.4.6 coza1.dnsnode.net -- resolving 1.4.6 coza1.dnsnode.net (194.146.106.74) -- completed earlier (1.2.5) 1.5 disa.tenet.ac.za (196.21.79.50) Results: 10.0%: Answer from coza1.dnsnode.net (194.146.106.74) co.za. 3600 IN NS coza1.dnsnode.net. co.za. 3600 IN NS ns0.neotel.co.za. co.za. 3600 IN NS ns.coza.net.za. co.za. 3600 IN NS ns1.coza.net.za. co.za. 3600 IN NS ns0.is.co.za. co.za. 3600 IN NS ns4.iafrica.com. 20.0%: Answer from za1.dnsnode.net (194.146.106.78) co.za. 3600 IN NS ns0.is.co.za. co.za. 3600 IN NS coza1.dnsnode.net. co.za. 3600 IN NS ns4.iafrica.com. co.za. 3600 IN NS ns1.coza.net.za. co.za. 3600 IN NS ns.coza.net.za. co.za. 3600 IN NS ns0.neotel.co.za. 20.0%: Answer from disa.tenet.ac.za (196.21.79.50) co.za. 86400 IN NS coza1.dnsnode.net. co.za. 86400 IN NS ns.coza.net.za. co.za. 86400 IN NS ns0.is.co.za. co.za. 86400 IN NS ns0.neotel.co.za. co.za. 86400 IN NS ns1.coza.net.za. co.za. 86400 IN NS ns4.iafrica.com. 10.0%: Answer from ns0.is.co.za (196.4.160.17) co.za. 3600 IN NS ns.coza.net.za. co.za. 3600 IN NS ns4.iafrica.com. co.za. 3600 IN NS ns1.coza.net.za. co.za. 3600 IN NS coza1.dnsnode.net. co.za. 3600 IN NS ns0.is.co.za. co.za. 3600 IN NS ns0.neotel.co.za. 10.0%: Answer from ns4.iafrica.com (196.7.142.131) co.za. 3600 IN NS coza1.dnsnode.net. co.za. 3600 IN NS ns.coza.net.za. co.za. 3600 IN NS ns1.coza.net.za. co.za. 3600 IN NS ns0.is.co.za. co.za. 3600 IN NS ns4.iafrica.com. co.za. 3600 IN NS ns0.neotel.co.za. 9.8%: Answer from ns.coza.net.za (206.223.136.200) co.za. 3600 IN NS ns0.is.co.za. co.za. 3600 IN NS ns4.iafrica.com. co.za. 3600 IN NS ns1.coza.net.za. co.za. 3600 IN NS ns.coza.net.za. co.za. 3600 IN NS coza1.dnsnode.net. co.za. 3600 IN NS ns0.neotel.co.za. 10.0%: Answer from ns0.neotel.co.za (41.160.0.4) co.za. 3600 IN NS ns1.coza.net.za. co.za. 3600 IN NS ns0.neotel.co.za. co.za. 3600 IN NS ns0.is.co.za. co.za. 3600 IN NS coza1.dnsnode.net. co.za. 3600 IN NS ns4.iafrica.com. co.za. 3600 IN NS ns.coza.net.za. 10.0%: Answer from ns1.coza.net.za (66.135.62.20) co.za. 3600 IN NS ns1.coza.net.za. co.za. 3600 IN NS ns.coza.net.za. co.za. 3600 IN NS coza1.dnsnode.net. co.za. 3600 IN NS ns0.neotel.co.za. co.za. 3600 IN NS ns4.iafrica.com. co.za. 3600 IN NS ns0.is.co.za. 0.2%: Loop encountered at secdns1.posix.co.za While querying ns.coza.net.za/IN/A 0.0%: Loop encountered at ns.coza.net.za While querying secdns1.posix.co.za/IN/A Summary Results: 99.8% answered with co.za. 3600 IN NS ns0.is.co.za. co.za. 3600 IN NS coza1.dnsnode.net. co.za. 3600 IN NS ns4.iafrica.com. co.za. 3600 IN NS ns1.coza.net.za. co.za. 3600 IN NS ns.coza.net.za. co.za. 3600 IN NS ns0.neotel.co.za. 0.2% resulted in a loop
This is why your internets come unglued just sometimes.
dnstraverse, by the way is awesome, but there is a kinda fatal bug when it tries to load its documentation under RHEL/CentOS. To work around this, you can simply comment out the offending line in the code:
# gem install dnstraverse Fetching: dnsruby-1.60.0.gem (100%) Installing dnsruby... For issues and source code: https://github.com/alexdalitz/dnsruby For general discussion (please tell us how you use dnsruby): https://groups.google.com/forum/#!forum/dnsruby Successfully installed dnsruby-1.60.0 Fetching: dnstraverse-0.1.14.gem (100%) Successfully installed dnstraverse-0.1.14 Parsing documentation for dnsruby-1.60.0 Installing ri documentation for dnsruby-1.60.0 Parsing documentation for dnstraverse-0.1.14 Killed # dnstraverse /usr/share/rubygems/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- rdoc/usage (LoadError) from /usr/share/rubygems/rubygems/core_ext/kernel_require.rb:55:in `require' from /usr/local/share/gems/gems/dnstraverse-0.1.14/bin/dnstraverse:25:in `<top (required)>' from /usr/local/bin/dnstraverse:23:in `load' from /usr/local/bin/dnstraverse:23:in `<main>' # sed -i '25 s/^/#/' /usr/local/share/gems/gems/dnstraverse-0.1.14/bin/dnstraverse # dnstraverse parse error: Missing domain name parameter Usage: dnstraverse [options] DOMAIN -v, --[no-]verbose Run verbosely -d, --[no-]debug Debug mode. Use twice to turn on library debug. -r, --root-server HOST Root DNS server (default - ask local resolver) -a, --all-root-servers Find all root servers (default false) -t, --type TYPE Record type (A, AAAA, SRV, WKS, NS, CNAME, SOA, PTR, HINFO, MINFO, MX, TXT, ANY --udp-size SIZE UDP packet size (default 2048). Set to 512 to turn off EDNS0. --allow-tcp Try using tcp if udp truncated (default true) --always-tcp Always use tcp (default false) --max-depth DEPTH Maximum traversal depth (default 20) --retries TIMES Number of 2s retries before timing out (default 2) --[no-]follow-aaaa Only follow AAAA records for referrals (default false) --[no-]root-aaaa Look for IPv6 addresses for root servers (default false) --[no-]show-progress Display progress information (default true) --[no-]show-resolves Display referral resolutions (default false) --[no-]show-servers Display list of servers seen (default false) --[no-]show-versions Display versions of dns servers (default true) --[no-]show-all-stats Display statistics as we go (default false) --[no-]show-results Display the results (default true) --[no-]show-summary-results Display the summary results (default true) --save-objects --[no-]fast Fast mode (default true) turn off to be more accurate -h, --help Show full help -q, --quiet Supress supplementary information -V, --version Show version
This approach doesn’t work:
# gem install rdoc Fetching: rdoc-5.1.0.gem (100%) ERROR: Error installing rdoc: rdoc requires RubyGems version >= 2.2. Try 'gem update --system' to update RubyGems itself.