chnroute-linux — 中国大陆 IP 段每日自动更新 + 「仅允许国内访问」落地
在 Linux 上每天自动拉取中国大陆(CN)IPv4/IPv6 地址段,清洗聚合后原子写入内核,
配合入站白名单实现「仅允许国内 IP 访问」;同时可导出 ipset / nftables /RouterOS三种格式,
用于多 WAN 出口策略路由(PBR)与国内外分流。
本方案是
chnroute思路的工程化落地版:chnroute源自 Linux 社区,本质是
「中国大陆 CIDR 数据库」,用于在无 BGP 能力的边缘设备上实现近似 BGP 的按目标选路。
一、实测结果(2026-09-30,国内家宽)
APNIC 官方源 v4=8792 段 v6=2043 段 约 300 秒(国际出口慢) chnroutes2 聚合源 v4=3898 段 1.7 秒 china-operator-ip v4=6207 段 1.7 秒 china-operator-ip6 v6=3414 段 1.7 秒 ... ───────────────────────────────────────────────────────── 聚合结果 IPv4 5714 段 / 346,035,968 地址(约 3.46 亿,与 CNNIC 统计吻合) IPv6 2247 段 ISP 分组 电信 2843 段 / 移动 1003 段 / 联通 1733 段 / 教育网 85 段两个模式:
| 模式 | 命令 | 耗时 | 说明 |
|---|---|---|---|
| 全量(默认) | --sources all | ~300s | APNIC 官方 + 聚合源,最权威 |
| 快速 | --sources aggregate | ~74s | 只用 jsdelivr 镜像聚合源,国内网络推荐 |
GitHub 源可达性实测(这决定脚本必须做镜像回退):
| 镜像 | 结果 |
|---|---|
cdn.jsdelivr.net | ✅ 96 KB / 1.7 s |
ghproxy.net | ✅ 96 KB / 2.0 s |
raw.githubusercontent.com | ❌ 超时(国内直连不通) |
raw.gitmirror.com | ❌ DNS 解析失败 |
二、文件清单
| 文件 | 作用 |
|---|---|
update_chnroute.py | 主脚本:抓取 → 清洗 → 聚合 → 多格式导出 → 原子写入内核 |
apply-whitelist.sh | 启用「仅允许国内访问」入站白名单,自带防自锁自动回滚 |
install.sh | 一键部署(装文件、建目录、注册定时任务、首次运行) |
chnroute-update.service/.timer | systemd 每日定时更新单元 |
README.md | 本文档 |
三、快速开始
# 0) 依赖(Debian/Ubuntu 示例)sudoaptupdate&&sudoaptinstall-ypython3 ipset iptables# 1) 一键安装(同时立即跑一次,只生成数据、不动内核)sudo./install.sh --with-timer# 2) 确认数据合理(应为 4000~8000 段、覆盖 3.4 亿+ 地址)head-5/var/lib/chnroute/chnroute-v4.txtcat/var/lib/chnroute/state.json# 3) 原子写入内核 ipset(可反复执行,更新过程不断流)sudo/usr/local/bin/update_chnroute.py--outdir/var/lib/chnroute--apply# 4) 启用「仅允许国内访问」echo"你的公网出口IP"|sudotee-a/etc/chnroute/whitelist.txtsudo/usr/local/sbin/apply-whitelist.sh# 应用,300 秒后自动回滚# ↑ 立刻另开一个终端验证 SSH 是否还通sudo/usr/local/sbin/apply-whitelist.sh--commit# 确认无误,取消回滚,永久生效四、三个真正重要的工程细节
1. 白名单不会把你锁在门外(防自锁三重保险)
白名单一旦生效,境外 IP(包括你此刻的 SSH 跳板)会立刻被拒。所以apply-whitelist.sh:
- 自动豁免:回环、内网(10/8、172.16/12、192.168/16)、本机全部公网 IP、
当前所有已建立 TCP 会话的对端(也就是你正在用的那条 SSH 连接)、/etc/chnroute/whitelist.txt自定义列表 —— 全部自动进豁免集合; - 自动回滚:生效后立刻调度一个 300 秒的定时回滚(优先
systemd-run,退化到at,再退化到后台进程)。
规则就算写错,最多断 300 秒,机器会自己恢复; - 显式提交:你在窗口期内确认 SSH 正常,执行
--commit取消回滚,策略才永久生效。
2. 数据更新是原子的,不丢包不乱序
用「影子集合 + swap」,而不是「删除重建」:
ipset create cn4-tmp ... ← 灌入新数据到影子集合(线上集合仍在正常工作) ipset restore -exist < chnroute-ipset.v4 (集合名改写为 cn4-tmp) ipset swap cn4-tmp cn4 ← 内核里一次指针交换,瞬时生效,零空窗 ipset destroy cn4-tmp如果新数据抓取失败或校验不过,cn4保持原样 —— 白名单永远不会变成空集合。
3. 完整性守卫:防止数据源异常导致白名单塌陷
白名单塌陷 = 灾难(所有国内用户被拒之门外)。所以每次落地前强制校验:
- 绝对下限:IPv4 ≥ 2000 段、≥ 1 亿地址(实测约 5714 段 / 3.46 亿)
- 绝对上限:IPv4 ≤ 15 亿地址(超过说明把非 CN 网段并进来了)
- 相对变化:较上次条目数/IP 数骤降超 20%直接拒绝;骤增 3 倍以上也拒绝
- 命中即退出码
2,文件与内核都不改动,保留上一次的可用数据 - 确认数据源无误时用
--force跳过
五、脚本能力速查
# 常用python3 update_chnroute.py--outdir/var/lib/chnroute# 只生成数据python3 update_chnroute.py--sourcesaggregate--apply# 快速模式 + 写内核python3 update_chnroute.py--isp--ros-pbr--formatall--apply# 全格式 + ISP 分组 + ROS PBR 模板python3 update_chnroute.py--backendnft --nft-table'inet filter'--applypython3 update_chnroute.py --dry-run--apply# 只演示不落地python3 update_chnroute.py --log-file /var/log/chnroute/update.log| 参数 | 说明 |
|---|---|
--sources all|apnic|aggregate | 数据源组合,默认all |
--isp | 追加电信/移动/联通/教育网/科技网/鹏博士分组 |
--format txt,ipset,nft,ros | 输出格式,all表示全部 |
--set-prefix cn | ipset 集合前缀 →cn4/cn6 |
--ros-list CN/--ros-pbr | RouterOS list 名 / 生成 PBR 模板 |
--apply/--backend | 原子写入内核 / 选 ipset 或 nft |
--force | 跳过完整性守卫(危险) |
--quiet/--log-file | 静默 / UTF-8 日志落盘 |
输出文件(--format all):
chnroute-v4.txt / chnroute-v6.txt 纯 CIDR(带元信息头),通用格式 chnroute-ipset.v4 / .v6 ipset restore 格式(原子 swap 用) chnroute.nft nftables set 定义(nft -f 单事务加载) chnroute-ros.rsc RouterOS address-list 批量导入脚本 chnroute-ros-pbr.rsc RouterOS 策略路由模板(国内直连 / 境外分流) chnroute-diff.txt 与上次更新的差异(新增/移除各 200 条) state.json 本次摘要:段数、地址数、各源状态 cn-chinanet.txt / cn-cmcc.txt / ... ISP 分组(--isp 时生成)六、三种落地方式
A) ipset + iptables(推荐,兼容性最好)
sudoupdate_chnroute.py--outdir/var/lib/chnroute--formatall--applysudoapply-whitelist.sh--commitsudoapply-whitelist.sh--status# 查看链与集合sudoapply-whitelist.sh--rollback# 随时撤销生成的 IPv4 链结构(IPv6 同理走ip6tables):
CHNROUTE-IN: 1. -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT ← 放行已建立连接(响应包) 2. -i lo -j ACCEPT ← 回环 3. -m set --match-set chnroute-wl4 src -j ACCEPT ← 豁免集合(内网/本机/活跃会话/自定义) 4. -m set --match-set cn4 src -j ACCEPT ← 中国大陆 5. -j DROP ← 其余拒绝(MODE=loose 时改为 RETURN)挂到INPUT首位(-I INPUT 1),优先于既有规则。可用环境变量覆盖:
sudoSET4=cn4MODE=strictROLLBACK_DELAY=600WHITELIST_FILE=/etc/chnroute/whitelist.txt ./apply-whitelist.shB) nftables
sudoupdate_chnroute.py--backendnft --nft-table'inet filter'--formatnft--applynft -f chnroute.nft整文件是一个事务,同名 set 被原子替换。在你自己的规则里引用:
nft add rule inet filter input ip saddr @cn4 accept注意:nftables 的 set 与引用它的规则必须在同一张表内,所以用
--nft-table指定你的表名(默认inet filter)。
C) RouterOS(多 WAN 策略路由)
python3 update_chnroute.py--outdir./out--formatros--isp--ros-pbr# 把 chnroute-ros.rsc 上传到设备 /file,然后:# /import file-name=chnroute-ros.rsc生成的chnroute-ros-pbr.rsc是可直接改用的模板(国内直连、境外走代理线路):
/ip firewall mangle add chain=prerouting src-address-list=LAN dst-address-list=CN action=mark-routing new-routing-mark=to-cn passthrough=yes add chain=prerouting src-address-list=LAN dst-address-list=!CN action=mark-routing new-routing-mark=to-overseas passthrough=yes /ip route add dst-address=0.0.0.0/0 gateway=<国内WAN> routing-mark=to-cn distance=1 check-gateway=ping add dst-address=0.0.0.0/0 gateway=<海外WAN> routing-mark=to-overseas distance=1 check-gateway=ping配合--isp生成的CN-CHINANET/CN-CMCC/CN-UNICOM列表,还能做运营商级精细分流
(三网互联互通瓶颈是实打实的,电信用户访问移动 IDC 绕行会显著抬高 RTT 与丢包)。check-gateway=ping+distance分级实现链路健康感知与自动备份。
七、定时更新
sudo./install.sh --with-timer# systemd:每天 04:30 + 随机 30 分钟,自动 --applysudo./install.sh --with-cron# 无 systemd 时用 crontabsystemd 单元要点:
RandomizedDelaySec=1800打散触发时间,避免与其他定时任务叠加Persistent=true关机/休眠错过时间点后开机补跑TimeoutStartSec=900超时视为失败,旧 ipset 不受影响- 日志落
/var/log/chnroute/update.log
检查:
systemctl list-timers chnroute-update.timer journalctl-uchnroute-update.service-n50tail-f/var/log/chnroute/update.log八、常见问题
Q:APNIC 源太慢(约 5 分钟),能快吗?
用--sources aggregate(~74 秒)。它走 jsdelivr 镜像上的 BGP 聚合数据,段数更少、覆盖一致。
也可以把 systemd 单元的--format all改成加--sources aggregate。
Q:用户访问国内 CDN 但 CDN 回源在境外,会不会被误封?
白名单只判源 IP。国内 CDN 边缘节点在国内,源 IP 就是国内的,不受影响。
Q:白名单生效后,出站请求的响应包会被丢吗?
不会。链首放行ESTABLISHED,RELATED,你主动发起的连接,响应包照常进来。
Q:要不要同时放行 UDP / DNS?
白名单基于 address-list,协议无关。但如果只给国外用户开 DNS,那么他们连域名都解析不了 ——
若确有境外用户,请把他们加进/etc/chnroute/whitelist.txt而不是开放端口。
Q:误封了自己怎么救?
- 等 300 秒自动回滚(如果还没
--commit); - 云控制台 VNC/串口执行
sudo /usr/local/sbin/chnroute-rollback.sh; - 事先把出口 IP 写进
/etc/chnroute/whitelist.txt是唯一可靠的预防手段。
Q:IPv6 要不要一起管?
要。只做 v4 白名单时,境外用户仍可经 IPv6 进来。脚本默认 v4/v6 一起生成;
若服务器没有 IPv6,加--no-ipv6。
Q:想撤掉全部策略?sudo /usr/local/sbin/apply-whitelist.sh --rollback;完全卸载sudo ./install.sh --uninstall。
九、数据源与合规说明
- APNIC 官方统计文件:
delegated-apnic-latest,含 CN 的allocated/assigned记录,
权威、只增不减。IPv4 记录以「地址个数」表示,脚本用summarize_address_range正确转 CIDR
(例如 300 个地址 →/24 + /27 + /29 + /30,已单测验证)。 - china-operator-ip:BGP 路由表聚合,附带 ISP(电信/移动/联通/教育网等)归属。
- chnroutes2:已聚合的最小 CIDR 集,体积小、速度快。
以上均为公开的 RIR/BGP 数据派生品,用于网络运维与访问控制;请遵守当地法律法规及所在单位的网络管理规定。