How to Capture & Analyze DNS Traffic with Wireshark

How to Capture & Analyze DNS Traffic with Wireshark
11/05/2025 •

Introduction

This guide shows you how to capture and analyze DNS traffic with Wireshark like a pro. You’ll build a small lab, generate real DNS queries, master capture vs. display filters, decode request/response fields (flags, opcodes, RCODEs, EDNS, DNSSEC, truncation), analyze performance, and troubleshoot real-world problems including UDP→TCP fallback, EDNS/MTU issues, CNAME chains, NXDOMAIN storms, and encrypted DNS (DoT/DoH) visibility.

How to Capture & Analyze DNS Traffic with Wireshark

Note on examples

Where a domain is needed, this guide uses sanchitgurukul.xyz. For a resolver, we’ll reference 10.4.2.109.


What You’ll Learn

  • Picking the right interface, ring buffers, and safe capture practices
  • The difference between capture filters (BPF) and display filters (Wireshark)
  • Reading DNS queries & responses (transaction ID, flags, AA/TC/RD/RA/AD/CD, RCODE)
  • EDNS(0), UDP size, DO bit, DNSSEC indicators, and truncation handling
  • Timing analysis with dns.time, IO Graphs, Conversations, and Expert Info
  • Troubleshooting: slow lookups, SERVFAILs, NXDOMAIN floods, TCP fallback
  • Visibility into DoT (DNS over TLS) & DoH (DNS over HTTPS) and when/how decryption is possible
  • Best practices, privacy, and a quick-reference filter & command cheat sheet

Prerequisites

  • Wireshark (latest stable)
  • Npcap on Windows (install with “Support raw 802.11 traffic” if needed)
  • Admin privileges (or dumpcap group on Linux)
  • Optional command-line tools: dig/kdig, nslookup, tcpdump, tshark

Lab Topology (Example)

Diagram illustrating a network topology showing a client connecting to a resolver at IP 10.4.2.109, which then connects to authoritative servers on the internet, labeled with LAN/Wi-Fi.

You can capture on the client interface to see queries leaving the host, and/or on the resolver to see aggregate traffic.


Step‑by‑Step Walkthrough

1) Prepare your environment

  • Windows: Install Wireshark (Npcap included). Reboot if prompted.
  • macOS: Install via official dmg or Homebrew. Grant packet capture permissions.
  • Linux: sudo apt install wireshark → add your user to the wireshark group (log out/in).

Safety & privacy: In Wireshark, go to Preferences → Name Resolution and uncheck external name resolution to avoid generating extra DNS traffic while analyzing.


2) Start a clean capture (client side)

Open Wireshark → select your active interface (Ethernet/Wi‑Fi).

Capture filter (only DNS over UDP/TCP classic):

      port 53
    

Capture filters are applied before packets are recorded. They are BPF syntax and fast.

Click Start.


3) Generate real traffic

Open a terminal and run a few queries:

dig (recommended)

# A record

      dig sanchitgurukul.xyz @10.4.2.109
    

# CNAME chain / www

      dig www.sanchitgurukul.xyz @10.4.2.109
    

# DNSSEC / larger answers

      dig +dnssec sanchitgurukul.xyz @10.4.2.109 +bufsize=4096
    

# Non-existent name (NXDOMAIN)

      dig nosuchhost.sanchitgurukul.xyz @10.4.2.109
    

nslookup (Windows built-in)

      nslookup sanchitgurukul.xyz 10.4.2.109
    

Browser test

      Visit https://sanchitgurukul.xyz 
    

-> To generate DNS from the browser.

-> Stop capture after 10–20 seconds.


4) Baseline analysis (display filters & anatomy)

Basic display filters (apply in the top filter box):

      dns
    
      udp.port == 53 || tcp.port == 53
    

Click a DNS query packet. In Packet Details expand Domain Name System (query).

Key fields to know:

Transaction ID: correlates request/response

Flags: QR (query/response), OPCODE, AA (Authoritative Answer), TC (Truncated), RD (Recursion Desired), RA (Recursion Available), AD (Authenticated Data), CD (Checking Disabled)

Questions: dns.qry.name, dns.qry.type (A/AAAA/CNAME/MX/TXT/SOA/NS/SRV)

Answers/Authority/Additional: RRs with TTLs and data

Response codes (RCODE) you’ll see: – NOERROR (0) — success – NXDOMAIN (3) — name does not exist – SERVFAIL (2) — server failure (common when upstream DNSSEC validation fails) – REFUSED (5) — policy blocking, ACLs, RPZ, etc.

Handy filters

# Successful answers

      dns.flags.rcode == 0 && dns.flags.response == 1
    

# NXDOMAIN only

      dns.flags.rcode == 3
    

# SERVFAIL only

      dns.flags.rcode == 2
    

# Truncation (UDP too small, expect TCP fallback)

      dns.flags.tc == 1
    

# Only queries for our domain

      dns.qry.name contains "sanchitgurukul.xyz"
    

# Slow responses (>100 ms)

      dns.time > 0.1
    

Tip: Add the dns.time column (Right‑click a field → Apply as Column) to see per‑transaction latency.


5) Understand UDP→TCP fallback & EDNS(0)

  • If a UDP response is too large and TC=1, clients retry over TCP 53.
  • EDNS(0) advertises a larger UDP size (e.g., 1232/4096).
  • DNSSEC and many records (e.g., many A/AAAA) increase size; watch for fragmentation/MTU issues if you see timeouts then TCP retries.

Filter to observe fallback:

      (dns.flags.tc == 1) || (tcp.port == 53 && dns)
    

6) Performance analysis

  • Add the dns.time column and sort to find outliers.
  • Use Statistics → Protocol Hierarchy to view DNS share of traffic.
  • Use Statistics → Conversations (UDP/TCP) to see heavy talkers.
  • Use Statistics → IO Graphs to graph COUNT(dns) and AVG(dns.time) over time.
  • Use Analyze → Expert Information for warnings (retransmissions, malformed packets).

Latency buckets (rule of thumb): – < 20 ms: local cache/resolver – 20–80 ms: typical recursive – 80–200+ ms: upstream/authoritative, WAN latency, or problems


7) Real‑World Troubleshooting Playbooks

A) “Web is slow” — EDNS/MTU blackhole

Symptoms: Browser hang before first byte, dns.time spikes (e.g., >1 s), TC=1, no UDP response or fragmented UDP blocked; eventual TCP fallback.

How to prove in Wireshark: 1. Filter dns && (dns.flags.tc == 1 || dns.time > 0.5) 2. Check OPT record: what is udp payload size? (e.g., 4096) 3. Look for missing UDP response or ICMP Frag Needed suppression. 4. Observe client retries over TCP and improved success.

Fixes: Lower EDNS size on resolver (e.g., 1232), ensure path MTU discovery/ICMP allowed, or prefer TCP for large answers.


B) Random NXDOMAINs — search suffix or split‑horizon issues

Symptoms: Users hit host instead of FQDN; queries go to host.localdomain then to external; or internal names leak publicly.

How to prove:

      dns.flags.rcode == 3 && (dns.qry.name contains ".local" || dns.qry.name matches ".*\.internal$")
    

Fixes: Enforce FQDN use, correct search suffix order, configure split DNS properly.


C) SERVFAIL bursts — upstream validation or auth problems

Symptoms: dns.flags.rcode == 2, often with AD=0, CD=0.

How to prove: – Look at Authority section for SOA; check which upstream the resolver is querying (capture server side). – Inspect DNSSEC DO bit and absence of RRSIGs; correlation with specific domains.

Fixes: Check upstream resolvers, time sync, DNSSEC trust anchors, or broken auth zones.


D) Long CNAME chains to CDN

Symptoms: Multiple CNAMEs before final A/AAAA → higher dns.time.

How to prove:

      dns.qry.name == "www.sanchitgurukul.xyz" && dns.flags.response == 1
    

Open the packet and expand Answers to count CNAME hops; compare total dns.time vs. single‑label lookups.

Fixes: Cache tuning, prefetch, or vendor side changes.


8) Encrypted DNS (DoT/DoH) visibility

DoT (DNS over TLS)

  • Default port 853. Filter: tcp.port == 853.
  • Without TLS keys, you see only the TLS handshake (SNI may be visible if not Encrypted ClientHello). With keys, Wireshark can decrypt and reassemble DNS messages.
  • After decryption, use Decode As… → TLS stream as DoT so Wireshark dissects payloads as DNS.

Client TLS key capture (where possible):

Set SSLKEYLOGFILE env var before launching the client that makes DoT connections, then in Wireshark Preferences → Protocols → TLS → (Pre)-Master-Secret log filename point to that file.

DoH (DNS over HTTPS)

  • DoH rides over HTTPS (HTTP/2 or HTTP/3/QUIC). Filter examples:
      http2 && tcp.port == 443 && (http2.header.value contains "dns-query")
quic && udp.port == 443
    
  • You’ll likely need TLS keys as above. After decryption, look for :path like /dns-query and content type application/dns-message.

Note: Many modern browsers support Encrypted ClientHello (ECH). If ECH is active and you lack keys, server name and payloads will be opaque.


9) Server‑side capture (on resolver 10.4.2.109)

Use tcpdump with ring buffers to avoid disk blow‑ups:

      sudo tcpdump -i eth0 -n -s 0 -w /var/log/dns-%Y%m%d%H%M%S.pcap -Z root \
  -G 300 -W 12 '(port 53 or port 853)'
    

-G 300 rolls files every 5 min; -W 12 keeps last 1 hour.

  • Copy .pcap files to your workstation for deep dives in Wireshark.

Quick, text‑only look with tshark:

# Top queriers

      
sudo tshark -r file.pcap -Y "dns && dns.flags.response == 0" -T fields -e ip.src | sort | uniq -c | sort -nr | head
    


# Slow transactions (>200 ms)

      sudo tshark -r file.pcap -Y "dns.time > 0.2 && dns.flags.response == 1" -T fields -e frame.number -e dns.qry.name -e dns.time
    

10) Exporting & reporting

  • Save as pcapng to preserve name resolution and comments.
  • File → Export Packet Dissections → As CSV for sharing tables of slow queries.
  • Add Packet Comments (right‑click a packet) for annotations.
  • Use Statistics → Endpoints/Conversations screenshots in reports, with sensitive IPs masked.

Best Practices & Security

  • Minimize scope: Narrow capture filters (e.g., host 10.4.2.109 and port 53).
  • Avoid generating DNS during analysis: Disable external name resolution in preferences.
  • Time sync: Ensure NTP on all devices; inaccurate clocks break correlation.
  • Respect privacy: DNS reveals browsing intent; obtain approvals and redact before sharing.
  • Column hygiene: Add dns.time, dns.qry.name, dns.flags.rcode, and tcp.stream/udp.stream.
  • Coloring rules: Color dns.flags.rcode != 0 to spot errors fast.
  • EDNS size: 1232 is a good conservative default when MTU issues are suspected.
  • Cache analysis: Look at TTLs; low TTLs cause more upstream traffic.

Useful DNS Display Filters (Quick Reference)

# Everything DNS

      dns
    

# By server IP

      dns && ip.addr == 10.4.2.109
    

# Only queries vs only responses

      dns.flags.response == 0
    
      dns.flags.response == 1
    

# Errors

      dns.flags.rcode != 0
    

# NXDOMAIN / SERVFAIL

      dns.flags.rcode == 3
    
      dns.flags.rcode == 2
    

# Truncated

      dns.flags.tc == 1
    

# Large answers (>1200B) – approximate

      dns && frame.len > 1200
    

# Slow transactions (>100 ms)

      dns.time > 0.1
    

# Query for A/AAAA only

      dns.qry.type == 1 || dns.qry.type == 28
    

# TXT / SRV / MX

      dns.qry.type == 16 || dns.qry.type == 33 || dns.qry.type == 15
    

# Only our domain

      dns.qry.name contains "sanchitgurukul.xyz"
    

# DoT / DoH indicators

      tcp.port == 853
    

      http2.header.value contains "dns-query"
    


Handy Commands Cheat Sheet

# Client tests
Dig basic            :

      dig sanchitgurukul.xyz @10.4.2.109
    

Dig with DNSSEC      :

      dig +dnssec sanchitgurukul.xyz @10.4.2.109 +bufsize=4096
    

Dig AAAA only        :

      dig aaaa sanchitgurukul.xyz @10.4.2.109
    

Dig timing           :

      dig +stats sanchitgurukul.xyz @10.4.2.109
    

# Continuous: 1 q/s for 60s

      while true; do dig +retry=0 +timeout=1 sanchitgurukul.xyz @10.4.2.109; sleep 1; done
    

# tcpdump (client): only DNS

      sudo tcpdump -i any -n -s0 -w dns.pcap '(port 53 or port 853)'
    

# tshark: show query name and RCODE live

      tshark -i any -Y "dns" -T fields -e frame.time -e dns.qry.name -e dns.flags.rcode
    

Advanced Testing & Troubleshooting Ideas

  • Trigger truncation: Query DNSSEC‑enabled names with many records; watch for TC=1 and TCP retry.
  • CNAME depth test: Query www on CDN‑backed domains and count hops.
  • Negative caching: Query a non‑existent name twice; second should be faster if resolver caches NXDOMAIN with SOA.
  • Policy blocks (RPZ/ACL): Look for REFUSED (5) or NOERROR with 0 answers.
  • DGA/malware hunting: High volume of random‑looking labels, many NXDOMAINs from a single host.
  • DNS tunneling detection: Long TXT queries/answers, consistent QPS from a single host, unusual RR types.

Caution: Use these techniques only in environments where you have permission to test.


Use Cases (When DNS Capture Pays Off)

  • Root cause for “slow internet” (DNS latency vs. network/app)
  • EDNS/MTU path issues causing timeouts
  • Split‑DNS design reviews (internal vs. external views)
  • Security: detect DGAs, tunneling, exfiltration via TXT, or blocked C2 domains
  • Capacity planning: QPS per client, burst patterns, cache hit/miss hints
  • Vendor/CDN troubleshooting: CNAME chains, geolocation mis‑mapping

Summary (TL;DR)

  1. Use a tight capture filter (port 53) with safe settings.
  2. Apply display filters (dns.time, dns.flags.rcode, dns.flags.tc) to identify issues.
  3. Correlate UDP truncation, EDNS sizes, and MTU/fragmentation symptoms.
  4. For DoT/DoH, obtain TLS keys for query visibility; otherwise treat as encrypted flows.
  5. Follow playbooks for NXDOMAIN storms, SERVFAIL issues, and CDN CNAME chains.
  6. Export clean evidence (pcapng, CSV), document, and share responsibly.

Checklist

  • Correct interface selected, external name resolution off
  • Capture filter set (port 53 / 853 as needed)
  • Columns include dns.time, dns.qry.name, dns.flags.rcode
  • Look for TC=1, UDP size in OPT, TCP fallback
  • Check RCODE distribution and slow transactions
  • Validate EDNS/MTU path; test with DNSSEC/large answers
  • For encrypted DNS, configure key logging if allowed
  • Save pcapng, export CSV, write packet comments

https://www.wireshark.org/docs/relnotes

https://sanchitgurukul.com/basic-networking

https://sanchitgurukul.com/network-security


©sanchitgurukul – You may copy with attribution.

Disclaimer: This article may contain information that was accurate at the time of writing but could be outdated now. Please verify details with the latest vendor advisories or contact us at admin@sanchitgurukul.com.

Discover more from

Subscribe now to keep reading and get access to the full archive.

Continue reading