When you perform a DNS lookup using tools like nslookup
or dig
, the response typically shows the immediate DNS server that provided the answer (usually your local resolver), but doesn't reveal the authoritative server that ultimately resolved the query. Here's how to dig deeper.
nslookup example.com
Output:
Server: 127.0.0.53
Address: 127.0.0.53#53
Non-authoritative answer:
Name: example.com
Address: 93.184.216.34
This only shows your local resolver (127.0.0.53 in this case), not the complete resolution path.
The dig +trace
command performs a full iterative lookup from the root servers down:
dig +trace example.com
Output shows each step:
;; Received 525 bytes from 192.36.148.17#53(192.36.148.17) in 24 ms
;; Received 332 bytes from 192.5.6.30#53(192.5.6.30) in 28 ms
;; Received 340 bytes from 199.43.135.53#53(199.43.135.53) in 32 ms
For a more targeted approach without full tracing:
dig +norecurse +nocmd example.com @8.8.8.8
This reveals intermediate servers in the resolution path.
To see which nameserver ultimately answered authoritatively:
dig +short NS example.com
Output:
a.iana-servers.net.
b.iana-servers.net.
For complete visibility, use tcpdump
:
sudo tcpdump -i any -n port 53 -w dns.pcap
Analyze with Wireshark to see every DNS transaction.
- DNS resolution often involves multiple caching layers
- Results may vary based on your network configuration
- Some DNS providers may obscure the complete path
When you run a simple nslookup
or dig
command, the answer you get is often a result of multiple DNS servers communicating behind the scenes. Here's how to peel back the layers and see exactly which server provided the final answer.
nslookup google.de
Server: 127.0.1.1
Address: 127.0.1.1#53
Non-authoritative answer:
Name: google.de
Address: 172.217.18.3
The "Server" line shows your local resolver (often dnsmasq on Ubuntu), but this isn't the authoritative source. To find the actual responding server, we need deeper inspection.
While dig +trace
shows the full recursive path, it's overkill when you just want to see the final responder. Try this instead:
dig google.de +norecurse +stat
; <<>> DiG 9.16.1-Ubuntu <<>> google.de +norecurse +stat
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 65160
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;google.de. IN A
;; ANSWER SECTION:
google.de. 251 IN A 172.217.18.3
;; Query time: 24 msec
;; SERVER: 127.0.0.53#53(127.0.0.53)
;; WHEN: Thu Feb 10 12:34:56 UTC 2022
;; MSG SIZE rcvd: 55
For real-time observation of DNS traffic:
sudo tcpdump -i any -n port 53 -vv
Run this in one terminal while executing your DNS query in another to see the actual network packets.
Here's how to programmatically identify the responding server:
import dns.resolver
def find_responder(domain):
resolver = dns.resolver.Resolver()
resolver.nameservers = ['8.8.8.8'] # Set to known resolver
response = resolver.resolve(domain)
print(f"Final responder: {resolver.nameservers[0]}")
return response
find_responder('google.de')
- The "Server" line in nslookup shows your local resolver, not the authoritative server
- Use
dig +norecurse
for a lighter-weight alternative to +trace - Network sniffing provides the most accurate picture of actual DNS traffic