Skip to main content

🕷️ DomainSpyder

Domain intelligence from one CLI: subdomain enumeration, DNS analysis, port scanning, technology detection and WHOIS, with JSON and HTML reports.

PyPI Python CI CodeQL License: MIT CodeRabbit Pull Request Reviews

⚠️ 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, balanced and stealth modes 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.xml and 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 subdomains command 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 as 8.8.8.8 and 1.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)

Source distribution for domainspyder 1.0.1
File Size Uploaded
domainspyder-1.0.1.tar.gz 132.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for domainspyder 1.0.1
File Interpreter ABI Platform
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 log

Release 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

Release history Release notifications | RSS feed

This release

1.0.1 This release

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page