mirror of
https://github.com/nmap/nmap.git
synced 2026-08-28 12:31:12 +00:00
Update ip-geolocation-ipinfodb.nse
IPinfoDB is no longer accepting new sign ups for the IPInfoDB API.Instead, IPinfoDB requests for signing up for IP2Location.io IP Geolocation API.Furthermore, the new service endpoint (api.ip2location.io) uses different JSON field names for location data (e.g., city_name instead of cityName).This change makes the script more resilient to external service changes, ensuring geolocation continues to work with both old and new API keys provided by the service migration. The script is updated to implement a dual-endpoint fallback mechanism within the ipinfodb function: Primary Attempt (New API): The script first attempts to query the IP2Location.io API (api.ip2location.io). This ensures compatibility for all newly registered API keys. It uses the new field names (city_name, region_name, country_name) to correctly parse the JSON response. Fallback Attempt (Old API): If the primary request fails, the script falls back to querying the IPInfoDB API (api.ipinfodb.com). This preserves functionality for existing Nmap users who possess an old, still-active IPInfoDB API key, using the legacy field names (cityName, regionName, countryName). Unified Error Handling: Error handling for invalid API keys is maintained and applied to both requests. Updated Documentation The script description has also been updated to include information about the new IP2Location.io service and its registration link.
This commit is contained in:
parent
a74125aef5
commit
4305308812
1 changed files with 74 additions and 21 deletions
|
|
@ -8,12 +8,12 @@ local table = require "table"
|
|||
|
||||
description = [[
|
||||
Tries to identify the physical location of an IP address using the
|
||||
IPInfoDB geolocation web service
|
||||
(http://ipinfodb.com/ip_location_api.php).
|
||||
|
||||
IPInfoDB geolocation web service (http://ipinfodb.com/ip_location_api.php)
|
||||
or its successor, IP2Location.io.
|
||||
There is no limit on requests to this service. However, the API key
|
||||
needs to be obtained through free registration for this service:
|
||||
<code>http://ipinfodb.com/login.php</code>
|
||||
<code>http://ipinfodb.com/login.php</code> or the new signup at
|
||||
<code>https://www.ip2location.io/register</code>
|
||||
]]
|
||||
|
||||
---
|
||||
|
|
@ -65,30 +65,83 @@ hostrule = function(host)
|
|||
return true
|
||||
end
|
||||
|
||||
-- Function to make a request and attempt to parse the response
|
||||
local function do_request(host_name, api_url, api_key, ip, city_key, region_key, country_key)
|
||||
local response = http.get(host_name, 80, api_url..api_key.."&format=json".."&ip="..ip, {any_af=true})
|
||||
local stat, loc = oops.raise(
|
||||
"Unable to parse "..host_name.." response",
|
||||
json.parse(response.body)
|
||||
)
|
||||
|
||||
if not stat then
|
||||
return stat, loc
|
||||
end
|
||||
|
||||
if loc.statusMessage and loc.statusMessage == "Invalid API key." then
|
||||
return false, oops.err(loc.statusMessage)
|
||||
end
|
||||
|
||||
-- Check if we got location data (specific to the new IP2Location API response)
|
||||
if loc.latitude and loc.longitude and loc[city_key] then
|
||||
local output = geoip.Location:new()
|
||||
output:set_latitude(loc.latitude)
|
||||
output:set_longitude(loc.longitude)
|
||||
output:set_city(loc[city_key])
|
||||
output:set_region(loc[region_key])
|
||||
output:set_country(loc[country_key])
|
||||
|
||||
geoip.add(ip, loc.latitude, loc.longitude)
|
||||
return true, output
|
||||
end
|
||||
|
||||
-- If no location data was found, return failure for this API attempt
|
||||
return false, oops.err("No location data found in response from "..host_name)
|
||||
end
|
||||
|
||||
|
||||
-- No limit on requests. A free registration for an API key is a prerequisite
|
||||
local ipinfodb = function(ip)
|
||||
local api_key = stdnse.get_script_args(SCRIPT_NAME..".apikey")
|
||||
local response = http.get("api.ipinfodb.com", 80, "/v3/ip-city/?key="..api_key.."&format=json".."&ip="..ip, {any_af=true})
|
||||
local stat, loc = oops.raise(
|
||||
"Unable to parse ipinfodb.com response",
|
||||
json.parse(response.body))
|
||||
if not stat then
|
||||
return stat, loc
|
||||
end
|
||||
if loc.statusMessage and loc.statusMessage == "Invalid API key." then
|
||||
return false, oops.err(loc.statusMessage)
|
||||
|
||||
-- 1. Try NEW IP2Location API (api.ip2location.io)
|
||||
local stat, result = do_request(
|
||||
"api.ip2location.io",
|
||||
"/?key=",
|
||||
api_key,
|
||||
ip,
|
||||
"city_name", -- New key name for City
|
||||
"region_name", -- New key name for Region
|
||||
"country_name" -- New key name for Country
|
||||
)
|
||||
|
||||
-- If successful, return the result
|
||||
if stat then
|
||||
stdnse.debug1("Successfully retrieved geolocation from ip2location.io")
|
||||
return stat, result
|
||||
end
|
||||
|
||||
local output = geoip.Location:new()
|
||||
output:set_latitude(loc.latitude)
|
||||
output:set_longitude(loc.longitude)
|
||||
output:set_city(loc.cityName)
|
||||
output:set_region(loc.regionName)
|
||||
output:set_country(loc.countryName)
|
||||
stdnse.debug1("Failed to retrieve geolocation from ip2location.io, error: %s. Trying ipinfodb.com...", result)
|
||||
|
||||
geoip.add(ip, loc.latitude, loc.longitude)
|
||||
-- 2. Fallback to OLD IPInfoDB API (api.ipinfodb.com)
|
||||
stat, result = do_request(
|
||||
"api.ipinfodb.com",
|
||||
"/v3/ip-city/?key=",
|
||||
api_key,
|
||||
ip,
|
||||
"cityName", -- Old key name for City
|
||||
"regionName", -- Old key name for Region
|
||||
"countryName" -- Old key name for Country
|
||||
)
|
||||
|
||||
return true, output
|
||||
-- If successful, return the result
|
||||
if stat then
|
||||
stdnse.debug1("Successfully retrieved geolocation from ipinfodb.com")
|
||||
return stat, result
|
||||
end
|
||||
|
||||
-- If both fail, return the last error
|
||||
stdnse.debug1("Failed to retrieve geolocation from ipinfodb.com, error: %s.", result)
|
||||
return stat, result
|
||||
end
|
||||
|
||||
action = function(host,port)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue