IP 地理归属库说明

本功能每周更新的是 IP 地理归属库,不是代理 IP 池。它用于访问日志的国家、省份、城市和运营商归属统计,不能用于判断准确物理位置、住址或个人身份。VPN、代理、移动网络、运营商调度及数据时效均可能造成偏差。

数据来源与授权边界

默认不设置在线数据源,自动下载处于禁用状态;不会影响已有数据库的读取。请自行提供具有相应使用、更新及分发授权的 HTTPS 数据源,或合法取得的离线文件。数据许可、署名、商用和再分发条件需要独立核实,数据库授权不随本产品授权一并授予。

本仓库历史脚本 migration-tools/update-access-dashboard.cjs 曾引用 lionsoul2014/ip2region 仓库固定提交 1bf6cabfb63c1a14af0971749c2120a3e5c77d72 的 data/ipv4_source.txt。这只是历史下载路径线索;未核实该数据的原始采集来源、当前可用性、具体许可或商业分发权。旧建库脚本本身不记载数据许可。新发布包不将该路径配置为默认源,也不把代码仓库许可证视作数据授权证明。

环境变量

变量默认值与含义
YMING_DATA_DIR/var/lib/zhisou-monitor;状态文件目录。Windows 请显式配置可写路径。
YMING_GEO_DATABASEYMING_DATA_DIR/ip_geo.sqlite3;目标 SQLite 文件。父目录须可写,主应用仅以只读方式使用此库,不应开启写事务或 WAL。
YMING_GEO_SOURCE_URL空,禁用网络更新。必须是 HTTPS;禁止明文 HTTP 重定向及 URL 内用户名密码。不支持压缩包,须返回原始 UTF-8 文本。
YMING_GEO_SHA256可选,原始文件的 64 位十六进制 SHA-256;优先于校验文件地址。离线导入也执行此项校验。
YMING_GEO_SHA256_URL可选 HTTPS 地址,仅适用于网络模式;内容只能是一个 64 位 SHA-256 值及首尾空白,不接受带文件名的 sha256sum 清单,最大 4096 字节。
YMING_GEO_MIN_ROWS1000;有效行数下限,正整数。根据授权数据集规模调整,测试小文件时可设为 1。
YMING_GEO_MAX_BYTES268435456(256 MiB);下载或离线输入最大字节数,正整数。
YMING_GEO_TIMEOUT_SECONDS30;网络阻塞操作超时秒数,正整数。
YMING_GEO_TOTAL_TIMEOUT_SECONDS600;传输总时限秒数,正整数;在读块间检查,正在阻塞的网络读取最多还需一次网络超时才会退出。不限制本地 SQLite 建库时长。

不配置 SHA-256 时仍执行 HTTPS、大小及格式校验,但无法确认文件是否匹配预期版本。建议从可信独立渠道取得固定摘要;与数据同源的摘要不能抵御源站同时遭到篡改。设置固定摘要后,每次发布新数据也需要更新该配置。

输入格式

start|end|country|province|city|isp|code
1.0.0.0|1.0.0.255|中国|广东|广州|示例运营商|示例代码

第一行只是字段说明,实际文件不含表头。这是七字段的 IPv4 ip2region text 风格约定,不保证兼容所有 ip2region 导出版本;不支持 xdb、IPv6、整数形式地址或压缩数据。代码字段保留原样,不推断其编码体系。

每行严格为七字段;UTF-8(无 BOM),允许 LF 或 CRLF,允许末行没有换行符。前两列必须是规范点分十进制 IPv4,后五列允许空字符串;禁止空行、注释、控制字符和字段内竖线。单行最多 16384 字节,含换行符。范围含首尾端点,起始地址不得大于结束地址,按起始地址严格递增且不重叠;允许区间之间存在空隙。任何一行异常都会拒绝整个版本,不静默跳行。

SQLite 表兼容 server/build_ip_geo_db.py:ranges(start INTEGER PRIMARY KEY, end INTEGER NOT NULL, country TEXT, province TEXT, city TEXT, isp TEXT, code TEXT)。

运行与集成

python geo_update.py
python geo_update.py --file /path/to/authorized-ipv4.txt
python -m unittest -v test_geo_update.py

Python 3.11+,仅使用标准库。无参执行网络模式,遵守已保存的更新日期;离线导入是明确的人工操作,可绕过更新日期,但仍执行锁、校验和备份。离线模式不会请求校验文件 URL,可使用固定 SHA-256。CLI 输出 JSON,失败退出码为 1。

from geo_update import run_update, start_scheduler
status = run_update()  # 可选:单次检查,返回字典
thread = start_scheduler(stop_event)  # threading.Event,由主程序持有
# 关闭时:stop_event.set(); thread.join()

后台守护线程启动时只检查是否到期,此后每天检查一次。成功后 7 天才再次允许网络更新,失败后至少等待 24 小时;检查时间可能使实际执行比到期时间稍晚。启动网络 I/O 前先持久化 24 小时重试保护,避免崩溃或重启引发下载雪崩。关闭事件会中断日常等待,不会中断已开始的更新;在途网络受超时限制。不要删除状态文件来进行常规重启。

可靠性与状态

全过程按块下载、逐行解析、逐行写 SQLite,不把整个数据集装入内存。候选库与目标位于同一目录,完整校验通过后先将旧库复制到 目标文件.bak,再以原子替换发布候选库。只保留一版备份。下载、格式校验、校验和、建库或替换失败均不修改原目标库。需要预留输入文件、候选库及备份所需磁盘空间。

目标旁的 .lock 文件使用操作系统文件锁,进程退出自动释放;不要删除正在使用的锁文件。建议部署于本地文件系统,同一数据库的进程使用同一规范路径和同一个数据目录,避免符号链接别名或网络文件系统锁语义差异。替换时 Windows 上若读取连接未释放,可能失败;旧库保留,下一次重试继续。

YMING_DATA_DIR/geo_update_status.json 原子保存状态、上次尝试/成功时间、下次允许重试时间(Unix 秒)、行数及摘要。状态包括 disabled、updating、updated、failed;调用返回值还可能为 not_due 或 locked。失败只记异常类型,不记录可能包含凭据的 URL 或原始数据。损坏的状态文件按其修改时间额外保护 24 小时。发布后状态写入失败会返回 state_write_error,已发布数据库仍有效,应检查磁盘和权限。

目标文件修改时间会随成功发布改变,供主应用实现 mtime 缓存失效检测;本模块不修改主应用缓存逻辑。测试使用临时目录和模拟网络响应,不访问公网。