dnsprober
v1.0.0
Published
A concurrent CLI that resolves domains across multiple DNS servers and reports results in a live log and summary table.
Readme
dnsprober
A fast, concurrent CLI for resolving domains against multiple DNS servers and comparing the results.
What it does
dnsprober takes a list of domains and a list of DNS server IPs, then resolves every domain against every server in parallel (with a configurable concurrency limit). Each lookup's addresses, status, and timing are streamed to the console and written to an output file, and a summary table is printed at the end grouped by domain and sorted by response time.
Features
- Many-to-many resolution — resolves every domain against every DNS server you provide
- Concurrency control — cap how many lookups run at once via a semaphore
- Live streaming output — results print as they complete, not just at the end
- Persistent log file — every result (success or failure) is appended to an output file
- Summary table — successful results are grouped by domain and sorted by response time in a clean ASCII table
- DNS server file validation — only valid, de-duplicated IPv4 addresses are used as resolvers
- Debug logging — fine-grained logging per component via the
debugpackage
Requirements
- Node.js (with native TypeScript execution support, e.g. Node 22.6+ using
--experimental-strip-types, or run viatsx/ts-node)
Installation
git clone <this-repo>
cd dnsprober
npm installUsage
dnsprober --domains <d1,d2,...> --dns <resolvers.txt> [options]Options
| Flag | Description | Required | Default |
| --------------------- | ------------------------------------------------------- | -------- | --------------------------------- |
| --domains <list> | Comma-separated list of domains to resolve | Yes | — |
| --dns <file> | Path to a file containing DNS server IPs (one per line) | Yes | — |
| --concurrency <num> | Maximum number of concurrent resolutions | No | 10 |
| --output <file> | Path to the output result file | No | dns-scan-result-<timestamp>.txt |
| -h, --help | Show the help message | No | — |
DNS server file format
A plain text file with one IPv4 address per line. Blank lines and lines starting with # are ignored, and duplicates/invalid entries are filtered out automatically.
# Public resolvers
8.8.8.8
1.1.1.1
9.9.9.9Example
dnsprober --domains example.com,anthropic.com --dns resolvers.txt --concurrency 20 --output results.txtSample console output:
Resolving 2 domain(s) against 3 DNS server(s), concurrency=20
Results streaming to: /path/to/results.txt
[ OK ] example.com via 8.8.8.8 — 1 address(es): 93.184.215.14 (42ms)
[ OK ] anthropic.com via 1.1.1.1 — 2 address(es): 104.18.10.106, 104.18.11.106 (55ms)
[FAIL] example.com via 9.9.9.9 — error: ETIMEOUT (2001ms)
┌──────────────┬────────────┬────────┬───────────────────────────────┬───────────┐
│ Domain │ DNS Server │ Status │ Addresses │ Time (ms) │
├──────────────┼────────────┼────────┼───────────────────────────────┼───────────┤
│ example.com │ 8.8.8.8 │ OK │ 93.184.215.14 │ 42 │
│ anthropic.com│ 1.1.1.1 │ OK │ 104.18.10.106, 104.18.11.106 │ 55 │
└──────────────┴────────────┴────────┴───────────────────────────────┴───────────┘Every result (including failures) is also appended to the output file, e.g.:
[ OK ] example.com via 8.8.8.8 — 1 address(es): 93.184.215.14 (42ms)
[FAIL] example.com via 9.9.9.9 — error: ETIMEOUT (2001ms)
[ OK ] anthropic.com via 1.1.1.1 — 2 address(es): 104.18.10.106, 104.18.11.106 (55ms)Debug logging
dnsprober uses the debug package internally. Enable verbose logging with the DEBUG environment variable:
DEBUG=app:* dnsprober --domains example.com --dns resolvers.txtAvailable namespaces: app:ip-validator, app:file-loader, app:arg-parser, app:resolver, app:batch, app:organizer, app:writer, app:table, app:main.
Exit codes
0— completed successfully1— invalid arguments, unreadable DNS file, or no valid DNS servers found
License
MIT
