dnssnoop is a utility for tracing standard DNS queries as they are sent from your system to DNS servers from all processes on a Linux system in real-time. It captures information related to both the query made and the resulting response with minimal system overhead.
dnssnoop is a yeet that can be deployed to a yeet daemon using the yeet package manager or directly from the system running the yeet daemon.
Go to https://yeet.cx/@yeet/dnssnoop, select the host on which you'd like it deployed, and click "Deploy".
Build the eBPF program:
makeDeploy to the local host:
yeet add .Each time a DNS query is made and answered an event is emitted:
| Field | Type | Description |
|---|---|---|
| tid | KernelPid |
The thread ID of the thread that made this query. |
| pid | KernelPid |
The process ID of the process that made this query. |
| cgroup_id | INT |
The ID of the control group associated with the process that made this query. |
| latency_ns | INT |
The latency, in nanoseconds, between the request and the reply. |
| transaction_id | INT |
The transaction ID of the query. |
| command | STRING |
The full command that spawned the process that made this query. |
| domain_name | STRING |
The domain name being queried. |
| resolved_addresses | [STRING] |
All the A records returned by the reply. |
| cgroup_name | STRING |
The name of the control group associated with the process that made this query. |
| remote_ip | STRING |
The IP address of the DNS server this query was sent to. |
| remote_port | INT |
The UDP port of the DNS server this query was sent to. |
| local_ip | STRING |
The IP address this query was sent from. |
| local_port | INT |
The UDP port this query was sent from. |
SELECT
event.domain_name,
ROUND(QUANTILE_CONT(event.latency_ns, 0.99) / 1e6, 2) AS p99_latency_ms
FROM <collection_name>
GROUP BY event.domain_name
ORDER BY p99_latency_ms DESC
LIMIT 10- Identifies domains with the slowest DNS resolution times.
- Helps optimize performance by pinpointing DNS bottlenecks.
- Detects third-party services affecting latency and application speed.
- Surfaces misconfigured or overloaded DNS resolvers.
- Prevents timeouts, slow API responses, and degraded user experiences.
SELECT
event.domain_name,
COUNT(*) AS total_queries
FROM <collection_name>
GROUP BY event.domain_name
ORDER BY total_queries DESC
LIMIT 10- Identifies which domains are queried the most.
- Helps analyze DNS traffic patterns for potential optimizations.
- Detects unexpected domain spikes that may indicate security risks or application bugs.
SELECT
event.remote_ip AS dns_resolver,
ROUND(QUANTILE_CONT(event.latency_ns, 0.99) / 1e6, 2) AS p99_latency_ms
FROM <collection_name>
GROUP BY event.remote_ip
ORDER BY p99_latency_ms DESC
LIMIT 10- Finds the slowest DNS resolvers that may be affecting performance.
- Helps decide if switching to a faster resolver (e.g., Cloudflare, Google) is necessary.
- Detects network congestion issues between your system and specific resolvers.
SELECT
event.command AS process,
COUNT(*) AS total_queries
FROM <collection_name>
GROUP BY event.command
ORDER BY total_queries DESC
LIMIT 10- Identifies which processes generate the most DNS traffic.
- Helps debug applications or scripts overloading the DNS resolver.
- Detects potential malware or suspicious activity.
SELECT
date_trunc('second', timestamp) AS second_bucket,
COUNT(*) AS queries_per_sec
FROM <collection_name>
GROUP BY second_bucket
ORDER BY second_bucket DESC- Detects sudden spikes in DNS traffic (DDoS, botnets, misconfigured services).
- Helps monitor real-time DNS query load.
- Useful for capacity planning and anomaly detection.
SELECT
event.domain_name,
COUNT(*) AS query_count
FROM <collection_name>
GROUP BY event.domain_name
ORDER BY query_count ASC- Finds domains that have been queried the least.
- Highlights one-off lookups, which may indicate: malware, data exfiltration, misconfigured internal / test domains.
- Useful for threat hunting and anomaly detection.