CI / test (pull_request) Failing after 2m13s
- Rewrite README.md with overview, features, installation (go install +
build from source), quick start, full CLI flag reference table,
output section descriptions, project structure, and development guide
- Add package-level doc comments to all five internal packages:
config, dns, fingerprint, output, traverse (via doc.go or existing
package-declaration files)
- Add GoDoc comments on every exported type, constant, function, and
method across all packages:
- internal/config: Config struct fields, all Parse*/Default/Validate
- internal/dns: QueryConfig, Resolver, BasicResolver, CachingResolver,
ExchangeFunc, RootServer, RootDiscoveryConfig, DecodedResponse,
ResponseClassification, all exported helpers
- internal/fingerprint: Fingerprinter, New, NewWithTimeout, Query,
FingerprintAll
- internal/traverse: Traverser, TraverserConfig, TraversalResult,
Referral, ResolutionState, Response, ResponseType, InfoCache,
Stack, TraverserHooks, EventStage, TraversalEvent, EventHandler,
CircularReferralError, UnresolvableNameserverError
- internal/output: Format, Config, Formatter, SummaryStats,
NewFormatter, AttachHooks, RunTraversal, DefaultConfig,
ComputeSummary
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: multica-agent <github@multica.ai>
272 lines
7.1 KiB
Markdown
272 lines
7.1 KiB
Markdown
# ExploreDNS
|
||
|
||
ExploreDNS is a command-line DNS reconnaissance and exploration tool that performs iterative DNS traversal from the root servers down to the target domain — the same way resolvers do, but with full visibility into every step.
|
||
|
||
Unlike a standard resolver query, ExploreDNS shows you the entire delegation path: which root server was queried, which TLD server was referred to, which authoritative server finally answered, and the probability that each path was followed. It also fingerprints nameservers via `version.bind` and detects CNAME chains, CNAME loops, and circular referrals.
|
||
|
||
Inspired by [dnstraverse](https://github.com/jeremyevans/dnstraverse).
|
||
|
||
---
|
||
|
||
## Features
|
||
|
||
- **Full delegation path visibility** — every referral hop from root to authoritative
|
||
- **CNAME chain following** and **loop detection**
|
||
- **DNAME synthesis** — generates implicit CNAME targets from DNAME records
|
||
- **Server fingerprinting** — queries `version.bind` CHAOS TXT on all encountered servers
|
||
- **JSON output** — machine-readable structured output for scripting and pipelines
|
||
- **Fast mode** — shared glue cache across branches (on by default)
|
||
- **Configurable transport** — UDP with TCP fallback, or TCP-only
|
||
- **All 13 root servers** — optionally query every root for maximum coverage
|
||
- **IPv6 support** — follow AAAA glue records when available
|
||
- **Probability weighting** — each result carries a probability so you know how authoritative it is
|
||
|
||
---
|
||
|
||
## Installation
|
||
|
||
### go install (recommended)
|
||
|
||
```sh
|
||
go install github.com/hits/ExploreDNS/cmd/exploredns@latest
|
||
```
|
||
|
||
### Build from source
|
||
|
||
```sh
|
||
git clone https://github.com/hits/ExploreDNS.git
|
||
cd ExploreDNS
|
||
go build -o bin/exploredns ./cmd/exploredns
|
||
```
|
||
|
||
Or via the Makefile:
|
||
|
||
```sh
|
||
make build
|
||
```
|
||
|
||
The binary is placed at `bin/exploredns`.
|
||
|
||
---
|
||
|
||
## Quick Start
|
||
|
||
```sh
|
||
# Basic A record traversal
|
||
exploredns www.example.com
|
||
|
||
# Query MX records
|
||
exploredns --type MX example.com
|
||
|
||
# JSON output for scripting
|
||
exploredns --json www.example.com | jq .summary
|
||
|
||
# Use all 13 root servers
|
||
exploredns --all-root-servers www.example.com
|
||
|
||
# TCP only (no UDP)
|
||
exploredns --allow-tcp --always-tcp www.example.com
|
||
|
||
# Quiet mode — results only, no headers
|
||
exploredns --quiet --no-show-progress --no-show-resolves --no-show-servers www.example.com
|
||
|
||
# Debug mode (shows config and traversal steps)
|
||
exploredns --debug www.example.com
|
||
|
||
# Library-level debug
|
||
exploredns -dd www.example.com
|
||
```
|
||
|
||
---
|
||
|
||
## Examples
|
||
|
||
### Basic traversal
|
||
|
||
```
|
||
$ exploredns www.example.com
|
||
ExploreDNS - exploring: www.example.com (type: A)
|
||
1 198.41.0.4 (A)
|
||
2 192.5.6.30 (A)
|
||
3 199.43.135.53 (A)
|
||
4 93.184.216.34 (A)
|
||
4 100% answered with 93.184.216.34
|
||
|
||
The following servers were encountered:
|
||
a.root-servers.net: 198.41.0.4
|
||
a.iana-servers.net: 199.43.135.53
|
||
a.gtld-servers.net: 192.5.6.30
|
||
|
||
Results:
|
||
4 100% answered with 93.184.216.34
|
||
|
||
Summary:
|
||
100% answered with 93.184.216.34
|
||
```
|
||
|
||
### MX records
|
||
|
||
```sh
|
||
exploredns --type MX gmail.com
|
||
```
|
||
|
||
### JSON output
|
||
|
||
```sh
|
||
exploredns --json www.example.com
|
||
```
|
||
|
||
```json
|
||
{
|
||
"domain": "www.example.com",
|
||
"query_type": "A",
|
||
"results": [
|
||
{
|
||
"depth": 3,
|
||
"probability": 1,
|
||
"response_type": "answer",
|
||
"server": "93.184.216.34",
|
||
"answers": ["www.example.com. 3600 IN A 93.184.216.34"]
|
||
}
|
||
],
|
||
"servers": [
|
||
{"name": "a.root-servers.net", "ips": ["198.41.0.4"]},
|
||
{"name": "a.gtld-servers.net", "ips": ["192.5.6.30"]},
|
||
{"name": "a.iana-servers.net", "ips": ["199.43.135.53"]}
|
||
],
|
||
"summary": {
|
||
"answers": [{"rdata": "93.184.216.34", "probability": 1}]
|
||
}
|
||
}
|
||
```
|
||
|
||
### All root servers
|
||
|
||
```sh
|
||
exploredns --all-root-servers www.example.com
|
||
```
|
||
|
||
Uses all 13 root servers. Each branch carries a probability of approximately 1/13.
|
||
|
||
### Verbose mode
|
||
|
||
```sh
|
||
exploredns -v www.example.com
|
||
```
|
||
|
||
Adds bailiwick information to each progress line.
|
||
|
||
---
|
||
|
||
## CLI Reference
|
||
|
||
```
|
||
Usage:
|
||
exploredns [flags] <domain>
|
||
```
|
||
|
||
### Query Options
|
||
|
||
| Flag | Default | Description |
|
||
|------|---------|-------------|
|
||
| `--type` | `A` | Record type: `A`, `AAAA`, `NS`, `CNAME`, `MX`, `TXT`, `SOA`, `PTR`, `ANY` |
|
||
| `--root-server` | _(auto)_ | Override the root server IP address |
|
||
| `--all-root-servers` | `false` | Use all 13 root servers |
|
||
| `--root-aaaa` | `false` | Include IPv6 addresses of root servers |
|
||
| `--follow-aaaa` | `false` | Follow only AAAA glue records for referrals |
|
||
|
||
### Transport Options
|
||
|
||
| Flag | Default | Description |
|
||
|------|---------|-------------|
|
||
| `--udp-size` | `2048` | EDNS0 UDP payload size (512–4096) |
|
||
| `--allow-tcp` | `true` | TCP fallback when UDP response is truncated |
|
||
| `--always-tcp` | `false` | Always use TCP (requires `--allow-tcp`) |
|
||
| `--retries` | `2` | Number of retry attempts per query (0–10) |
|
||
|
||
### Traversal Options
|
||
|
||
| Flag | Default | Description |
|
||
|------|---------|-------------|
|
||
| `--max-depth` | `20` | Maximum referral depth (1–100) |
|
||
| `--fast` | `true` | Fast mode: sibling branches share a glue cache |
|
||
|
||
### Output Options
|
||
|
||
| Flag | Default | Description |
|
||
|------|---------|-------------|
|
||
| `--verbose`, `-v` | `false` | Verbose output (shows bailiwick on each line) |
|
||
| `--debug`, `-d` | `false` | Application debug output to stderr |
|
||
| `-dd` | `false` | Library-level debug (equivalent to `-d -d`) |
|
||
| `--quiet`, `-q` | `false` | Suppress introductory banner |
|
||
| `--json` | `false` | Output results as a single JSON document |
|
||
| `--show-progress` / `--no-show-progress` | on | Per-referral traversal progress lines |
|
||
| `--show-resolves` / `--no-show-resolves` | on | Nameserver address resolution detail |
|
||
| `--show-servers` / `--no-show-servers` | on | Encountered servers list |
|
||
| `--show-versions` / `--no-show-versions` | on | Server version.bind fingerprints |
|
||
| `--show-all-stats` / `--no-show-all-stats` | on | Per-result stats as they arrive |
|
||
| `--show-results` / `--no-show-results` | on | Terminal results section |
|
||
| `--show-summary-results` / `--no-show-summary-results` | on | Probability summary section |
|
||
|
||
> **Tip:** Set `NO_COLOR=1` in your environment to disable ANSI colour codes.
|
||
|
||
---
|
||
|
||
## Output Sections
|
||
|
||
### Traversal progress
|
||
|
||
```
|
||
1 198.41.0.4 (A)
|
||
2 192.5.6.30 (A)
|
||
```
|
||
|
||
Each line shows the hop number, the server IP, and the query type. Indentation reflects delegation depth.
|
||
|
||
### Servers list
|
||
|
||
Lists every nameserver encountered, mapped to its IP address, with optional `version.bind` fingerprints.
|
||
|
||
### Results
|
||
|
||
Terminal outcomes (answers, NXDOMAIN, SERVFAIL, etc.) for each leaf of the traversal tree.
|
||
|
||
### Summary
|
||
|
||
Aggregates terminal results by response type, weighted by probability. Answer results are grouped by RDATA value.
|
||
|
||
---
|
||
|
||
## Project Structure
|
||
|
||
```
|
||
cmd/exploredns/ CLI entry point and flag parsing
|
||
internal/config/ Config struct, validation, and usage text
|
||
internal/dns/ DNS query primitives, response decoding, root discovery
|
||
internal/traverse/ Iterative DNS tree traversal engine
|
||
internal/fingerprint/ DNS server version fingerprinting
|
||
internal/output/ Text and JSON output formatters
|
||
```
|
||
|
||
---
|
||
|
||
## Development
|
||
|
||
```sh
|
||
make test # run tests
|
||
make lint # run go vet
|
||
make clean # remove build artifacts
|
||
```
|
||
|
||
To run tests with the race detector:
|
||
|
||
```sh
|
||
go test -race ./...
|
||
```
|
||
|
||
---
|
||
|
||
## License
|
||
|
||
MIT
|