Know Your IP

https://img.shields.io/pypi/v/know_your_ip.svg Documentation Status

Get comprehensive data on IP addresses. Learn where they are located (lat/long, country, city, time zone), whether they are flagged as malicious (by AbuseIPDB, VirusTotal, IPVoid, etc.), which ports are open and what services are running (via Shodan), and network diagnostics (ping, traceroute).

If you are curious about potential application of the package, we have a presentation on its use in cybersecurity analysis workflow.

You can use the package in two different ways. You can call it from the shell, or you can use it as an external library. From the shell, you can run know_your_ip. It takes a csv with a single column of IP addresses (sample input file: input.csv), and a modern TOML configuration file with API keys and output settings, and appends the requested results to the IP list (sample output file: output.csv). This simple setup allows you to mix and match easily.

If you want to use it as an external library, the package also provides that. The function query_ip uses the modern Pydantic configuration system and takes an IP address. You can also get data from specific services. For instance, if you only care about getting the MaxMind data, use maxmind_geocode_ip. If you would like data from the abuseipdb, call the abuseipdb_api function, etc. These functions use the type-safe KnowYourIPConfig configuration object. For examples of how to use the package, see example.py or the jupyter notebook example.ipynb.

What’s New in v0.2.0

The latest version brings significant modernization and improvements:

Modern Configuration System - TOML configuration format with Pydantic v2 validation - Type-safe configuration with field validators - Environment variable support (KNOW_YOUR_IP_* prefix) - Embedded AbuseIPDB category mapping (no external CSV files)

API Upgrades - VirusTotal API v3 with enhanced threat intelligence - Updated rate limits and improved error handling - Modern Python 3.11+ features (match/case syntax, union types)

Performance Improvements - Eliminated file I/O operations for category lookups - Self-contained category dictionary with all 23 AbuseIPDB categories - Faster startup and reduced dependencies

Developer Experience - Google-style docstrings with comprehensive examples - Type hints throughout codebase - Improved error messages and validation

Brief Primer on Functionality

  • Geocoding IPs: There is no simple way to discern the location of an IP. The locations are typically inferred from data on delay and topology along with information from private and public databases. For instance, one algorithm starts with a database of locations of various ‘landmarks’, calculates the maximum distance of the last router before IP from the landmarks using Internet speed, and builds a boundary within which the router must be present and then takes the centroid of it. The accuracy of these inferences is generally unknown, but can be fairly `poor.’ For instance, most geolocation services place my IP more than 30 miles away from where I am. Try http://www.geoipinfo.com/.

    The script provides hook to Maxmind City Lite DB. It expects a copy of the database to be in the folder in which the script is run. To download the database, go here. The function maxmind_geocode_ip returns city, country, lat/long etc.

  • Timezone: In theory, there are 24 time zones. In practice, a few more. For instance, countries like India have half-hour offsets. Theoretical mappings can be easily created for lat/long data based on the 15 degrees longitude span. For practical mappings, one strategy is to map (nearest) city to time zone (recall the smallish lists that you scroll though on your computer’s time/date program.) There are a variety of services for getting the timezone, including, but not limited to,

For its ease, we choose a Python hook to nodeJS lat/long to timezone. To get the timezone, we first need to geocode the IP (see above). The function tzwhere_timezone takes lat/long and returns timezone.

  • Ping: Sends out a ICMP echo request and waits for the reply. Measures round-trip time (min, max, and mean), reporting errors and packet loss. If there is a timeout, the function produces nothing. If there is a reply, it returns:

    packets_sent, packets_received, packets_lost, min_time,
    max_time, avg_time
    
  • Traceroute: Sends a UDP (or ICMP) packet. Builds the path for how the request is routed, noting routers and time.

  • Backgrounder:

    • censys.io: Performs ZMap and ZGrab scans of IPv4 address space. To use censys.io, you must first register. Once you register and have the API key, configure it in your TOML file or environment variables. The function takes an IP and returns asn, timezone, country etc. For a full list, see https://censys.io/ipv4/help.

    • shodan.io: Scans devices connected to the Internet for services, open ports etc. You must register to use shodan.io. Querying costs money. Once you register and have the API key, configure it in your TOML file or environment variables. The script implements two API calls: shodan/host/ip and shodan/scan. The function takes a list of IPs and returns

  • Blacklists and Backgrounders: The number of services that maintain blacklists is enormous. Here’s a list of some of the services: TornevallNET, BlockList_de, Spamhaus, MyWOT, SpamRATS, Malc0de, SpyEye, GoogleSafeBrowsing, ProjectHoneypot, etc. Some of the services report results from other services as part of their results. In this script, we implement hooks to the following three:

    • virustotal.com: A Google company that analyzes and tracks suspicious files, URLs, and IPs. You must register to use virustotal. Once you register and have the API key, configure it in your TOML file or environment variables. The function implements the modern VirusTotal API v3 for retrieving IP address reports.

    • abuseipdb.com: Tracks reports on IPs. You must register to use the API. Once you register and have the API key, configure it in your TOML file or environment variables. The API provides comprehensive abuse data with embedded category mapping for improved performance.

    • ipvoid.com: Tracks information on IPs. There is no API. We scrape information about IPs including status on various blacklist sites.

Query Limits

API

Know Your IP

A Python package to get comprehensive data about IP addresses including: - Geolocation (latitude/longitude, country, city, timezone) - Security analysis (blacklist status via multiple services) - Network information (open ports, running services) - Network diagnostics (ping, traceroute)

Supports multiple data sources including MaxMind, AbuseIPDB, VirusTotal, Shodan, Censys, and more.

class know_your_ip.KnowYourIPConfig(*, maxmind: MaxMindConfig = MaxMindConfig(enabled=True, db_path=PosixPath('db')), geonames: GeoNamesConfig = GeoNamesConfig(enabled=False, username=None), abuseipdb: AbuseIPDBConfig = AbuseIPDBConfig(enabled=False, api_key=None, days=180), ping: PingConfig = PingConfig(enabled=False, timeout=3000, count=3), traceroute: TracerouteConfig = TracerouteConfig(enabled=False, max_hops=30), tzwhere: TzwhereConfig = TzwhereConfig(enabled=True), ipvoid: IPVoidConfig = IPVoidConfig(enabled=True), apivoid: APIVoidConfig = APIVoidConfig(enabled=False, api_key=None), censys: CensysConfig = CensysConfig(enabled=False, api_url='https://search.censys.io/api', api_key=None), shodan: ShodanConfig = ShodanConfig(enabled=False, api_key=None), virustotal: VirusTotalConfig = VirusTotalConfig(enabled=False, api_key=None), output: OutputConfig = OutputConfig(columns=['ip', 'maxmind.continent.names.en', 'maxmind.country.names.en', 'maxmind.location.time_zone', 'maxmind.postal.code', 'maxmind.registered_country.names.en', 'tzwhere.timezone', 'abuseipdb.bad_isp', 'abuseipdb.categories', 'ipvoid.blacklist_status', 'ipvoid.reverse_dns', 'apivoid.anonymity.is_hosting', 'apivoid.anonymity.is_proxy', 'apivoid.anonymity.is_tor', 'apivoid.anonymity.is_vpn', 'apivoid.anonymity.is_webproxy', 'apivoid.blacklists.detection_rate', 'apivoid.blacklists.detections', 'apivoid.blacklists.engines_count', 'apivoid.blacklists.scantime', 'apivoid.information.city_name', 'apivoid.information.continent_code', 'apivoid.information.continent_name', 'apivoid.information.country_calling_code', 'apivoid.information.country_code', 'apivoid.information.country_currency', 'apivoid.information.country_name', 'apivoid.information.isp', 'apivoid.information.latitude', 'apivoid.information.longitude', 'apivoid.information.region_name', 'apivoid.information.reverse_dns', 'shodan.asn', 'shodan.isp', 'shodan.vulns', 'shodan.os', 'shodan.ports']))[source]

Main configuration for Know Your IP.

model_config: ClassVar[ConfigDict] = {}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

know_your_ip.abuseipdb_api(config: KnowYourIPConfig, ip: str) dict[str, Any][source]

Get abuse information for an IP address from AbuseIPDB API.

Parameters:
  • config – Configuration object containing AbuseIPDB settings including API key, days lookback period, and category mappings.

  • ip – IP address to check for abuse reports.

Returns:

  • abuseipdb.categories: Human-readable abuse categories (e.g., “DDoS Attack|Phishing”)

  • abuseipdb.confidence: Abuse confidence percentage

  • abuseipdb.country: Country of origin

  • abuseipdb.reports: Number of reports

  • Other fields from API response

Return type:

Dictionary containing AbuseIPDB analysis results with keys

Note

Uses embedded category mapping to convert numeric category IDs (e.g., 4, 7, 15) to descriptive names (e.g., “DDoS Attack”, “Phishing”, “Hacking”).

References

https://www.abuseipdb.com/api.html https://docs.abuseipdb.com/

Example

>>> config = KnowYourIPConfig()
>>> config.abuseipdb.api_key = "your_api_key"
>>> config.abuseipdb.days = 90
>>> result = abuseipdb_api(config, '222.186.30.49')
>>> print(result.get('abuseipdb.categories', 'Clean'))
SSH|Brute Force
know_your_ip.abuseipdb_web(config: KnowYourIPConfig, ip: str) dict[str, Any][source]

Get information from AbuseIPDB website

Parameters:
  • config – Typed configuration object.

  • ip (str) – an IP address

Returns:

AbuseIPDB information

Return type:

dict

References

e.g. http://www.abuseipdb.com/check/94.31.29.154

Example

abuseipdb_web(args, ‘222.186.30.49’)

know_your_ip.apivoid_api(config: KnowYourIPConfig, ip: str) dict[str, Any][source]

Get information from APIVoid IP Reputation API

Parameters:
  • config – Typed configuration object.

  • ip (str) – an IP address

Returns:

IP Reputation API information

Return type:

dict

Notes

Must register and get 25 free API credits valid for 30 days

Example

apivoid_api(args, ‘222.186.30.49’)

know_your_ip.censys_api(config: KnowYourIPConfig, ip: str) dict[str, Any][source]

Get information from Censys Platform API.

Note: Legacy Censys Search v1/v2 APIs are deprecated as of 2025. This uses the new Censys Platform API with updated authentication.

Parameters:
  • config – Typed configuration object containing Censys settings.

  • ip – IP address to query.

Returns:

Dictionary containing Censys data with ‘censys.’ prefixed keys.

Rate Limits:

Free tier: 250 requests/month, 1 request per 2.5 seconds

References

https://search.censys.io/api https://docs.censys.com/reference/get-started

Example

>>> config.censys.enabled = True
>>> config.censys.api_key = "your_api_key"
>>> result = censys_api(config, '8.8.8.8')
>>> print(result.get('censys.autonomous_system.name'))
know_your_ip.geonames_timezone(config: KnowYourIPConfig, lat: float, lng: float) dict[str, Any][source]

Get timezone for a latitude/longitude from GeoNames

Parameters:
  • config – Typed configuration object.

  • lat (float) – latitude

  • lng (float) – longitude

Returns:

GeoNames data

Return type:

dict

Notes

Please visit this link for more information about GeoNames.org Web Services

e.g. URL: http://api.geonames.org/timezone?lat=47.01&lng=10.2&username=demo

Limit:

30,000 credits daily limit per application (identified by the parameter ‘username’), the hourly limit is 2000 credits. A credit is a web service request hit for most services. An exception is thrown when the limit is exceeded.

Example

geonames_timezone(config, 32.0617, 118.7778)

know_your_ip.ipvoid_scan(config: KnowYourIPConfig, ip: str) dict[str, Any][source]

Get Blacklist information from IPVoid website

Parameters:
  • config – Typed configuration object.

  • ip (str) – an IP address

Returns:

IPVoid information

Return type:

dict

Example

ipvoid_scan(args, ‘222.186.30.49’)

know_your_ip.load_config(config_file: Path | None = None) KnowYourIPConfig[source]

Load configuration from multiple sources with proper validation.

Sources are loaded in this order (later sources override earlier ones): 1. Default configuration (embedded in code) 2. Configuration file (TOML format) 3. Environment variables

Parameters:

config_file – Path to configuration file. If None, will search standard locations.

Returns:

Validated configuration object.

Raises:

ConfigurationError – If configuration is invalid.

know_your_ip.maxmind_geocode_ip(config: KnowYourIPConfig, ip: str) dict[str, Any][source]

Get location of IP address from Maxmind City database (GeoLite2-City.mmdb)

Parameters:
  • config – Typed configuration object.

  • ip – an IP address

Returns:

Geolocation data

Return type:

dict

Notes

There are other Maxmind databases including:
  • Country Database (GeoLite2-Country.mmdb)

  • Anonymous IP Database (GeoIP2-Anonymouse-IP.mmdb)

  • Connection-Type Database (GeoIP2-Connection-Type.mmdb)

  • Domain Database (GeoIP2-Domain.mmdb)

  • ISP Database (GeoIP2-ISP.mmdb)

know_your_ip.ping(config: KnowYourIPConfig, ip: str) dict[str, Any][source]

Get information using Ping (ICMP protocol)

Parameters:
  • config – Typed configuration object.

  • ip (str) – an IP address

Returns:

Ping statistics information

Return type:

dict

Notes

Ping function is based on a pure python ping implementation using raw socket and you must have root (on Linux) or Admin (on Windows) privileges to run.

Example

ping(args, ‘222.186.30.49’)

know_your_ip.query_ip(config: KnowYourIPConfig, ip: str) dict[str, Any][source]

Get all information of IP address

Parameters:
  • config – Typed configuration object.

  • ip (str) – an IP address

Returns:

Information on the given IP address

Return type:

dict

Example

query_ip(args, ‘222.186.30.49’)

know_your_ip.shodan_api(config: KnowYourIPConfig, ip: str) dict[str, Any][source]

Get information from Shodan

Parameters:
  • config – Typed configuration object.

  • ip (str) – an IP address

Returns:

Shodan information

Return type:

dict

Example

shodan_api(args, ‘222.186.30.49’)

know_your_ip.traceroute(config: KnowYourIPConfig, ip: str) dict[str, Any][source]

Get information using traceroute

Parameters:
  • config – Typed configuration object.

  • ip (str) – an IP address

Returns:

traceroute information

Return type:

dict

Notes

Currently traceroute uses the operating system command traceroute on Linux and tracert on Windows.

Example

traceroute(args, ‘222.186.30.49’)

know_your_ip.tzwhere_timezone(config: KnowYourIPConfig, lat: float, lng: float) str | None[source]

Get timezone of a latitude/longitude using the tzwhere package.

Parameters:
  • config – Typed configuration object.

  • lat (float) – latitude

  • lng (float) – longitude

Returns:

timezone data

Return type:

dict

Example

tzwhere_timezone(args, 32.0617, 118.7778)

know_your_ip.virustotal_api(config: KnowYourIPConfig, ip: str) dict[str, Any][source]

Get information from VirusTotal API v3.

Parameters:
  • config – Typed configuration object containing VirusTotal settings.

  • ip – IP address to analyze.

Returns:

  • virustotal.harmless: Number of harmless detections

  • virustotal.malicious: Number of malicious detections

  • virustotal.suspicious: Number of suspicious detections

  • virustotal.undetected: Number of undetected results

  • virustotal.asn: Autonomous System Number

  • virustotal.as_owner: AS owner name

  • virustotal.country: Country code

  • virustotal.network: Network range

  • virustotal.reputation: Reputation score

  • virustotal.categories: Threat categories (if available)

Return type:

Dictionary containing VirusTotal analysis results with keys

Note

VirusTotal API v3 Rate Limits:
  • Public API: 500 requests/day, 4 requests/minute

  • Premium API: Higher limits based on subscription

Uses HTTP requests with improved error handling. Official vt-py client dependency is available for future async improvements.

References

https://developers.virustotal.com/reference/ip-info https://docs.virustotal.com/reference/overview

Example

>>> config = KnowYourIPConfig()
>>> config.virustotal.api_key = "your_api_key"
>>> result = virustotal_api(config, '8.8.8.8')
>>> print(result['virustotal.reputation'])
530

Installation

Requirements: Python 3.11+

The script depends on some system libraries. Currently traceroute uses operating system command traceroute on Linux and tracert on Windows.

Ping function is based on a pure python ping implementation using raw socket and you must have root (on Linux) or Admin (on Windows) privileges to run

# Install package and dependencies
pip install know_your_ip

# On Ubuntu Linux (if traceroute command not installed)
sudo apt-get install traceroute

Getting KYIP Ready For Use

To use the software, you need to configure API keys and optionally download MaxMind databases:

  • Configuration: Create a TOML configuration file (default: know_your_ip.toml) with your API keys and settings

  • MaxMind Database: For geolocation, download the GeoLite2-City database from MaxMind and place it in the db_path directory

  • Output Columns: Configure desired output columns in the TOML file’s [output] section

  • Environment Variables: Alternatively, use environment variables with the KNOW_YOUR_IP_* prefix

  • Python 3.11+: Ensure you have Python 3.11 or higher installed

Configuration File

Most functions make calls to different public REST APIs and hence require an API key and/or username. You can register to get the API keys at the following URLs:

  • GeoNames - Free: 10K requests/day, 1K requests/hour

  • AbuseIPDB - Free tier: 1K requests/day

  • VirusTotal - Free tier: 500 requests/day, 4 requests/min

  • Censys - Free tier: 250 requests/month, 1 req/2.5 sec

  • Shodan - Paid service starting at $69/month

TOML Configuration File

Create a know_your_ip.toml file with your API keys and settings (see examples/know_your_ip.toml for full example):

# Know Your IP Configuration
# See https://github.com/themains/know-your-ip for documentation

[maxmind]
enabled = true
db_path = "./db"

[geonames]
enabled = false
# username = "your_username_here"

[abuseipdb]
enabled = true
api_key = "your_api_key_here"
days = 90

[virustotal]
enabled = true
api_key = "your_api_key_here"

[shodan]
enabled = false
# api_key = "your_api_key_here"

[output]
columns = [
    "ip",
    "maxmind.country.names.en",
    "maxmind.location.time_zone",
    "abuseipdb.categories",
    "virustotal.reputation",
    "virustotal.malicious"
]

Environment Variables

You can also configure via environment variables:

export KNOW_YOUR_IP_VIRUSTOTAL_API_KEY="your_key_here"
export KNOW_YOUR_IP_VIRUSTOTAL_ENABLED=true
export KNOW_YOUR_IP_ABUSEIPDB_API_KEY="your_key_here"
export KNOW_YOUR_IP_ABUSEIPDB_ENABLED=true

Programmatic Configuration

from know_your_ip import KnowYourIPConfig

config = KnowYourIPConfig()
config.virustotal.enabled = True
config.virustotal.api_key = "your_api_key"
config.abuseipdb.enabled = True
config.abuseipdb.days = 30

Using KYIP

From the command line

usage: know_your_ip [-h] [-f FILE] [-c CONFIG] [-o OUTPUT] [-n MAX_CONN]
                    [--from FROM_ROW] [--to TO] [-v] [--no-header]
                    [ip [ip ...]]

Know Your IP

positional arguments:
ip                    IP Address(es)

optional arguments:
-h, --help            show this help message and exit
-f FILE, --file FILE  List of IP addresses file
-c CONFIG, --config CONFIG
                        Configuration file
-o OUTPUT, --output OUTPUT
                        Output CSV file name
-n MAX_CONN, --max-conn MAX_CONN
                        Max concurrent connections
--from FROM_ROW       From row number
--to TO               To row number
-v, --verbose         Verbose mode
--no-header           Output without header at the first row
know_your_ip --file input.csv

As an External Library

Please look at example.py or the jupyter notebook example.ipynb.

As an External Library with Pandas DataFrame

import pandas as pd
from know_your_ip import KnowYourIPConfig, query_ip

# Load configuration
config = KnowYourIPConfig()
config.virustotal.enabled = True
config.virustotal.api_key = "your_api_key"
config.abuseipdb.enabled = True
config.abuseipdb.api_key = "your_api_key"

# Process DataFrame
df = pd.read_csv('examples/input.csv', header=None)
odf = df[0].apply(lambda ip: pd.Series(query_ip(config, ip)))
odf.to_csv('output.csv', index=False)

Authors

Suriyan Laohaprapanon and Gaurav Sood

The Contributor Code of Conduct

The project welcomes contributions from everyone! In fact, it depends on it. To maintain this welcoming atmosphere, and to collaborate in a fun and productive way, we expect contributors to the project to abide by the Contributor Code of Conduct.

License

The package is released under the MIT License.