25

I have a seemingly simple question but couldn't find the answer to precisely that question after some search:
I know that, if I want to look up the IP address of some domain name, I type, for example:

nslookup google.de

and get

Server:     127.0.1.1
Address:    127.0.1.1#53

Non-authoritative answer:
Name:   google.de
Address: 172.217.18.3

However, I don't know where I got this answer from. As far as I know at first my resolver tries to ask my local DNS server (which is on Ubuntu dnsmasq) and if that one doesn't have the answer it asks the next server and so on. But I want to know what exact server in the end had the answer. Is that possible?
I also tried

dig +trace www.google.com

which provides all information about the issued servers but performs a fully iterative lookup. I'd basically like an answer like that but with a normal look-up.

Staki42
  • 353

4 Answers4

10

See this https://stackoverflow.com/questions/38021/how-do-i-find-the-authoritative-name-server-for-a-domain-name

in short, nslookup set the query type to SOA

single line:

 nslookup -querytype=soa google.de
 nslookup -d2 -type=ANY google.de
 nslookup -d2 -type=ANY google.de 8.8.8.8

look for: primary name server

command line> nslookup
> set querytype=soa
> google.de
Server:  google-public-dns-a.google.com
Address:  8.8.8.8

Non-authoritative answer:
google.de
    primary name server = ns2.google.com 
    responsible mail addr = dns-admin.google.com
    serial  = 160093636
    refresh = 900 (15 mins)
    retry   = 900 (15 mins)
    expire  = 1800 (30 mins)
    default TTL = 60 (1 min)

>

EDIT:

I'm told that the SOA record may not be the best method. That it may not even be set correctly. So, the NS record would have been a better choice:

Where is the nameserver server for the domain...

  nslookup  -type=NS google.de

Or with a lot of debug info to find the nameserver

  nslookup -d2 -type=NS google.de
9

I want to know what exact server in the end had the answer. Is that possible?

This is not achievable. You will not find the specific authoritative server that was consulted named anywhere in the payload of a DNS reply. There are CHAOS queries that exist for the purpose of identifying the specific recursive server that replied to you, but no such equivalent for extracting the name of the exact authoritative server that a recursor obtained the data from.

The StackOverflow Q&A that Phillip linked to provides instructions for how to identify the list of NS records that were present in the authority section of a recursive DNS response. This is the full list of servers though, not the specific server. Even were that sufficient for your uses, this information is considered optional by the DNS standards and it is increasingly rare to see it in recursive responses in order to reduce the payload size of internally sourced reflection attacks.

If you know the name of the zone, you can request the full list of NS records via an explicit request for them. This requires knowing that you are at the apex of the zone; a request for example.com NS records will return the desired response but www.example.com will not, unless www was delegated to another set of servers. In this case, you have no choice but to work backwards iteratively until you discover the apex of the zone.

Long story short, there is no reliable short path (i.e. single query) to getting information about all upstream authority from a recursive server, and there is no way to learn the specific authoritative server that responded to a query without also controlling the authoritative server and creating unique data on each server. (if you do this, please create a unique zone for that purpose so that it does not interfere with your more sensitive production zone transfers)

Andrew B
  • 33,868
4

When you use dig in the default reply you will have the IP of the answering nameserver, which should be the recursive nameserver configured in your system (/etc/resolv.conf typically).

Patrick Mevzek
  • 10,581
  • 7
  • 35
  • 45
0

So for better understand the +trace command, you can use the dnstracer.

Install it and run the dnstracer command like the example below the -s . is to request a full trace from the root servers the -4 to query just ipv4 (usefull if you do not have ipv6 enabled) and -o to output the query results too

 dnstracer -s . -4 -o b.org
Tracing to b.org[a] via A.ROOT-SERVERS.NET, maximum of 3 retries
A.ROOT-SERVERS.NET [.] (198.41.0.4) 
 |\___ b2.org.afilias-nst.org [org] (2001:0500:0048:0000:0000:0000:0000:0001) Not queried
 |\___ b2.org.afilias-nst.org [org] (199.249.120.1) 
 |     |\___ ns2.dan.com [b.org] (173.201.66.67) Got authoritative answer 
 |     |\___ ns2.dan.com [b.org] (2603:0005:2225:0000:0000:0000:0000:0043) Not queried
 |      \___ ns1.dan.com [b.org] (97.74.98.67) Got authoritative answer 
 |      \___ ns1.dan.com [b.org] (2603:0005:2125:0000:0000:0000:0000:0043) Not queried
 |\___ b0.org.afilias-nst.org [org] (2001:0500:000c:0000:0000:0000:0000:0001) Not queried
 |\___ b0.org.afilias-nst.org [org] (199.19.54.1) 
 |     |\___ ns1.dan.com [b.org] (97.74.98.67) (cached)
 |     |\___ ns1.dan.com [b.org] (2603:0005:2125:0000:0000:0000:0000:0043) Not queried
 |      \___ ns2.dan.com [b.org] (173.201.66.67) (cached)
 |      \___ ns2.dan.com [b.org] (2603:0005:2225:0000:0000:0000:0000:0043) Not queried
 |\___ a2.org.afilias-nst.info [org] (2001:0500:0040:0000:0000:0000:0000:0001) Not queried
 |\___ a2.org.afilias-nst.info [org] (199.249.112.1) 
 |     |\___ ns2.dan.com [b.org] (173.201.66.67) (cached)
 |     |\___ ns2.dan.com [b.org] (2603:0005:2225:0000:0000:0000:0000:0043) Not queried
 |      \___ ns1.dan.com [b.org] (97.74.98.67) (cached)
 |      \___ ns1.dan.com [b.org] (2603:0005:2125:0000:0000:0000:0000:0043) Not queried
 |\___ c0.org.afilias-nst.info [org] (2001:0500:000b:0000:0000:0000:0000:0001) Not queried
 |\___ c0.org.afilias-nst.info [org] (199.19.53.1) 
 |     |\___ ns1.dan.com [b.org] (97.74.98.67) (cached)
 |     |\___ ns1.dan.com [b.org] (2603:0005:2125:0000:0000:0000:0000:0043) Not queried
 |      \___ ns2.dan.com [b.org] (173.201.66.67) (cached)
 |      \___ ns2.dan.com [b.org] (2603:0005:2225:0000:0000:0000:0000:0043) Not queried
 |\___ a0.org.afilias-nst.info [org] (2001:0500:000e:0000:0000:0000:0000:0001) Not queried
 |\___ a0.org.afilias-nst.info [org] (199.19.56.1) 
 |     |\___ ns2.dan.com [b.org] (173.201.66.67) (cached)
 |     |\___ ns2.dan.com [b.org] (2603:0005:2225:0000:0000:0000:0000:0043) Not queried
 |      \___ ns1.dan.com [b.org] (97.74.98.67) (cached)
 |      \___ ns1.dan.com [b.org] (2603:0005:2125:0000:0000:0000:0000:0043) Not queried
 |\___ d0.org.afilias-nst.org [org] (2001:0500:000f:0000:0000:0000:0000:0001) Not queried
  \___ d0.org.afilias-nst.org [org] (199.19.57.1) 
       |\___ ns1.dan.com [b.org] (97.74.98.67) (cached)
       |\___ ns1.dan.com [b.org] (2603:0005:2125:0000:0000:0000:0000:0043) Not queried
        \___ ns2.dan.com [b.org] (173.201.66.67) (cached)
        \___ ns2.dan.com [b.org] (2603:0005:2225:0000:0000:0000:0000:0043) Not queried

ns1.dan.com (97.74.98.67) b.org -> 3.64.163.50 ns2.dan.com (173.201.66.67) b.org -> 3.64.163.50

This will show that the . is taken care by the root DNS servers, then the org is taken care by the *.afilias-nst.org DNS servers and finally the b is taken care by the dan.com servers. It will detect broken dns servers in the path and even some miss-configs

a normal query will choose any of the above paths, will not query all servers, just one server in each level, bypassing ones that may already have in cache.

If you want to find what DNS server is replying to your query, that is harder and depends a lot from your setup... but at least in big setups, this sometimes work

May not work in most places, but the DNS EDNS protocol allow the remote server to send a NSID, to help identify the origin server.

Use the +edns +nsid in the dig and it MAY return a NSID line with the id:

 dig +edns +nsid google.com  @8.8.8.8

; <<>> DiG 9.10.3-P4-Debian <<>> +edns +nsid google.com @8.8.8.8 ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 11816 ;; flags: qr rd ra; QUERY: 1, ANSWER: 6, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 512 ; NSID: 67 70 64 6e 73 2d 6c 68 72 ("gpdns-lhr") ;; QUESTION SECTION: ;google.com. IN A

;; ANSWER SECTION: google.com. 300 IN A 74.125.193.102 google.com. 300 IN A 74.125.193.138 google.com. 300 IN A 74.125.193.139 google.com. 300 IN A 74.125.193.113 google.com. 300 IN A 74.125.193.100 google.com. 300 IN A 74.125.193.101

;; Query time: 20 msec ;; SERVER: 8.8.8.8#53(8.8.8.8) ;; WHEN: Thu Oct 05 23:17:15 UTC 2023 ;; MSG SIZE rcvd: 148

If the NSID line is empty, the remote server is not configured to send that info.

In bind, you can configure your server to return the NSID by setting up the server-id option : https://bind9.readthedocs.io/en/latest/reference.html#namedconf-statement-server-id

higuita
  • 1,321
  • 10
  • 13