erichutchins/polars_iptools

GitHub: erichutchins/polars_iptools

基于 Rust 的高性能 Polars 扩展,提供 IP 地址解析、GeoIP 地理位置富化及代理/VPN 检测能力。

Stars: 28 | Forks: 1

# Polars IPTools Polars IPTools 是一个基于 Rust 的扩展,旨在加速 Polars dataframe 中的 IP 地址操作和富化。该库包含了各种用于处理 IPv4 和 IPv6 地址的实用函数,以及使用 MaxMind 数据库进行的 GeoIP 和匿名化/代理富化功能。 [![文档](https://img.shields.io/badge/docs-mkdocs-blue)](https://erichutchins.github.io/polars_iptools/) [![PyPI - Python 版本](https://img.shields.io/pypi/pyversions/polars-iptools)](https://pypi.org/project/polars-iptools/) [![uv](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json)](https://github.com/astral-sh/uv) [![ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) [![ty](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ty/refs/heads/main/assets/badge/v0.json)](https://github.com/astral-sh/ty) [![许可证: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE) [![Claude](https://img.shields.io/badge/Claude-D97757?logo=claude&logoColor=fff)](https://claude.ai) [![Gemini](https://img.shields.io/badge/Gemini-8E75FF?logo=googlegemini&logoColor=fff)](https://antigravity.google) ## 安装 ``` pip install polars-iptools ``` ## 示例 ### 简单富化 IPTools 的 Rust 实现能为您提供关于基本 IP 问题的快速解答,例如“这是一个私有 IP 吗?” ``` >>> import polars as pl >>> import polars_iptools as ip >>> df = pl.DataFrame({'ip': ['8.8.8.8', '2606:4700::1111', '192.168.100.100', '172.21.1.1', '172.34.5.5', 'a.b.c.d']}) >>> df.with_columns(ip.is_private(pl.col('ip')).alias('is_private')) shape: (6, 2) ┌─────────────────┬────────────┐ │ ip ┆ is_private │ │ --- ┆ --- │ │ str ┆ bool │ ╞═════════════════╪════════════╡ │ 8.8.8.8 ┆ false │ │ 2606:4700::1111 ┆ false │ │ 192.168.100.100 ┆ true │ │ 172.21.1.1 ┆ true │ │ 172.34.5.5 ┆ false │ │ a.b.c.d ┆ false │ └─────────────────┴────────────┘ ``` ### IP 扩展类型 IPTools 提供了两种 Arrow 扩展类型用于高效存储 IP 地址。 `IPv4` 使用 4 字节的 `UInt32` 存储;`IPAddress` 使用 16 字节二进制格式,并同时处理 IPv4 和 IPv6。这两种类型在 Parquet 和 IPC 往返过程中都能保留 dtype。 ``` >>> import polars as pl >>> import polars_iptools as ip >>> df = pl.DataFrame({"ip": ["8.8.8.8", "2606:4700::1111", "192.168.1.1", "invalid"]}) >>> df.with_columns(ip.to_address("ip")) shape: (4, 2) ┌─────────────────┬─────────────────┐ │ ip ┆ ip │ │ --- ┆ --- │ │ str ┆ ip_addr │ ╞═════════════════╪═════════════════╡ │ 8.8.8.8 ┆ 8.8.8.8 │ │ 2606:4700::1111 ┆ 2606:4700::1111 │ │ 192.168.1.1 ┆ 192.168.1.1 │ │ invalid ┆ null │ └─────────────────┴─────────────────┘ >>> # Write typed column to Parquet — dtype is preserved on read >>> typed = df.with_columns(ip.to_address("ip")) >>> typed.write_parquet("/tmp/ips.parquet") >>> pl.read_parquet("/tmp/ips.parquet").dtypes [String, IPAddress] ``` ### 网络范围的 `is_in` Pandas 和 Polars 拥有 `is_in` 函数来执行成员查找。IPTools 扩展了此功能,支持 IP 地址在 IP _网络_ 中的成员资格判断。该函数无缝支持 IPv4 和 IPv6 地址,并将指定的网络转换为 [层级压缩前缀树](https://github.com/Orange-OpenSource/iptrie) 以实现快速、高效的查找。 ``` >>> import polars as pl >>> import polars_iptools as ip >>> df = pl.DataFrame({'ip': ['8.8.8.8', '1.1.1.1', '2606:4700::1111']}) >>> networks = ['8.8.8.0/24', '2606:4700::/32'] >>> df.with_columns(ip.is_in(pl.col('ip'), networks).alias('is_in')) shape: (3, 2) ┌─────────────────┬───────┐ │ ip ┆ is_in │ │ --- ┆ --- │ │ str ┆ bool │ ╞═════════════════╪═══════╡ │ 8.8.8.8 ┆ true │ │ 1.1.1.1 ┆ false │ │ 2606:4700::1111 ┆ true │ └─────────────────┴───────┘ ``` ### GeoIP 富化 使用 [MaxMind](https://www.maxmind.com/en/geoip-databases) 的 _GeoLite2-ASN.mmdb_ 和 _GeoLite2-City.mmdb_ 数据库,IPTools 提供了网络归属和地理位置的离线富化功能。 `ip.geoip.full` 返回一个包含所有可用元数据参数的 Polars struct。如果您只需要 ASN 和 AS 组织信息,可以使用 `ip.geoip.asn`。 ``` >>> import polars as pl >>> import polars_iptools as ip >>> df = pl.DataFrame({"ip":["8.8.8.8", "192.168.1.1", "2606:4700::1111", "999.abc.def.123"]}) >>> df.with_columns([ip.geoip.full(pl.col("ip")).alias("geoip")]) shape: (4, 2) ┌─────────────────┬─────────────────────────────────┐ │ ip ┆ geoip │ │ --- ┆ --- │ │ str ┆ struct[11] │ ╞═════════════════╪═════════════════════════════════╡ │ 8.8.8.8 ┆ {15169,"GOOGLE","","NA","","",… │ │ 192.168.1.1 ┆ {0,"","","","","","","",0.0,0.… │ │ 2606:4700::1111 ┆ {13335,"CLOUDFLARENET","","","… │ │ 999.abc.def.123 ┆ {null,null,null,null,null,null… │ └─────────────────┴─────────────────────────────────┘ >>> df.with_columns([ip.geoip.asn(pl.col("ip")).alias("asn")]) shape: (4, 2) ┌─────────────────┬───────────────────────┐ │ ip ┆ asn │ │ --- ┆ --- │ │ str ┆ str │ ╞═════════════════╪═══════════════════════╡ │ 8.8.8.8 ┆ AS15169 GOOGLE │ │ 192.168.1.1 ┆ │ │ 2606:4700::1111 ┆ AS13335 CLOUDFLARENET │ │ 999.abc.def.123 ┆ │ └─────────────────┴───────────────────────┘ ``` ### Spur 富化 [Spur](https://spur.us/) 是一项商业服务,提供“用于检测 VPN、住宅代理和机器人的数据”。其产品之一是 [Maxmind mmdb 格式](https://docs.spur.us/feeds?id=feed-export-utility) 的数据库,包含最多 2,000,000 个“最繁忙”的匿名或匿名+住宅 IP。 `ip.spur.full` 返回一个包含所有可用元数据参数的 Polars struct。 ``` >>> import polars as pl >>> import polars_iptools as ip >>> df = pl.DataFrame({"ip":["8.8.8.8", "192.168.1.1", "999.abc.def.123"]}) >>> df.with_columns([ip.spur.full(pl.col("ip")).alias("spur")]) shape: (3, 2) ┌─────────────────┬─────────────────────────────────┐ │ ip ┆ spur │ │ --- ┆ --- │ │ str ┆ struct[7] │ ╞═════════════════╪═════════════════════════════════╡ │ 8.8.8.8 ┆ {0.0,"","","","","",null} │ │ 192.168.1.1 ┆ {0.0,"","","","","",null} │ │ 999.abc.def.123 ┆ {null,null,null,null,null,null… │ └─────────────────┴─────────────────────────────────┘ ``` ## 环境配置 IPTools 使用两个 MaxMind 数据库:_GeoLite2-ASN.mmdb_ 和 _GeoLite2-City.mmdb_。只有在调用 geoip 函数时才需要这些文件。 设置 `MAXMIND_MMDB_DIR` 环境变量以告知扩展这些文件的位置。 ``` export MAXMIND_MMDB_DIR=/path/to/your/mmdb/files # 或 Windows 用户 set MAXMIND_MMDB_DIR=c:\path\to\your\mmdb\files ``` 如果未设置环境变量,polars_iptools 将检查另外两个常见位置(在 Mac/Linux 上): ``` /usr/local/share/GeoIP /opt/homebrew/var/GeoIP ``` ### Spur 环境 如果您是 Spur 的客户,请将数据源导出为 `spur.mmdb`,并使用 `SPUR_MMDB_DIR` 环境变量指定其位置。 ``` export SPUR_MMDB_DIR=/path/to/spur/mmdb # 或 Windows 用户 set SPUR_MMDB_DIR=c:\path\to\spur\mmdb ``` ## 致谢 遵循 Marco Gorelli 的 [教程](https://marcogorelli.github.io/polars-plugins-tutorial/) 和 [cookiecutter 模板](https://github.com/MarcoGorelli/cookiecutter-polars-plugins),开发此扩展变得非常简单。
标签:Cybersecurity, EDR, GitHub, IPv4, IPv6, IP 地址批量处理, IP地址解析, MaxMind, Polars扩展, PowerShell, Prompt Injection, Python, Rust, Siem工具, Threat Intelligence, 代理检测, 代码示例, 匿名化, 可视化界面, 地理定位, 威胁情报, 开发者工具, 开源, 数据 enrichment, 数据分析, 数据处理库, 无后门, 网络安全, 网络流量审计, 脆弱性评估, 逆向工具, 隐私保护