Playbook: Find the Geolocation of an External IP Address
Purpose
Determine the geographic location of an external IP address using multiple sources, and validate that the results are consistent.
Required Tools & Access
| Tool | Access Needed | Free Tier? | Notes |
|---|---|---|---|
| IPinfo.io | API token or web interface | Yes (50k/month) | Privacy detection requires paid plan |
| ip-api.com | No auth for non-commercial | Yes | Includes proxy/hosting flags |
| VirusTotal | API key or web interface | Yes (limited) | |
| AbuseIPDB | API key or web interface | Yes (1k/day) | Tor/proxy detection |
| Tor Exit Node List | None | Yes | Official Tor Project list |
You need at least two geolocation sources to cross-validate results.
Input
- One external IPv4 or IPv6 address (e.g.,
8.8.8.8)
Steps
1. Query IPinfo.io
Web interface:
- Go to https://ipinfo.io
- Enter the IP address in the search box
- Record: City, Region, Country, Organization, ASN
API:
curl "https://ipinfo.io/{IP_ADDRESS}?token={YOUR_TOKEN}"
Record the following fields:
cityregioncountryorgasn
2. Query ip-api.com
Web interface:
- Go to http://ip-api.com
- The IP appears in the URL; modify to:
http://ip-api.com/json/{IP_ADDRESS} - Record: City, Region, Country, ISP, AS
API:
curl "http://ip-api.com/json/{IP_ADDRESS}"
Record the following fields:
cityregionNamecountryispas
3. Query VirusTotal (optional but recommended)
Web interface:
- Go to https://virustotal.com
- Click “Search” and enter the IP address
- Go to the “Details” tab
- Record: Country, ASN, Network
API:
curl --header "x-apikey: {YOUR_API_KEY}" \
"https://www.virustotal.com/api/v3/ip_addresses/{IP_ADDRESS}"
Record from data.attributes:
countryasnas_owner
4. Check for VPN/Proxy/Tor
This step determines whether the IP is masking its true origin.
4a. Check ip-api.com flags
If you queried ip-api.com in Step 2, check these additional fields in the response:
proxy: true/false (detects proxy/VPN)hosting: true/false (datacenter/hosting provider, often indicates VPN)
API (with extra fields):
curl "http://ip-api.com/json/{IP_ADDRESS}?fields=status,country,city,isp,as,proxy,hosting"
4b. Check AbuseIPDB
Web interface:
- Go to https://abuseipdb.com
- Enter the IP address
- Look for: Usage Type, ISP, and “Is Tor” flag
API:
curl -G "https://api.abuseipdb.com/api/v2/check" \
--data-urlencode "ipAddress={IP_ADDRESS}" \
-H "Key: {YOUR_API_KEY}" \
-H "Accept: application/json"
Record from response:
data.usageType(e.g., “Data Center/Web Hosting/Transit”)data.isTor(true/false)data.totalReports(abuse report count)
4c. Check Tor Exit Node List
Manual check:
- Download the list: https://check.torproject.org/torbulkexitlist
- Search for the IP address in the file
- If found, the IP is a known Tor exit node
Command line:
curl -s "https://check.torproject.org/torbulkexitlist" | grep -q "{IP_ADDRESS}" && echo "TOR EXIT NODE" || echo "Not a Tor exit"
Summary: Privacy/Anonymization Flags
| Check | Result |
|---|---|
| ip-api proxy flag | |
| ip-api hosting flag | |
| AbuseIPDB usageType | |
| AbuseIPDB isTor | |
| Tor exit node list |
Interpretation:
- Tor exit node: Location data is meaningless; this is the exit point, not the user
- Proxy/VPN detected: Location may be the VPN endpoint, not the user
- Hosting/Datacenter: Likely a server, VPN endpoint, or automated traffic—not a typical end user
Validation
Compare the results from each source:
| Field | IPinfo.io | ip-api.com | VirusTotal |
|---|---|---|---|
| Country | |||
| City/Region | |||
| ASN/Org |
Validation checks:
-
Country match: Do all sources agree on the country?
- If YES: High confidence in country-level location
- If NO: Flag discrepancy; IP may use anycast or be misattributed
-
City/Region match: Do at least 2 sources agree on city or region?
- If YES: Reasonable confidence in city-level location
- If NO: Report country only; city-level data is unreliable for this IP
-
ASN/Org match: Do the ASN numbers match?
- If YES: Confirms the network owner
- If NO: Investigate further; one source may have stale data
Known limitations:
- VPNs, proxies, and Tor exit nodes will show the endpoint location, not the user (Step 4 helps detect these)
- CDN and anycast IPs (e.g., Cloudflare, Google) may return multiple valid locations
- Mobile IPs may geolocate to carrier headquarters, not actual user location
- Privacy detection is not perfect; some VPNs use residential IPs that evade detection
Output
Produce a summary in this format:
IP Address: {IP}
Lookup Date: {YYYY-MM-DD}
Location:
Country: {country} (confidence: high/medium/low)
City/Region: {city, region} (confidence: high/medium/low)
Network:
ASN: {asn}
Organization: {org name}
Privacy/Anonymization:
Tor Exit Node: {yes/no}
Proxy/VPN Detected: {yes/no/unknown}
Hosting/Datacenter: {yes/no}
⚠️ Location Reliability: {reliable / unreliable - anonymized}
Validation:
Sources queried: {list sources}
Country consensus: {yes/no}
City consensus: {yes/no}
Notes:
{any discrepancies or flags}
Important: If any privacy/anonymization flag is positive, add a warning that the geolocation data represents the proxy/VPN/Tor endpoint, NOT the actual user location.
Logging
Record the following in your investigation log or ticket:
- The IP address queried
- Date/time of lookup
- Sources consulted
- Location results: Country, City/Region, confidence level
- Network info: ASN, Organization
- Privacy flags: Tor, Proxy/VPN, Hosting/Datacenter
- Location reliability assessment
- Any discrepancies noted
- Analyst name or “automated” if run by script
Example log entry:
[2026-01-01 14:30] GeoIP lookup for 203.0.113.42
Sources: IPinfo.io, ip-api.com, VirusTotal, AbuseIPDB, Tor list
Result: Netherlands, Amsterdam (high confidence)
ASN: AS12345 - Example Hosting Inc.
Privacy: Not Tor, no proxy detected, hosting=yes (datacenter IP)
Notes: All geo sources agree. Datacenter IP suggests server or VPN endpoint.
Analyst: AJ
Automation Notes
This playbook is a good candidate for scripting because:
- All steps are deterministic
- APIs return structured data
- Validation logic is straightforward
A script should:
- Accept IP as input
- Query all configured sources
- Compare results automatically
- Output the summary format above
- Flag discrepancies for human review