Domain intelligence from one CLI: subdomain enumeration, DNS analysis, port scanning, technology detection and WHOIS, with JSON and HTML reports.
⚠️ Only scan domains and hosts you own or are authorised to test. Read the Disclaimer section below before running it against anything else.
Quick start
pipx install domainspyder
domainspyder subdomains example.com --alive
domainspyder dns example.com
domainspyder info example.com --output report.html
Commands
| Command | What it does |
|---|---|
subdomains |
Passive enumeration from 5 public sources plus multithreaded DNS brute force |
dns |
A, AAAA, MX, NS, TXT and CNAME records, SPF/DMARC analysis, a 0-10 security score |
ports |
Concurrent TCP connect scan with service identification and banner grabbing |
tech |
Web technology fingerprinting with confidence scores and versions |
info |
WHOIS, RDAP, SSL certificate and DNS SOA data merged into one view |
Every command can export a structured report with --output (.json or .html).
Installation
Requires Python 3.9 or newer.
pipx install domainspyder # recommended: isolated, puts `domainspyder` on your PATH
# or
pip install domainspyder
Check the install, or upgrade to the latest release:
domainspyder --version
pipx upgrade domainspyder
# or
pip install --upgrade domainspyder
Release notes are in the changelog. To install from source for development, see CONTRIBUTING.md.
Features
Subdomain enumeration
- Passive sources: crt.sh (Certificate Transparency), AlienVault OTX (passive DNS), HackerTarget, RapidDNS and the Wayback Machine
- Multithreaded DNS brute force with
fast,balancedandstealthmodes and custom wordlists - Wildcard DNS detection, so wildcard answers are not reported as real subdomains
- Alive detection with status code, server header and page title (HTTPS first, HTTP fallback)
DNS intelligence
- Six record types resolved in parallel over a rotating resolver pool
- SPF validation (
-all,~all,+all) and DMARC policy detection - Email provider identification (Google Workspace, Microsoft 365, Zoho, Amazon SES) and MX/SPF mismatch warnings
- DNS/CDN provider detection (Cloudflare, AWS Route 53, Azure DNS, Google Cloud, GoDaddy, Wix)
- A 0-10 security score with itemised issues and recommendations
Port scanning
- Concurrent TCP connect scanning of common ports, custom lists or preset ranges
- Service identification, safe banner grabbing and reverse DNS
- Exposure insights for remote-access, database and other high-risk services
Technology detection
- HTTP headers, cookies, meta tags, HTML signatures, scripts and stylesheets
- Concurrent probes:
robots.txt, DNS TXT hints, favicon hashes,sitemap.xmland the WordPress/wp-json/API - Frontend, backend, server, CMS and CDN categories with confidence scores and versions
- Security header analysis (HSTS, CSP, X-Frame-Options)
Domain info
- WHOIS, RDAP (RFC 9083), SSL certificate and DNS SOA queried concurrently
- Keeps working when individual sources fail, merging results by priority (WHOIS > RDAP > SSL > DNS SOA)
- Domain age, expiry alerts, WHOIS privacy detection and plain-English EPP status codes
Usage
domainspyder <command> <target> [options]
domainspyder <command> --help
Targets
Targets are normalised before scanning, so https://Example.com/path,
example.com. and example.com:8443 all scan example.com.
subdomains, dns and info need a domain name; ports also accepts an
IPv4 address, and tech accepts a full URL (the path is kept).
Subdomain enumeration
domainspyder subdomains example.com
Runs all 5 passive sources and a DNS brute force in parallel, then deduplicates the results.
| Option | Behaviour |
|---|---|
--alive |
Show only live subdomains, with status code, server and title |
--brute-only |
Skip passive sources and run only the DNS brute force |
--brutemode MODE |
fast, balanced (default) or stealth; applies with --brute-only |
--wordlist PATH |
Use a custom wordlist instead of the bundled one |
--threads N |
Number of threads (default: 50) |
--save PATH |
Save the subdomain list to a text file |
$ domainspyder subdomains example.com --alive
Alive Subdomains
╭───────┬────────────────────────────────┬──────────┬─────────────────┬────────────────╮
│ # │ Subdomain │ Status │ Server │ Title │
├───────┼────────────────────────────────┼──────────┼─────────────────┼────────────────┤
│ 1 │ www.example.com │ 200 │ cloudflare │ Example Domain │
╰───────┴────────────────────────────────┴──────────┴─────────────────┴────────────────╯
TOTAL 1 result(s) found
Brute-force modes
| Mode | Delay | Threads | Best for |
|---|---|---|---|
fast |
0.001s | 80 | Small wordlists, unrestricted targets |
balanced |
0.005s | 50 | Medium wordlists, general recon (default) |
stealth |
0.01s | 20 | Large wordlists, WAF/rate-limit avoidance |
domainspyder subdomains example.com --brute-only --brutemode stealth --wordlist words.txt
Before brute-forcing, DomainSpyder resolves a few random labels. If the domain
answers for names that don't exist (*.example.com), hits that resolve only to
those wildcard addresses are discarded, and the scan reports that a wildcard was
detected.
DNS analysis
domainspyder dns example.com
domainspyder dns example.com --raw-only # records only, no analysis or score
$ domainspyder dns example.com
────────────────────────────────────────────────────────────
RAW DNS RECORDS
────────────────────────────────────────────────────────────
[A]
104.20.23.154
172.66.147.243
[AAAA]
2606:4700:8dd5:72db:f243:0:ef6b:ff98
[NS]
elliott.ns.cloudflare.com
hera.ns.cloudflare.com
[TXT]
_k2n1y4vw3qtb4skdx9e7dxt97qrmmq9
v=spf1 -all
────────────────────────────────────────────────────────────
DNS INSIGHTS
────────────────────────────────────────────────────────────
+ DMARC: Strict (reject)
+ DNS/CDN Provider: Cloudflare
+ SPF: Strict (-all) - strong protection
────────────────────────────────────────────────────────────
SECURITY SUMMARY
────────────────────────────────────────────────────────────
Score: [██████████] 10/10 Low Risk
Passed:
+ SPF record present
+ SPF is strict (-all)
+ DMARC strict (reject)
Port scanning
domainspyder ports scanme.nmap.org
scanme.nmap.org is a host the Nmap project provides
for testing scanners.
| Option | Behaviour |
|---|---|
| Default | Scans 14 common ports |
--ports LIST |
Scans a comma-separated list, e.g. 22,80,443 |
--top-100 |
Scans a preset of 20 high-value ports |
--top-1000 |
Scans ports 1-1000 |
--full |
Scans the full TCP range 1-65535 |
--fast |
Higher concurrency, banner grabbing disabled |
--deep |
Banner grabbing enabled for richer service details |
--threads N |
Number of threads (default: 50) |
$ domainspyder ports scanme.nmap.org
────────────────────────────────────────────────────────────
PORT SCAN SUMMARY
────────────────────────────────────────────────────────────
Target: scanme.nmap.org (45.33.32.156)
Provider: Unknown
Reverse DNS: scanme.nmap.org
Ports Scanned: 14
Open Ports: 2
Closed: 12
Duration: 1.715s
Open Ports
╭───────┬──────────┬────────────┬──────────────┬─────────────────────────────────────────╮
│ # │ Port │ State │ Service │ Banner │
├───────┼──────────┼────────────┼──────────────┼─────────────────────────────────────────┤
│ 1 │ 22 │ open │ ssh │ SSH-2.0-OpenSSH_6.6.1p1 │
│ │ │ │ │ Ubuntu-2ubuntu2.13 │
│ 2 │ 80 │ open │ http │ HTTP/1.1 200 OK │
╰───────┴──────────┴────────────┴──────────────┴─────────────────────────────────────────╯
────────────────────────────────────────────────────────────
PORT INSIGHTS
────────────────────────────────────────────────────────────
! SSH exposed (remote access)
Technology detection
domainspyder tech yahoo.com
$ domainspyder tech yahoo.com
────────────────────────────────────────────────────────────
TECHNOLOGY DETECTION
────────────────────────────────────────────────────────────
Target: yahoo.com
URL: https://www.yahoo.com/
Status: 200
[Frontend ] React ████████░░ (High)
[CMS ] Magento ████░░░░░░ (Low)
Other Technologies:
+ Next.js
+ Webpack
Low-confidence results come from weak signals and are worth confirming by hand.
Domain info
domainspyder info example.com
| Option | Behaviour |
|---|---|
| Default | Queries WHOIS, RDAP, SSL and DNS SOA concurrently |
--brief |
Show only key registration fields (skip SSL, SOA, status) |
--no-ssl |
Skip the SSL certificate check, e.g. when port 443 is blocked |
--no-whois |
Skip WHOIS (use RDAP, SSL and DNS only), e.g. when WHOIS is rate-limited |
Example output
$ domainspyder info google.com
────────────────────────────────────────────────────────────
DOMAIN INFORMATION
────────────────────────────────────────────────────────────
Domain: google.com
Registrar: MarkMonitor, Inc.
Created: 1997-09-15 (29 years — Veteran)
Expires: 2028-09-14 (719 days remaining)
Updated: 2019-09-09
Organization: Google LLC
Country: US
DNSSEC: unsigned
Sources: dns_soa, rdap, ssl, whois
Duration: 2.547s
────────────────────────────────────────────────────────────
NAME SERVERS
────────────────────────────────────────────────────────────
+ ns1.google.com
+ ns2.google.com
+ ns3.google.com
+ ns4.google.com
────────────────────────────────────────────────────────────
REGISTRATION STATUS
────────────────────────────────────────────────────────────
~ clientDeleteProhibited — Domain cannot be deleted by registrar
~ clientTransferProhibited — Domain cannot be transferred
~ clientUpdateProhibited — Domain cannot be modified
~ serverDeleteProhibited — Registry prevents deletion
~ serverTransferProhibited — Registry prevents transfer
~ serverUpdateProhibited — Registry prevents modification
────────────────────────────────────────────────────────────
SSL CERTIFICATE
────────────────────────────────────────────────────────────
Issuer: WE2 (Google Trust Services)
Subject: *.google.com
Valid From: 2026-09-10
Valid Until: 2026-12-03 (69 days remaining)
SANs: *.google.com, *.appengine.google.com, *.bdn.dev, *.origin-test.bdn.dev, *.cloud.google.com
... and 60 more
────────────────────────────────────────────────────────────
DNS SOA RECORD
────────────────────────────────────────────────────────────
Primary NS: ns1.google.com
Admin: dns-admin@google.com
Serial: 987384001
Refresh: 900s (15m)
Retry: 900s (15m)
Expire: 1800s (30m)
Min TTL: 60s (1m)
────────────────────────────────────────────────────────────
DOMAIN INSIGHTS
────────────────────────────────────────────────────────────
! DNSSEC is not enabled
+ Domain is well-established (29 years)
+ SSL certificate is valid
+ 4/4 sources responded successfully
Reports
Every command accepts --output. The file extension picks the format: .json
for raw data, .html for a self-contained, readable report. HTML reports use
the light theme by default; add --html-dark for the dark theme.
domainspyder dns example.com --output dns.json
domainspyder ports scanme.nmap.org --output ports.html --html-dark
Debug logging
--debug goes before the command and enables detailed logging:
domainspyder --debug dns example.com
Exit codes
| Exit code | Meaning |
|---|---|
0 |
Scan completed (including scans that found nothing) |
1 |
Scan failed (e.g. target did not resolve) or saving/export failed |
2 |
Invalid arguments (bad domain, port list, thread count, wordlist) |
130 |
Interrupted with Ctrl+C |
Disclaimer
DomainSpyder is intended for authorised security testing, research and education.
- Only scan targets you own or have explicit permission to test. Port scanning and brute-force subdomain enumeration can break the law, a contract or a provider's acceptable-use policy, even when nothing is exploited.
- Passive enumeration shares the target with third parties. The
subdomainscommand sends the domain to crt.sh, AlienVault OTX, HackerTarget, RapidDNS and the Wayback Machine. If your scope does not allow that, use--brute-only, which only makes DNS lookups through public resolvers such as8.8.8.8and1.1.1.1. - You are responsible for how you use it. DomainSpyder is provided "as is", without warranty of any kind.
Contributing
Bug reports, feature requests and pull requests are welcome. See CONTRIBUTING.md for development setup, checks, project structure and architecture.
License
Released under the MIT License. Created by Amaan Khan.
Release files for domainspyder 1.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| domainspyder-1.0.1.tar.gz | 132.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| domainspyder-1.0.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 256.3 kB
Release files / domainspyder-1.0.1.tar.gz
| Download URL | domainspyder-1.0.1.tar.gz |
|---|---|
| Size | 132.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b07206b16f5a76647787a4254477f1b4080f872a4bbabedc6a1cb5eb137ed50a
|
|
BLAKE2b-256 checksum How to use checksums |
67dbd38a1b7a800737a3d1f6e62c65ed5908dd1405b0383dd36fa3f4b8861c14
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.
Transparency logRelease files / domainspyder-1.0.1-py3-none-any.whl
| Download URL | domainspyder-1.0.1-py3-none-any.whl |
|---|---|
| Size | 123.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
61fc4eef655393a5031e94eb64b3e93de5fb87085baaef0baef7a79303c89682
|
|
BLAKE2b-256 checksum How to use checksums |
13a59a97883604330735768a0a26883f6bf937d059523681a1eaca5c7f9d4cb9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.
Transparency log