Skip to content

feat: add ip-lookup skill (geolocation + RDAP + PTR + abuse check)#171

Closed
MichaelZhangty wants to merge 3 commits intoopenclaw:mainfrom
MichaelZhangty:feat/add-ip-lookup-skill
Closed

feat: add ip-lookup skill (geolocation + RDAP + PTR + abuse check)#171
MichaelZhangty wants to merge 3 commits intoopenclaw:mainfrom
MichaelZhangty:feat/add-ip-lookup-skill

Conversation

@MichaelZhangty
Copy link

@MichaelZhangty MichaelZhangty commented Mar 10, 2026

PR: Add ip-lookup skill

Summary

Adds a new ip-lookup skill — a zero-dependency, zero-config network intelligence tool for any IP address or hostname. Built entirely on Python stdlib, so it works out of the box on any machine with Python 3.11+ and no pip install step required.

This fills a real gap in the skills catalog: there's no existing skill that combines IP geolocation, ASN/ISP lookup, reverse DNS, WHOIS/RDAP network block info, and abuse reputation checking in a single, clean CLI tool.


What it does

Given any IP address or hostname, the skill runs up to four lookups in parallel and renders a structured terminal report:

Panel Data returned API used Auth required
🌍 Geolocation Country, region, city, coordinates, timezone, ISP, org ip-api.com (ipwho.is fallback) None
🔄 Reverse DNS PTR record (hostname for the IP) dns.google None
📋 RDAP / WHOIS Network name, CIDR block, IP range, abuse contact email, registration & last-changed dates rdap.arin.net (RIPE fallback for EU IPs) None
🛡 Abuse (optional) Confidence score 0–100, total report count, last reported date, usage type, associated domain api.abuseipdb.com Free API key via ABUSEIPDB_KEY env var

Hostnames are auto-resolved to IP before lookup. RDAP uses ARIN first, falls back to RIPE for European addresses. All panels support --json for machine-readable output.


Real-world use cases

  • SRE / DevOps: "Which datacenter is this IP in? Who do I email to report abuse?"
  • Security: "Is this IP from a known Tor exit node or hosting provider? Does AbuseIPDB flag it?"
  • Development: "What ASN and ISP is serving my API traffic from?"
  • Networking: "What CIDR block does 1.1.1.1 belong to? When was it registered?"
  • Content moderation: "Where is this user connecting from? Is it a VPN or proxy?"

Trigger examples (what a user might say)

  • "Who owns this IP: 185.220.101.1"
  • "Where is 8.8.8.8 located?"
  • "Look up github.com's IP address"
  • "Check if this IP has abuse reports"
  • "What ASN is 1.1.1.1?"
  • "Do a reverse DNS lookup on 104.21.0.1"
  • "Whois for IP 91.108.4.1"
  • "Is this IP a VPN or proxy?"

CLI usage

# Basic geo + PTR + RDAP
python3 {baseDir}/scripts/ip_lookup.py 8.8.8.8

# Works with hostnames too (auto-resolves)
python3 {baseDir}/scripts/ip_lookup.py github.com

# Fast geo-only (skip RDAP)
python3 {baseDir}/scripts/ip_lookup.py 1.1.1.1 --no-rdap

# Full check including abuse reputation
ABUSEIPDB_KEY=your_key python3 {baseDir}/scripts/ip_lookup.py 185.220.101.1 --abuse

# Machine-readable JSON for piping / scripting
python3 {baseDir}/scripts/ip_lookup.py 8.8.8.8 --json | jq .geo.country

All flags:

Flag Effect
--json Output raw JSON (all panels, pipe-friendly)
--abuse Enable AbuseIPDB reputation panel (needs ABUSEIPDB_KEY)
--no-rdap Skip RDAP/WHOIS (faster for simple geo queries)
--no-ptr Skip reverse DNS PTR lookup

Sample output

  🔍  Investigating: 1.1.1.1  2026-03-10T03:36:38Z

  ╔══ 🌍  Geolocation   [via ip-api.com]
  ║  IP Address            1.1.1.1
  ║  Country               Australia [AU]
  ║  Region                Queensland
  ║  City                  South Brisbane
  ║  ZIP                   4101
  ║  Coordinates           -27.4766, 153.0166
  ║  Timezone              Australia/Brisbane
  ║  ISP                   Cloudflare, Inc
  ║  Org                   APNIC and Cloudflare DNS Resolver project
  ║  ASN                   AS13335 Cloudflare, Inc.
  ║  Flags                 HOSTING/VPN
  ╚══════════════════════════════════════════════════

  ╔══ 🔄  Reverse DNS (PTR)
  ║  PTR Record            (no PTR record)
  ╚══════════════════════════════════════════════════

  ╔══ 📋  RDAP / WHOIS
  ║  Network Name          APNIC-LABS
  ║  Handle                1.1.1.0 - 1.1.1.255
  ║  Type                  ASSIGNED PORTABLE
  ║  CIDR Block(s)         1.1.1.0/24
  ║  Abuse Contact         IRT-APNICRANDNET-AU
  ║  Abuse Email           helpdesk@apnic.net
  ║  Registration          2011-08-10
  ║  Last Changed          2023-04-26
  ╚══════════════════════════════════════════════════

Files changed

skills/miketyzhang/ip-lookup/
├── SKILL.md              ← frontmatter (name, description, metadata/emoji) + usage docs
├── _meta.json            ← owner, slug, displayName, version 1.0.0
└── scripts/
    └── ip_lookup.py      ← ~230 lines, Python 3.11+ stdlib only, no pip needed

Technical notes

  • Zero dependencies — uses only urllib, socket, json, argparse from stdlib
  • ANSI colour output auto-disabled when stdout is not a TTY (safe for pipes/logs)
  • Graceful fallbacks — ip-api.com → ipwho.is for geo; ARIN → RIPE for RDAP
  • IPv6 aware — geo and RDAP work for IPv6; PTR lookup is IPv4-only (noted in docs)
  • Rate limits — ip-api.com free tier: 45 req/min; use --no-rdap or --json for scripting

Testing

Tested on:

python3 scripts/ip_lookup.py 8.8.8.8          # Google DNS — geo + ASN + RDAP
python3 scripts/ip_lookup.py 1.1.1.1          # Cloudflare — full RDAP with abuse contact
python3 scripts/ip_lookup.py github.com       # hostname resolution → Microsoft Azure SG
python3 scripts/ip_lookup.py 8.8.8.8 --json  # JSON output validation

All pass. RDAP confirmed returning CIDR, abuse email, and registration dates.


Checklist

  • SKILL.md has valid YAML frontmatter (name + description + metadata)
  • metadata.openclaw.emoji set to "🔍"
  • metadata.openclaw.requires.bins = ["python3"]
  • _meta.json present with owner, slug, displayName, version, publishedAt
  • {baseDir} placeholder used in SKILL.md (not hardcoded paths)
  • Script uses only Python stdlib — no pip, no install step
  • --json mode works for scripting and automation
  • Tested on 8.8.8.8, 1.1.1.1, github.com
  • Packaged and validated with package_skill.py — all checks pass
  • No secrets or sensitive data in any file
  • No symlinks
  • Follows skills/<owner>/<skill-name>/ directory convention

@openclaw-barnacle
Copy link

Thanks for the pull request! This repository is read-only and is automatically synced from https://clawhub.ai, so we can’t accept changes here. Please make updates on the website instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant