Skip to content

Repository files navigation

🛰️ shodan-recon-agent

CI License: MIT Python 3.9+

A production-ready command-line agent for Internet reconnaissance via the Shodan API — host lookups, search, DNS, on-demand scans, and network monitoring alerts, all from one polished CLI.

$ shodan-recon host 8.8.8.8

                  Host: 8.8.8.8
┏━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Field            ┃ Value                    ┃
┡━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ Organization     │ Google LLC               │
│ ISP              │ Google LLC               │
│ Country          │ United States            │
│ Open Ports       │ 53, 443                  │
│ Hostnames        │ dns.google               │
└──────────────────┴──────────────────────────┘

Table of contents

✨ Features

  • Full Shodan API coverage - host lookup, search, count, DNS resolve/reverse/domain, on-demand scans, network alerts, honeyscore, exploit search, ports/protocols, account & plan info.
  • Polished output - colorized tables via rich, or --json for scripting/jq.
  • Safe by default - API keys are never logged or printed in full; scan requests require explicit confirmation.
  • Resilient - automatic retry with exponential backoff on transient errors and rate limits.
  • Flexible credentials - CLI flag, environment variable, .env file, or a saved config file - your choice.
  • Fully tested - unit + CLI integration tests with mocked API calls (no real network calls in CI), linting via ruff, type-checking via mypy.

📦 Installation

pip install -e .
# or, once published to PyPI:
# pip install shodan-recon-agent

Requires Python 3.9+.

🔑 Configuration

Get an API key from account.shodan.io, then use any one of the following:

# Option 1: interactive setup, saved to ~/.shodan/api_key (mode 0600)
shodan-recon configure

# Option 2: environment variable
export SHODAN_API_KEY="your_key_here"

# Option 3: .env file in your project directory
cp .env.example .env   # then edit it

# Option 4: one-off flag
shodan-recon --api-key your_key_here host 8.8.8.8

Resolution order: --api-key flag → SHODAN_API_KEY env var → .env file → ~/.shodan/api_key.

🚀 Usage

# Host lookup
shodan-recon host 8.8.8.8
shodan-recon host 8.8.8.8 --history

# Search
shodan-recon search "apache country:DE"
shodan-recon search "product:nginx" --facets "country,org" --limit 50
shodan-recon count "port:3389"   # free - doesn't use query credits

# DNS
shodan-recon dns resolve example.com www.example.com
shodan-recon dns reverse 8.8.8.8 1.1.1.1
shodan-recon dns domain example.com

# Account / plan
shodan-recon account
shodan-recon myip

# On-demand scanning (consumes scan credits; requires confirmation)
shodan-recon scan request 203.0.113.5 --yes
shodan-recon scan status <scan_id>

# Network monitoring alerts
shodan-recon alert create "office-network" 203.0.113.0/24
shodan-recon alert list
shodan-recon alert delete <alert_id>

# Machine-readable output (works on every command)
shodan-recon --json host 8.8.8.8 | jq '.ports'

Run shodan-recon --help or shodan-recon <command> --help for full details on any command.

🏗️ Architecture

flowchart LR
    CLI["shodan-recon CLI\n(Click)"] --> CFG["Config\n(api key resolution)"]
    CLI --> CMD["Command modules\nhost · search · dns · scan · alert · account"]
    CMD --> CLIENT["ShodanClient\n(retry + backoff + error translation)"]
    CLIENT --> SDK["Official shodan SDK"]
    SDK --> API[("Shodan API")]
    CMD --> FMT["Formatters\n(rich tables / JSON)"]
    FMT --> OUT["Terminal / stdout"]

    CFG -.resolves key from.-> ENV["--api-key / env / .env / ~/.shodan/api_key"]
Loading

Each command module stays thin (argument parsing + output formatting only); all Shodan API interaction and resilience logic lives in client.py, so behavior is consistent and easy to unit-test in isolation from the CLI.

🧱 Project structure

shodan-recon-agent/
├── src/shodan_recon/
│   ├── cli.py            # Click entry point & global options
│   ├── client.py         # Resilient wrapper around the shodan SDK
│   ├── config.py         # API key resolution & persistence
│   ├── formatters.py     # rich-based table/JSON output
│   ├── exceptions.py     # Package-specific exception hierarchy
│   └── commands/         # One module per command group
├── tests/                 # pytest suite (all API calls mocked)
└── .github/workflows/     # CI: lint, type-check, test, build

🧪 Development

pip install -e ".[dev]"
ruff check .
mypy src/shodan_recon
pytest

See CONTRIBUTING.md for contribution guidelines.

🐳 Docker

docker build -t shodan-recon-agent .
docker run --rm -e SHODAN_API_KEY="$SHODAN_API_KEY" shodan-recon-agent host 8.8.8.8

⚖️ Responsible use

This tool is a client for the Shodan API. It does not perform local scanning or exploitation — all data comes from Shodan's own index, and on-demand scans are executed by Shodan's infrastructure against IPs you submit, consuming your account's scan credits. Only query, monitor, or request scans for assets you own or are explicitly authorized to assess. You are responsible for complying with Shodan's Terms of Service and applicable law.

📄 License

MIT — see LICENSE.

About

Production-ready Python CLI for authorized Internet reconnaissance with the Shodan API—host lookup, search, DNS, on-demand scans, network alerts, and JSON output.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages