geotool 是一个使用 Zig 编写的轻量级命令行工具,用于解析 geosite.dat / dlc.dat 这类 geosite 文件。
它的目标很明确:
- 列出 geosite 文件中的全部分类
- 导出一个或多个分类下的原始规则
- 保留规则类型前缀,而不是只导出裸域名
- 保持二进制体积尽可能小,便于后续跨平台静态编译
当前实现已经支持:
list列出全部分类export导出单个分类export导出多个分类geoip-list列出 geoip 分类geoip-export导出 geoip CIDR 规则- 多分类合并时按完整规则去重
- 分类名大小写不敏感
- 输出保留
domain:/full:/keyword:/regexp:前缀 - 输出保留属性,格式为
@attr或@key=value geoip-export支持--ipv4/--ipv6过滤export支持--format输出模式切换batch-export支持在一个进程内完成多项 geosite / geoip 导出任务stat/geoip-stat支持输出分类规则条数
这个项目更适合 Zig,而不是 C,主要原因如下:
- Zig 原生支持静态编译和交叉编译,后续生成
armv7、aarch64版本更直接 - 只依赖 Zig 标准库,不需要额外引入 protobuf 库
- 代码可以保持接近 C 的控制力,同时减少手写二进制解析时的样板代码
- 对于这个工具的目标体积,Zig 已经足够小
当前代码在 x86_64-linux-musl + ReleaseSmall 下生成的静态二进制约为 38K。
当前版本:1.2
当前代码已在 Zig 0.15.2 下验证。
构建 x86_64 静态版本:
zig build -Dtarget=x86_64-linux-musl -Doptimize=ReleaseSmall生成的二进制位于:
./zig-out/bin/geotool如果要一次性输出多平台发布包,可以直接运行:
bash ./scripts/build-release.sh默认会生成以下版本:
x86_64armv5tearmv7aarmv7hfaarch64
输出目录为:
./dist脚本默认行为:
- 默认不使用 UPX
- 如需压缩,再显式加
--upx - 输出文件名带版本号,例如
geotool-v1.0-linux-armv7a
默认会启用 UPX 压缩。
关闭 UPX:
bash ./scripts/build-release.sh --no-upx显式启用 UPX:
bash ./scripts/build-release.sh --upx脚本默认使用:
/tmp/zig或系统中可找到的最新 Zig--upx模式下优先读取环境变量中的 UPX 路径- 如果没设置环境变量,则会从
PATH中查找upx-4.2.4和upx-5.0.2
也可以通过环境变量覆盖:
ZIG=/path/to/zig \
UPX_4_2_4=/path/to/upx-4.2.4 \
UPX_5_0_2=/path/to/upx-5.0.2 \
bash ./scripts/build-release.sh --upx只构建指定目标:
bash ./scripts/build-release.sh armv7a aarch64说明:
armv5te使用UPX 4.2.4- 其它目标使用
UPX 5.0.2 - 为了兼容构建与压缩流程,发布脚本中的各目标会使用静态 musl +
-lc方式构建 armv7a默认 CPU 为mpcorenovfp,更适合 RT-AC88U 这类 Broadcom BCM4709 / Cortex-A9 路由器armv7hf默认 CPU 为cortex_a9,用于硬浮点 ARMv7 设备的对照测试,不建议替代 RT-AC88U 的默认选择
列出全部分类:
./zig-out/bin/geotool list -i geosite.dat导出单个分类:
./zig-out/bin/geotool export -i geosite.dat -c GFW列出 geoip 分类:
./zig-out/bin/geotool geoip-list -i geoip.dat查看 geosite 分类条数:
./zig-out/bin/geotool stat -i geosite.dat
./zig-out/bin/geotool stat -i geosite.dat -c CN,GFW查看 geoip 分类条数:
./zig-out/bin/geotool geoip-stat -i geoip.dat
./zig-out/bin/geotool geoip-stat -i geoip.dat -c CN --ipv4导出 geoip 分类:
./zig-out/bin/geotool geoip-export -i geoip.dat -c CN只导出 geoip 中的 IPv4:
./zig-out/bin/geotool geoip-export -i geoip.dat -c CN --ipv4只导出 geoip 中的 IPv6:
./zig-out/bin/geotool geoip-export -i geoip.dat -c CN --ipv6导出多个分类:
./zig-out/bin/geotool export -i geosite.dat -c GFW,AI,GOOGLE导出到文件:
./zig-out/bin/geotool export -i geosite.dat -c GFW,AI,GOOGLE -o rules.txt导出为纯域名列表:
./zig-out/bin/geotool export -i geosite.dat -c CN,GFW --format domain如果逗号后包含空格,请给整个分类列表加引号:
./zig-out/bin/geotool export -i geosite.dat -c 'GFW, AI, GOOGLE'导出的不是纯域名,而是带规则类型的明文规则。
示例:
domain:google.com
full:firebase.google.com
keyword:google
regexp:^adservice\.google\.([a-z]{2}|com?)(\.[a-z]{2})?$
domain:example.com @ads
full:test.example.com @region=cn
说明:
domain:表示后缀域名匹配full:表示完整域名匹配keyword:表示关键字匹配regexp:表示正则匹配@attr表示布尔属性@key=value表示带值属性
export 默认使用 raw 模式,也可以通过 --format 切换:
raw:保留domain:/full:/keyword:/regexp:与属性domain:只输出domain/full两类规则的纯域名full:只输出full规则的纯域名suffix:只输出domain规则的纯域名keyword:只输出keyword规则的值regexp:只输出regexp规则的值
其中 domain 模式最适合 fancyss 这类需要生成 DNS 域名列表的场景。
geoip-export 输出的是 CIDR 明文规则,每行一条。
示例:
1.0.1.0/24
1.0.2.0/23
2001:250::/36
说明:
- 默认同时输出 IPv4 和 IPv6
--ipv4只输出 IPv4--ipv6只输出 IPv6- 多分类导出时,同样按完整规则文本去重
stat 和 geoip-stat 只输出最基础的条目数统计,格式为:
CATEGORY<TAB>COUNT
示例:
CN 128566
GFW 5939
geoip-stat 支持 --ipv4 / --ipv6,可以只统计某一族地址数。
当 -c 指定多个分类时:
- 按你给出的分类顺序依次导出
- 重复分类名会自动忽略
- 分类名比较时不区分大小写
- 如果不同分类中存在完全相同的规则,只输出一次
- 去重依据是完整规则文本,不只是域名部分
例如:
./zig-out/bin/geotool export -i geosite.dat -c google,GOOGLE,github这条命令里:
google和GOOGLE会被视为同一个分类- 若
google和github中有完全相同的规则,最终只保留一条
batch-export 用于在一个进程里完成多项 geosite / geoip 导出,减少多次启动命令和重复读文件的开销。
示例:
cat > plan.txt <<'EOF'
site|raw|AI,OPENAI|ai.rules
site|domain|CN,GFW|dns_domains.txt
ip|cidr4|CN|chnroute.txt
ip|cidr6|CN|chnroute6.txt
EOF
./zig-out/bin/geotool batch-export \
--geosite geosite.dat \
--geoip geoip.dat \
--plan plan.txt任务文件格式:
site|<format>|<category[,category...]>|<output>
ip|<cidr|cidr4|cidr6>|<category[,category...]>|<output>
支持:
- 空行
#注释行- geosite 与 geoip 任务混合
- 各任务独立去重输出
Usage:
geotool list -i <geosite.dat> [-o <file>]
geotool stat -i <geosite.dat> [-c <category[,category...]>] [-o <file>]
geotool export -i <geosite.dat> -c <category[,category...]> [-f <raw|domain|full|suffix|keyword|regexp>] [-o <file>]
geotool geoip-list -i <geoip.dat> [-o <file>]
geotool geoip-stat -i <geoip.dat> [-c <category[,category...]>] [--ipv4] [--ipv6] [-o <file>]
geotool geoip-export -i <geoip.dat> -c <category[,category...]> [--ipv4] [--ipv6] [-o <file>]
geotool batch-export --geosite <geosite.dat> --geoip <geoip.dat> --plan <file>
参数说明:
-i, --input:输入 geosite 文件路径-c, --category:一个或多个分类名,使用逗号分隔-f, --format:仅用于export,选择 geosite 导出格式-o, --output:输出到文件,而不是标准输出--geosite:仅用于batch-export,指定 geosite.dat--geoip:仅用于batch-export,指定 geoip.dat--plan:仅用于batch-export,指定批量任务文件--ipv4:仅用于geoip-export,只导出 IPv4--ipv6:仅用于geoip-export,只导出 IPv6-v, --version:显示版本号-h, --help:显示帮助
.
├── build.zig
├── README.md
├── DESIGN.md
└── src
├── geoip.zig
├── geosite.zig
├── main.zig
└── pb.zig
各文件职责:
src/main.zig:命令行参数解析与入口src/geoip.zig:geoip 数据解析与 CIDR 导出src/geosite.zig:geosite 数据解析、分类导出、规则去重src/pb.zig:最小 protobuf 读取器build.zig:构建脚本
当前包含最小单元测试,覆盖:
- 分类列表解析
- 单分类导出
- 多分类合并导出
- 重复分类名去重
- 重复规则去重
- 分类不存在时返回错误
- geoip CIDR 导出
- geoip IPv4/IPv6 过滤
运行测试:
zig test src/geosite.zig -O ReleaseSmall- 当前只实现 geosite / geoip 文件读取,不负责生成数据文件
- 当前错误提示较简洁,分类不存在时统一返回
category not found - 多分类导出时,只要其中任意一个分类不存在,命令会失败
- 当前默认面向本地文件使用,不包含网络下载逻辑
- 增加“列出某分类规则数量”的子命令
- 增加“模糊搜索分类名”的子命令
- 增加“导出全部分类到多个文件”的批处理模式
- 补充
armv7、aarch64的构建脚本或发布流程