DNSRecon gathers what a domain publishes in DNS and flags common mistakes. A standard run lists the MX, SOA, NS, A, AAAA, SPF and TXT records, checks every name server for an open zone transfer, tests for wildcard resolution and looks up common SRV records. Other modes expand a name across top-level domains, check a wordlist of likely host names, do reverse lookups over an IP range, and read certificate transparency logs through crt.sh. Optional Shodan support expands netblocks found in SPF and WHOIS data. Results export to JSON, XML, CSV or SQLite, and a small REST API exposes the same checks.
Carlos Perez (darkoperator) started it in 2010 as a Python port of an earlier Ruby script, and it is now maintained with Jay Townsend (L1ghtn1ng). It has about 3,100 stars, 84 contributors and 1,018 commits, is GPL-2.0, and is packaged in Kali and other security distributions. It is actively looked after: release 1.6.3 shipped in June 2026, Dependabot updates are merged within days, and the last push was on 27 October 2026.
- Repository: github.com/darkoperator/dnsrecon
- Licence: GPL-2.0 (GNU General Public License v2.0)
- Language: Python. Stars: 3,088. Forks: 575. Last push: Oct 27, 2026.
- Scan: safe, Oct 28, 2026, commit eecb953
Who it is for
System administrators and security teams checking their own DNS for open zone transfers, stale records or weak SPF, penetration testers working inside an agreed scope, and anyone learning how DNS works who wants to see a domain's full public record set.
Getting started
1. Clone the repository (Python 3.12 or later; on Kali: sudo apt install dnsrecon)
git clone https://github.com/darkoperator/dnsrecon.git && cd dnsrecon2. Install the dependencies into a virtual environment with uv
uv sync3. Run a standard check of your own domain
uv run dnsrecon -d example.com -t stdThe README installs uv with its curl | sh script from astral.sh; Homebrew and pipx also install uv. Shodan expansion needs your own Shodan API key. Wordlist and range modes send many queries, so run them on domains you own or are authorised to test.
Safety scan
We cloned darkoperator/dnsrecon at commit eecb953 on Oct 28, 2026 and ran the checks described on the GitHub Tools page: credential patterns, decode-and-execute code, install-time scripts, committed binaries, risky CI workflows, every host the code talks to, known vulnerabilities in pinned dependencies, and project hygiene. A person read every hit. This is what we found.
- 47 files and about 10,100 lines of Python. No secrets, no pattern hits, no install hooks and no committed binaries. Most of the 1.8 MB is subdomain wordlists in dnsrecon/data.
- uv.lock pins 44 packages; one has a known advisory: dnspython 2.8.0 (GHSA-45c3-73f7-pv4m, high), where a crafted DNS response can make name parsing use excessive CPU. It is a runtime dependency, so it ships. The advisory was published on 27 October 2026 and 2.9.0 fixes it; until the lock is updated, uv lock --upgrade-package dnspython applies the fix.
- The network hosts are the data sources: crt.sh, Bing and Yandex for search-engine discovery, api.shodan.io, and tld-list.com for the TLD list. The REST API binds to 127.0.0.1 by default and only reads wordlists from bundled or explicitly configured folders.
- Five workflows, none using pull_request_target. All 11 third-party actions are pinned to commits. Dependabot, CodeQL and dependency review are on, and OpenSSF Scorecard rates it 7.6 of 10. No security policy or contributing guide.
What the scanner counted
| Check | Result |
|---|---|
| Secrets | None found. |
| Suspicious code | None found. |
| Install-time code | None: nothing runs at install beyond the package manager itself. |
| Committed binaries | None. |
| CI workflows | 5 workflows. None use pull_request_target. 0 of 11 third-party actions pinned to a tag rather than a commit. |
| Network hosts | 8 distinct hosts referenced from source; most often crt.sh, www.darkoperator.com, www.bing.com, raw.githubusercontent.com. No URLs to bare IP addresses. |
| Known vulnerabilities | 1 advisory across 44 pinned packages: 0 critical, 1 high, 0 moderate, 0 low. uv.lock: 44 packages, 1 advisories. |
| Project hygiene | Has automated dependency updates, CodeQL, licence file. Missing security policy, contributing guide. |
| OpenSSF Scorecard | 7.6 out of 10, as of Oct 27, 2026. |
The raw findings
Every hit the scanner wrote out, with a link to the exact line at the scanned commit. Secrets candidates are redacted.
Worst known vulnerabilities (1 of 1)
| Advisory | Severity | Package | Summary |
|---|---|---|---|
| GHSA-45c3-73f7-pv4m | high | dnspython@2.8.0 | dnspython dns.name.from_wire_parser() excessive CPU use |
By the numbers
| Stars | 3,088 |
|---|---|
| Forks | 575 |
| Contributors | 84 |
| Commits | 1,018 |
| Open issues | 1 |
| Open pull requests | 1 |
| Releases | 30 |
| Latest release | 1.6.3 |
| Licence | GPL-2.0 |
| Main language | Python |
| Project age | 15 years |
| Last push | Oct 27, 2026 |
| Tracked files | 47 |
| Lines of code | 10.1K |
| Checkout size | 2 MB |
Lines by language: Python 9,354, YAML 377, Markdown 266, TOML 131.
Questions
Is DNSRecon free?
Yes. DNSRecon is GPL-2.0 and free for any use. The only paid part is optional: Shodan netblock expansion needs a Shodan API key, which has its own plans.
Is it legal to run DNSRecon against a domain?
Looking up a domain's public DNS records is routine and generally legal. Wordlist checks, zone transfer attempts and large reverse lookups put load on someone else's servers and can count as unauthorised testing, so keep those to domains you own or have written permission to assess.
What does a zone transfer check tell me?
A zone transfer copies every record a name server holds. It is meant for syncing your own secondary servers, so if DNSRecon can pull one from your public name servers, anyone can, and you should restrict transfers to your known secondaries.
This post is part of GitHub Tools, where every repository is cloned and scanned before it is written up. The scan is a snapshot of one commit on one day; the repository has moved on since, so check it before you install.
