Passive Subdomain Enumeration with subfinder
How projectdiscovery subfinder works, where it fits against Amass and assetfinder, and a reproducible pipeline from install to live-host list.
Passive Subdomain Enumeration with subfinder
Before you fire a single probe at a target, you need a map of what’s exposed. Passive subdomain enumeration is that map, and projectdiscovery subfinder builds it faster and more cleanly than most tools in the same category—without sending a single packet to the target’s infrastructure.
This post covers how subfinder works internally, where it sits in a modern recon workflow, how it stacks up against the alternatives, and a step-by-step pipeline you can run in under ten minutes.
What subfinder Actually Does
subfinder is an open-source passive subdomain discovery tool maintained by the ProjectDiscovery team. The GitHub repository has crossed 14,000 stars—not a vanity metric here, just an indicator that it’s become load-bearing infrastructure for a lot of professional workflows.
The design is intentionally narrow: subfinder queries third-party data sources—certificate transparency log frontends, DNS aggregators, internet scanning databases, threat intel feeds—deduplicates the results, and hands you a hostname list. No DNS queries to the target. No HTTP probes. Nothing that generates a log entry on infrastructure you don’t own.
The official documentation lists more than 40 supported sources: Shodan, Censys, VirusTotal, SecurityTrails, AlienVault OTX, ProjectDiscovery’s own Chaos dataset, and several CT log frontends. Which sources are active depends entirely on which API keys you’ve configured. Without any keys it still works—it falls back to unauthenticated sources—but coverage improves substantially once you wire in even a free-tier VirusTotal or SecurityTrails key.
Architecture
subfinder is written in Go and ships as a single statically-linked binary. Deployment is trivial; there’s no runtime dependency chain to manage.
Internally it follows a producer-consumer pattern:
- Source runners query each configured provider concurrently.
- Results flow into a central channel where duplicates are filtered.
- An optional output pipeline applies further processing—hostname resolution, pattern matching—before writing to stdout or a file.
The concurrency is why subfinder can hit dozens of upstream APIs and return a clean result set in seconds. That speed matters when you’re working through a large scope or iterating quickly.
Configuration lives at ~/.config/subfinder/provider-config.yaml. API keys go there. The file is auto-initialized on first run.
Where It Fits in the Toolchain
External recon moves through: asset discovery → service enumeration → vulnerability identification → exploitation or reporting. subfinder owns one slice of asset discovery: subdomain expansion from passive sources.
The surrounding toolchain looks like this:
- Upstream: Seed domains from passive DNS, WHOIS, or ASN lookups (
amass intel,whois). - subfinder’s lane: Passive subdomain enumeration against aggregated third-party sources.
- Downstream: dnsx to confirm which hostnames resolve → httpx to identify live HTTP/S services → nuclei for vulnerability detection.
ProjectDiscovery designed these tools to compose through stdin/stdout pipes, so subfinder’s output slots directly into the rest of the ecosystem without intermediate file wrangling.
subfinder vs. the Alternatives
subfinder vs. Amass
OWASP Amass is the most capable alternative. It layers in active DNS brute-forcing, graph-based relationship mapping, and ASN correlation on top of passive source querying. That breadth makes it the right tool when you need relationship context—mapping how a domain cluster connects to acquired companies or shared infrastructure. It’s also considerably slower. For rapid iteration where you just need a subdomain list, subfinder wins on time without meaningful loss in passive coverage.
subfinder vs. assetfinder
assetfinder by Tom Hudson takes the same passive-only approach with a smaller source list and no YAML configuration system—keys go in environment variables. For a quick one-off check on a single domain it’s frictionless. For a professional engagement where coverage matters, subfinder’s broader source list produces meaningfully better results.
subfinder vs. theHarvester
theHarvester collects emails, names, and IPs alongside subdomains. If subdomain discovery is the goal, theHarvester’s generalism works against it—subfinder is faster and more thorough on that specific task. If you need a general-purpose passive sweep that captures non-subdomain artifacts in the same pass, theHarvester still has a place.
Reach for subfinder when:
- Bug bounty recon where stealth matters and you need a fast, broad subdomain list
- Red team external recon during pre-engagement mapping
- Scheduled attack surface management pipelines
- Feeding a downstream toolchain that starts with dnsx or httpx
Reach for something else when:
- You need active DNS brute-forcing in the same tool → Amass or puredns
- You need domain-to-ASN relationship mapping → Amass
- You need email and people data in the same pass → theHarvester
Reproducible Pipeline: Install to Live-Host List
The following takes you from zero to a resolved, live-host-filtered subdomain list. Commands assume Linux/macOS with Go installed. Realistic runtime: 8–10 minutes.
Step 1: Install subfinder
go install -v github.com/projectdiscovery/subfinder/v2/cmd/subfinder@latest
Pre-built binaries are on the releases page if you’d rather not compile. Verify:
subfinder -version
Step 2: Configure API Keys
mkdir -p ~/.config/subfinder
subfinder -ls 2>/dev/null # lists all sources and initializes the config file
Open ~/.config/subfinder/provider-config.yaml and drop in keys for services you have access to. A free VirusTotal or SecurityTrails key is enough to meaningfully expand coverage. The repository wiki documents the exact YAML structure for each provider.
Step 3: Basic Passive Enumeration
Replace example.com with a domain you’re authorized to test:
subfinder -d example.com -o subdomains_raw.txt
-d— target domain-o— output file
Results print to stdout and write to the file simultaneously. Expect output within 10–30 seconds for most targets depending on source count and network latency.
Step 4: Multiple Domains
subfinder -dL domains.txt -o subdomains_raw.txt -t 10
-dL— file with one domain per line-t— concurrent goroutines per source (default 10; increase cautiously on API-rate-limited sources)
Step 5: Pipe into dnsx for Resolution Verification
go install -v github.com/projectdiscovery/dnsx/cmd/dnsx@latest
subfinder -d example.com -silent | dnsx -silent -o resolved.txt
-silent on both tools strips banners and informational output, leaving only result data on stdout. Raw subfinder output reflects historical data—CT log entries from two years ago don’t mean the hostname still resolves—so this step isn’t optional if you plan to act on the results.
Step 6: Pipe into httpx for Live Web Services
cat resolved.txt | httpx -silent -title -status-code -o live_hosts.txt
You now have confirmed HTTP/S services with status codes and page titles, ready to triage or feed into nuclei.
Full Pipeline as a One-Liner
subfinder -d example.com -silent | dnsx -silent | httpx -silent -title -status-code -o live_hosts.txt
Runs entirely in memory, no intermediate files, completes in under two minutes for a medium-sized target.
Operational Notes
Rate limits: Free-tier API keys on sources like Shodan and Censys will throttle under heavy usage. subfinder logs the error and continues with other sources rather than dying, but you’ll get incomplete coverage from throttled providers. For comprehensive results on large scopes, stagger runs or pay for higher rate limits.
Historical data as false positives: Passive sources are archives. A hostname in a CT log from 2022 may not exist anymore. The dnsx resolution step above exists precisely for this reason—validate before acting.
Continuous monitoring: subfinder’s pipeline-friendly design and cron-compatible flags make it straightforward to run on a schedule and diff today’s output against yesterday’s. Newly appearing subdomains are a reliable early-warning signal for shadow IT and freshly deployed services.
The fastest way to validate your current configuration: run subfinder -d your-target.com -v and watch which sources return results and which return errors. That output tells you exactly where your API key coverage has gaps—fix those first before worrying about tuning anything else.